You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

519 lines
21 KiB
Java

/*
* Copyright (c) 2015, Netsyms Technologies
* All rights reserved.
*
*
* CODE LICENSE ==========
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 4. You adhere to the Media License detailed below. If you do not, this license
* is automatically revoked and you must purge all copies of the software you
* possess, in source or binary form.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* MEDIA LICENSE ==========
* All images and other graphical files ("media") included with this
* software are copyright (c) 2015 Netsyms Technologies. You may not distribute
* the graphics or any program, source code repository, or other digital storage
* media containing them without permission from Netsyms Technologies.
* This ban on distribution only applies to publicly available systems.
* A password-protected network file share, USB drive, or other storage scheme that
* cannot be easily accessed by the public is generally allowed. If in doubt,
* contact Netsyms Technologies. If Netsyms Technologies allows or denies
* you permission, that decision is considered final and binding.
*
* You may only use the media for personal,
* non-commercial, non-educational use unless:
* 1, You have paid for the software and media via the SyMAT website,
* or 2, you are using it as part of the 15-day trial period.
* Other uses are prohibited without permission.
* If any part of this license is deemed unenforcable, the remainder
* of the license remains in full effect.
*/
package net.apocalypselabs.symat;
import java.awt.BorderLayout;
import java.awt.Component;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.web.PromptData;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.util.Callback;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/**
*
* @author Skylar
*/
public class PadEditor extends javax.swing.JInternalFrame implements RunScriptListener {
private WebView browser;
private WebEngine webEngine;
private JFXPanel jfxPanel;
private Group root;
private Scene scene;
private String padID = "";
private String padURL = "";
private RunScriptThread rt;
private JInternalFrame thisFrame;
/**
* Creates new form PadEditor
*
* @param padurl Pad URL to load
* @param padid Pad ID to load
*/
public PadEditor(String padurl, String padid) {
padID = padid;
padURL = padurl;
initComponents();
//setFrameIcon(new ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/editor.png")));
thisFrame = this;
jfxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
@Override
public void run() {
browser = new WebView();
browser.setPrefSize(getWidth(), getHeight());
root = new Group();
scene = new Scene(root);
ObservableList<Node> children = root.getChildren();
children.add(browser);
jfxPanel.setScene(scene);
webEngine = browser.getEngine();
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.RUNNING) {
statusLbl.setText("Loading...");
} else if (newState == Worker.State.SCHEDULED
|| newState == Worker.State.READY) {
} else {
statusLbl.setText("");
}
}
});
webEngine.setOnAlert(
new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> t) {
JOptionPane.showMessageDialog(thisFrame, t.getData(), "Message", JOptionPane.INFORMATION_MESSAGE);
}
});
webEngine.setPromptHandler(
new Callback<PromptData, String>() {
@Override
public String call(PromptData p) {
return JOptionPane.showInputDialog(thisFrame, p.getMessage(), "Question", JOptionPane.QUESTION_MESSAGE);
}
});
webEngine.setConfirmHandler(
new Callback<String, Boolean>() {
@Override
public Boolean call(String p) {
return (JOptionPane.showConfirmDialog(
thisFrame,
p,
"Question",
JOptionPane.OK_CANCEL_OPTION)
== JOptionPane.OK_OPTION ? true : false);
}
});
webEngine.setUserAgent("Mozilla/5.0 SyMAT/" + Main.VERSION_NAME);
webEngine.loadContent("Loading...");
webEngine.load(padurl);
}
});
browserBox.add(jfxPanel, BorderLayout.CENTER);
outputBox.setBackground(net.apocalypselabs.symat.Theme.boxColor());
outputBox.setForeground(net.apocalypselabs.symat.Theme.textColor());
}
/**
*
* @param url
*/
public void loadURL(final String url) {
Platform.runLater(new Runnable() {
@Override
public void run() {
webEngine.load(url);
resizeAll();
}
});
}
/**
*
*/
public void open() {
Main.loadFrame(this, true);
}
/**
*
* @param content
*/
public void loadString(final String content) {
Platform.runLater(new Runnable() {
@Override
public void run() {
webEngine.loadContent(content);
resizeAll();
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jSplitPane1 = new javax.swing.JSplitPane();
browserBox = new javax.swing.JPanel();
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
outputBox = new javax.swing.JTextArea();
clearBtn = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
statusBar = new javax.swing.JToolBar();
statusLbl = new javax.swing.JLabel();
jMenuBar1 = new javax.swing.JMenuBar();
runMenu = new javax.swing.JMenu();
runCodeBtn = new javax.swing.JMenuItem();
killButton = new javax.swing.JMenuItem();
codeLangMenu = new javax.swing.JMenu();
javascriptOption = new javax.swing.JRadioButtonMenuItem();
pythonOption = new javax.swing.JRadioButtonMenuItem();
javaOption = new javax.swing.JRadioButtonMenuItem();
setClosable(true);
setIconifiable(true);
setMaximizable(true);
setResizable(true);
setTitle("Pad Editor");
setFrameIcon(new javax.swing.ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/editor.png"))); // NOI18N
setMinimumSize(new java.awt.Dimension(300, 300));
setPreferredSize(new java.awt.Dimension(550, 391));
addInternalFrameListener(new javax.swing.event.InternalFrameListener() {
public void internalFrameActivated(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameClosing(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameDeactivated(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameDeiconified(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameIconified(javax.swing.event.InternalFrameEvent evt) {
}
public void internalFrameOpened(javax.swing.event.InternalFrameEvent evt) {
formInternalFrameOpened(evt);
}
});
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
formComponentResized(evt);
}
public void componentShown(java.awt.event.ComponentEvent evt) {
formComponentShown(evt);
}
});
jSplitPane1.setDividerLocation(200);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setResizeWeight(0.7);
jSplitPane1.setPreferredSize(new java.awt.Dimension(550, 375));
browserBox.setMinimumSize(new java.awt.Dimension(100, 25));
browserBox.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
browserBoxComponentResized(evt);
}
});
browserBox.setLayout(new java.awt.BorderLayout());
jSplitPane1.setLeftComponent(browserBox);
outputBox.setColumns(20);
outputBox.setRows(1);
outputBox.setTabSize(4);
jScrollPane1.setViewportView(outputBox);
clearBtn.setText("Clear");
clearBtn.setToolTipText("");
clearBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
clearBtnActionPerformed(evt);
}
});
jLabel1.setText("Output:");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 437, Short.MAX_VALUE)
.addComponent(clearBtn))
.addComponent(jScrollPane1)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addComponent(clearBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, 0)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE))
);
jSplitPane1.setBottomComponent(jPanel1);
getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);
statusBar.setFloatable(false);
statusLbl.setText(" ");
statusBar.add(statusLbl);
getContentPane().add(statusBar, java.awt.BorderLayout.PAGE_END);
runMenu.setText("Run");
runCodeBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
runCodeBtn.setText("Run code");
runCodeBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
runCodeBtnActionPerformed(evt);
}
});
runMenu.add(runCodeBtn);
killButton.setText("Kill script");
killButton.setEnabled(false);
killButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
killButtonActionPerformed(evt);
}
});
runMenu.add(killButton);
codeLangMenu.setText("Language");
javascriptOption.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_J, java.awt.event.InputEvent.CTRL_MASK));
javascriptOption.setSelected(true);
javascriptOption.setText("Javascript");
javascriptOption.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
javascriptOptionActionPerformed(evt);
}
});
codeLangMenu.add(javascriptOption);
pythonOption.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK));
pythonOption.setText("Python");
pythonOption.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pythonOptionActionPerformed(evt);
}
});
codeLangMenu.add(pythonOption);
javaOption.setText("Java");
javaOption.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
javaOptionActionPerformed(evt);
}
});
codeLangMenu.add(javaOption);
runMenu.add(codeLangMenu);
jMenuBar1.add(runMenu);
setJMenuBar(jMenuBar1);
pack();
}// </editor-fold>//GEN-END:initComponents
private void formInternalFrameOpened(javax.swing.event.InternalFrameEvent evt) {//GEN-FIRST:event_formInternalFrameOpened
}//GEN-LAST:event_formInternalFrameOpened
private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
resizeAll();
}//GEN-LAST:event_formComponentResized
private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
resizeAll();
}//GEN-LAST:event_formComponentShown
private void runCodeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_runCodeBtnActionPerformed
if (javascriptOption.isSelected()) {
rt = new RunScriptThread("javascript", Pads.getPad(padID), outputBox, null);
} else if (pythonOption.isSelected()) {
rt = new RunScriptThread("python", Pads.getPad(padID), outputBox, null);
} else if (javaOption.isSelected()) {
rt = new RunScriptThread("java", Pads.getPad(padID), outputBox, null);
} else {
return;
}
statusLbl.setText("Running...");
setRunning(true);
rt.registerListener(this);
rt.setDaemon(true);
rt.start();
}//GEN-LAST:event_runCodeBtnActionPerformed
@Override
public void scriptFinished() {
statusLbl.setText("Done");
setRunning(false);
}
private void killButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_killButtonActionPerformed
if (rt.isAlive()) {
rt.killme();
outputBox.append(""
+ "\n============="
+ "\nScript killed"
+ "\n=============\n");
}
statusLbl.setText("Killed");
setRunning(false);
}//GEN-LAST:event_killButtonActionPerformed
private void setRunning(boolean isRunning) {
final boolean running = isRunning;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (running) {
for (Component mu : jMenuBar1.getComponents()) {
mu.setEnabled(false);
}
runMenu.setEnabled(true);
runCodeBtn.setEnabled(false);
codeLangMenu.setEnabled(false);
killButton.setEnabled(true);
} else {
for (Component mu : jMenuBar1.getComponents()) {
mu.setEnabled(true);
}
runCodeBtn.setEnabled(true);
codeLangMenu.setEnabled(true);
killButton.setEnabled(false);
}
}
});
}
private void javascriptOptionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_javascriptOptionActionPerformed
pythonOption.setSelected(false);
javaOption.setSelected(false);
javascriptOption.setSelected(true);
}//GEN-LAST:event_javascriptOptionActionPerformed
private void pythonOptionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pythonOptionActionPerformed
pythonOption.setSelected(true);
javaOption.setSelected(false);
javascriptOption.setSelected(false);
}//GEN-LAST:event_pythonOptionActionPerformed
private void javaOptionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_javaOptionActionPerformed
pythonOption.setSelected(false);
javaOption.setSelected(true);
javascriptOption.setSelected(false);
}//GEN-LAST:event_javaOptionActionPerformed
private void browserBoxComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_browserBoxComponentResized
resizeAll();
}//GEN-LAST:event_browserBoxComponentResized
private void clearBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearBtnActionPerformed
outputBox.setText("");
}//GEN-LAST:event_clearBtnActionPerformed
private void resizeAll() {
Platform.runLater(new Runnable() {
@Override
public void run() {
jfxPanel.setSize(browserBox.getWidth(), browserBox.getHeight());
browser.setPrefSize(browserBox.getWidth(), browserBox.getHeight());
browser.resize(browserBox.getWidth(), browserBox.getHeight());
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel browserBox;
private javax.swing.JButton clearBtn;
private javax.swing.JMenu codeLangMenu;
private javax.swing.JLabel jLabel1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JRadioButtonMenuItem javaOption;
private javax.swing.JRadioButtonMenuItem javascriptOption;
private javax.swing.JMenuItem killButton;
private javax.swing.JTextArea outputBox;
private javax.swing.JRadioButtonMenuItem pythonOption;
private javax.swing.JMenuItem runCodeBtn;
private javax.swing.JMenu runMenu;
private javax.swing.JToolBar statusBar;
private javax.swing.JLabel statusLbl;
// End of variables declaration//GEN-END:variables
}