diff --git a/src/net/apocalypselabs/symat/Editor.form b/src/net/apocalypselabs/symat/Editor.form index 77633d3..9312f49 100644 --- a/src/net/apocalypselabs/symat/Editor.form +++ b/src/net/apocalypselabs/symat/Editor.form @@ -90,17 +90,33 @@ - + - - - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/net/apocalypselabs/symat/Editor.java b/src/net/apocalypselabs/symat/Editor.java index de4ed90..d4fa762 100644 --- a/src/net/apocalypselabs/symat/Editor.java +++ b/src/net/apocalypselabs/symat/Editor.java @@ -90,14 +90,10 @@ public class Editor extends javax.swing.JInternalFrame { public Editor(boolean python) { initComponents(); - FileFilter filter = new FileNameExtensionFilter("SyMAT JavaScript (.syjs)", "syjs"); + FileFilter filter = new FileNameExtensionFilter("JavaScript (syjs, js)", "syjs", "js"); fc.setFileFilter(filter); fc.addChoosableFileFilter(filter); - filter = new FileNameExtensionFilter("SyMAT Python (.sypy)", "sypy"); - fc.addChoosableFileFilter(filter); - filter = new FileNameExtensionFilter("JavaScript file (.js)", "js"); - fc.addChoosableFileFilter(filter); - filter = new FileNameExtensionFilter("Python script (.py)", "py"); + filter = new FileNameExtensionFilter("Python (sypy, py)", "sypy", "py"); fc.addChoosableFileFilter(filter); int font_size = 12; @@ -180,9 +176,10 @@ public class Editor extends javax.swing.JInternalFrame { public Editor() { this(false); } - + /** * Show open dialog. + * * @param openfile Nothing to see here, move along. */ public Editor(int openfile) { @@ -236,7 +233,9 @@ public class Editor extends javax.swing.JInternalFrame { sampleGraph = new javax.swing.JMenuItem(); saveMenu = new javax.swing.JMenuItem(); saveAsMenu = new javax.swing.JMenuItem(); + jMenu1 = new javax.swing.JMenu(); exportMenu = new javax.swing.JMenuItem(); + packPluginMenu = new javax.swing.JMenuItem(); shareMenu = new javax.swing.JMenuItem(); shareAsMenu = new javax.swing.JMenuItem(); editMenu = new javax.swing.JMenu(); @@ -385,14 +384,27 @@ public class Editor extends javax.swing.JInternalFrame { }); fileMenu.add(saveAsMenu); + jMenu1.setText("Publish"); + jMenu1.setToolTipText(""); + exportMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK)); - exportMenu.setText("Export..."); + exportMenu.setText("Export Code"); exportMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { exportMenuActionPerformed(evt); } }); - fileMenu.add(exportMenu); + jMenu1.add(exportMenu); + + packPluginMenu.setText("Package Plugin..."); + packPluginMenu.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + packPluginMenuActionPerformed(evt); + } + }); + jMenu1.add(packPluginMenu); + + fileMenu.add(jMenu1); shareMenu.setText("Share..."); shareMenu.addActionListener(new java.awt.event.ActionListener() { @@ -759,10 +771,7 @@ public class Editor extends javax.swing.JInternalFrame { } private void exportMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportMenuActionPerformed - String lang = "js"; - if (pythonOption.isSelected()) { - lang = "python"; - } + String lang = pythonOption.isSelected() ? "python" : "js"; Main.loadFrame(new CodeExport(codeBox.getText(), lang)); }//GEN-LAST:event_exportMenuActionPerformed @@ -833,6 +842,12 @@ public class Editor extends javax.swing.JInternalFrame { } }//GEN-LAST:event_shareAsMenuActionPerformed + private void packPluginMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_packPluginMenuActionPerformed + Main.loadFrame(new PackagePlugin(codeBox.getText(), + javascriptOption.isSelected() ? 0 : 1 + )); + }//GEN-LAST:event_packPluginMenuActionPerformed + private void createShared(String id) { try { String padid = Pads.genPad(id, codeBox.getText()); @@ -912,6 +927,7 @@ public class Editor extends javax.swing.JInternalFrame { private javax.swing.JMenuItem exportMenu; private javax.swing.JMenu fileMenu; private javax.swing.JLabel jLabel1; + private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu3; private javax.swing.JMenu jMenu4; private javax.swing.JMenuBar jMenuBar1; @@ -927,6 +943,7 @@ public class Editor extends javax.swing.JInternalFrame { private javax.swing.JMenu openSampleBtn; private javax.swing.JTextArea outputBox; private javax.swing.JPanel outputPanel; + private javax.swing.JMenuItem packPluginMenu; private javax.swing.JMenuItem pasteBtn; private javax.swing.JRadioButtonMenuItem pythonOption; private javax.swing.JMenuItem redoBtn; diff --git a/src/net/apocalypselabs/symat/Main.java b/src/net/apocalypselabs/symat/Main.java index 9256220..58c5cbd 100644 --- a/src/net/apocalypselabs/symat/Main.java +++ b/src/net/apocalypselabs/symat/Main.java @@ -58,6 +58,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -77,6 +78,7 @@ import javax.swing.ListModel; import javax.swing.UIManager; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; +import net.apocalypselabs.symat.plugin.LoadPlugin; import org.pushingpixels.flamingo.api.ribbon.*; import org.pushingpixels.flamingo.api.ribbon.resize.*; import org.pushingpixels.flamingo.api.common.*; @@ -145,6 +147,8 @@ public class Main extends JRibbonFrame { public static Main maingui; + JRibbonBand pluginband = new JRibbonBand("Plugins", null); + /** * Creates the main app window and does some quick things that aren't * threaded in SplashScreen. @@ -265,6 +269,26 @@ public class Main extends JRibbonFrame { } } + /** + * Load plugins from disk. + */ + public void loadPlugins() { + File dir = new File(System.getProperty("user.home") + "\\.symat\\plugins"); + dir.mkdirs(); + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".sypl"); + } + }); + + for (File pl : files) { + pluginband.addCommandButton( + (new LoadPlugin(pl)).getRibbonBtn(), + RibbonElementPriority.MEDIUM); + } + } + /** * Load the ribbon in all its glory. */ @@ -277,6 +301,7 @@ public class Main extends JRibbonFrame { JRibbonBand appsband = new JRibbonBand("Apps", null); JRibbonBand webband = new JRibbonBand("Community", null); JRibbonBand collabband = new JRibbonBand("Team", null); + loadPlugins(); shellbtn.addActionListener(new ActionListener() { @Override @@ -372,14 +397,19 @@ public class Main extends JRibbonFrame { collabband.setResizePolicies((List) Arrays.asList( new CoreRibbonResizePolicies.None(appsband.getControlPanel()), new IconRibbonBandResizePolicy(appsband.getControlPanel()))); + pluginband.setResizePolicies((List) Arrays.asList( + new CoreRibbonResizePolicies.None(appsband.getControlPanel()), + new IconRibbonBandResizePolicy(appsband.getControlPanel()))); RibbonTask hometask = new RibbonTask("Home", coreband, appsband); RibbonTask webtask = new RibbonTask("Tools", webband, collabband); + RibbonTask plugintask = new RibbonTask("Plugins", pluginband); loadRibbonMenu(null); ribbon.addTask(hometask); ribbon.addTask(webtask); + ribbon.addTask(plugintask); } public static ResizableIcon getRibbonIcon(String name) { @@ -505,8 +535,8 @@ public class Main extends JRibbonFrame { = new FileNameExtensionFilter("SyMAT File" + "(syjs, sypy, js, py, sytt)", "syjs", "sypy", "js", "py", "sytt"); - FileFilter tasklist = - new FileNameExtensionFilter("Task List (sytt)", + FileFilter tasklist + = new FileNameExtensionFilter("Task List (sytt)", "sytt"); fc.setFileFilter(all); fc.addChoosableFileFilter(script); diff --git a/src/net/apocalypselabs/symat/PackagePlugin.form b/src/net/apocalypselabs/symat/PackagePlugin.form index 336c456..6c994f4 100644 --- a/src/net/apocalypselabs/symat/PackagePlugin.form +++ b/src/net/apocalypselabs/symat/PackagePlugin.form @@ -4,8 +4,6 @@ - - @@ -56,7 +54,7 @@ - + @@ -66,19 +64,19 @@ - - + + - + - + - + - + @@ -209,13 +207,16 @@ - + - + + + + - + @@ -229,10 +230,14 @@ - - + + + + + + - + @@ -247,6 +252,7 @@ + @@ -256,7 +262,7 @@ - + @@ -268,6 +274,14 @@ + + + + + + + + diff --git a/src/net/apocalypselabs/symat/PackagePlugin.java b/src/net/apocalypselabs/symat/PackagePlugin.java index d6fcb5f..3955f4b 100644 --- a/src/net/apocalypselabs/symat/PackagePlugin.java +++ b/src/net/apocalypselabs/symat/PackagePlugin.java @@ -45,9 +45,11 @@ */ package net.apocalypselabs.symat; -import java.awt.image.BufferedImage; import java.io.FileOutputStream; +import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFileChooser; @@ -61,17 +63,35 @@ import net.apocalypselabs.symat.plugin.Plugin; */ public class PackagePlugin extends javax.swing.JInternalFrame { - private JFileChooser fc = new JFileChooser(); + private final JFileChooser fcimg = new JFileChooser(); + private final JFileChooser fcexp = new JFileChooser(); private ImageIcon icon; + public PackagePlugin(String code, int lang) { + this(); + try { + icon = new ImageIcon( + ImageIO.read(PackagePlugin.class.getResource("images/plugin.png"))); + } catch (IOException ex) { + Debug.stacktrace(ex); + } + langSelect.setSelectedIndex(lang); + codeBox.setText(code); + iconPreview.setIcon(icon); + } + /** * Creates new form PackagePlugin */ public PackagePlugin() { - fc.setFileFilter(new FileNameExtensionFilter( + fcimg.setFileFilter(new FileNameExtensionFilter( "Image (jpeg,jpg,gif,png,bmp)", "jpeg", "jpg", "gif", "png", "bmp")); + fcexp.setFileFilter(new FileNameExtensionFilter( + "Plugin (sypl)", + "sypl")); initComponents(); + author.setText(PrefStorage.getSetting("author")); } /** @@ -105,6 +125,7 @@ public class PackagePlugin extends javax.swing.JInternalFrame { iconPreview = new javax.swing.JLabel(); openIconBtn = new javax.swing.JButton(); jLabel10 = new javax.swing.JLabel(); + defaultIconBtn = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jLabel8 = new javax.swing.JLabel(); langSelect = new javax.swing.JComboBox(); @@ -115,8 +136,6 @@ public class PackagePlugin extends javax.swing.JInternalFrame { setClosable(true); setIconifiable(true); - setMaximizable(true); - setResizable(true); setTitle("Package Plugin"); jLabel1.setText("Plugin Name:"); @@ -145,7 +164,7 @@ public class PackagePlugin extends javax.swing.JInternalFrame { .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jLabel7) - .addComponent(jScrollPane1) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1) @@ -154,18 +173,18 @@ public class PackagePlugin extends javax.swing.JInternalFrame { .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(website) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(website, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(version, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(version, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(pluginName, javax.swing.GroupLayout.PREFERRED_SIZE, 127, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(pluginName) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel4) + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(author, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(author)) .addComponent(packageID) .addComponent(shortDesc)))) .addContainerGap()) @@ -204,9 +223,10 @@ public class PackagePlugin extends javax.swing.JInternalFrame { jLabel9.setText("Icon:"); + iconPreview.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); iconPreview.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); - openIconBtn.setText("Open Icon..."); + openIconBtn.setText("Open icon..."); openIconBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openIconBtnActionPerformed(evt); @@ -216,6 +236,13 @@ public class PackagePlugin extends javax.swing.JInternalFrame { jLabel10.setText("Recommended icon size is 100x76."); jLabel10.setVerticalAlignment(javax.swing.SwingConstants.TOP); + defaultIconBtn.setText("Use default"); + defaultIconBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + defaultIconBtnActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( @@ -227,11 +254,13 @@ public class PackagePlugin extends javax.swing.JInternalFrame { .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() - .addComponent(iconPreview, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(iconPreview, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(openIconBtn)) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(openIconBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(defaultIconBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addComponent(jLabel9)) - .addGap(0, 194, Short.MAX_VALUE))) + .addGap(0, 181, Short.MAX_VALUE))) .addContainerGap()) ); jPanel4Layout.setVerticalGroup( @@ -241,9 +270,12 @@ public class PackagePlugin extends javax.swing.JInternalFrame { .addComponent(jLabel9) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(openIconBtn) - .addComponent(iconPreview, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(openIconBtn) + .addGap(18, 18, 18) + .addComponent(defaultIconBtn)) + .addComponent(iconPreview, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, 122, Short.MAX_VALUE) .addContainerGap()) ); @@ -340,23 +372,32 @@ public class PackagePlugin extends javax.swing.JInternalFrame { p.setLang(langSelect.getSelectedIndex()); p.setScript(codeBox.getText()); p.setIcon(icon); + if (p.getTitle().equals("") + || p.getAuthor().equals("") + || p.getLongTitle().equals("") + || p.getDesc().equals("") + || p.getPackage().equals("") + || p.getVersion().equals("") + || p.getScript().equals("") + || p.getIcon() == null) { + throw new Exception("One or more required fields are empty."); + } } catch (Exception ex) { Debug.stacktrace(ex); JOptionPane.showInternalMessageDialog(this, "Error. Please check your data.\n\n" + ex.getMessage()); return; } - fc.setFileFilter(new FileNameExtensionFilter( - "Plugin (sypl)", - "sypl")); - int result = fc.showDialog(this, "Publish"); + int result = fcexp.showDialog(this, "Publish"); if (result == JFileChooser.APPROVE_OPTION) { try { - FileOutputStream fout = new FileOutputStream(fc.getSelectedFile()); + FileOutputStream fout = new FileOutputStream(FileUtils.getFileWithExtension(fcexp)); try (ObjectOutputStream oos = new ObjectOutputStream(fout)) { oos.writeObject(p); oos.close(); } + JOptionPane.showInternalMessageDialog(this, + "Publish complete!"); } catch (Exception ex) { Debug.stacktrace(ex); JOptionPane.showInternalMessageDialog(this, @@ -366,13 +407,10 @@ public class PackagePlugin extends javax.swing.JInternalFrame { }//GEN-LAST:event_savePluginActionPerformed private void openIconBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openIconBtnActionPerformed - fc.setFileFilter(new FileNameExtensionFilter( - "Image (jpeg,jpg,gif,png,bmp)", - "jpeg", "jpg", "gif", "png", "bmp")); - int result = fc.showDialog(this, "Select Icon"); + int result = fcimg.showDialog(this, "Select Icon"); if (result == JFileChooser.APPROVE_OPTION) { try { - icon = new ImageIcon(ImageIO.read(fc.getSelectedFile())); + icon = new ImageIcon(ImageIO.read(fcimg.getSelectedFile())); iconPreview.setIcon(icon); } catch (Exception ex) { Debug.stacktrace(ex); @@ -382,10 +420,23 @@ public class PackagePlugin extends javax.swing.JInternalFrame { } }//GEN-LAST:event_openIconBtnActionPerformed + private void defaultIconBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultIconBtnActionPerformed + try { + icon = new ImageIcon( + ImageIO.read(PackagePlugin.class.getResource("images/plugin.png"))); + iconPreview.setIcon(icon); + } catch (IOException ex) { + Debug.stacktrace(ex); + JOptionPane.showInternalMessageDialog(this, + "Error opening default icon.\n\n" + ex.getMessage()); + } + }//GEN-LAST:event_defaultIconBtnActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextField author; private javax.swing.JTextArea codeBox; + private javax.swing.JButton defaultIconBtn; private javax.swing.JLabel iconPreview; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; diff --git a/src/net/apocalypselabs/symat/components/TaskList.java b/src/net/apocalypselabs/symat/components/TaskList.java index d63c943..0c381fe 100644 --- a/src/net/apocalypselabs/symat/components/TaskList.java +++ b/src/net/apocalypselabs/symat/components/TaskList.java @@ -12,6 +12,9 @@ import java.util.ArrayList; * @author Skylar */ public class TaskList implements Serializable { + + private static final long serialVersionUID = 13370L; + private final ArrayList tasks = new ArrayList<>(); private String title = "Untitled"; diff --git a/src/net/apocalypselabs/symat/images/plugin.png b/src/net/apocalypselabs/symat/images/plugin.png new file mode 100644 index 0000000..8125c7d Binary files /dev/null and b/src/net/apocalypselabs/symat/images/plugin.png differ diff --git a/src/net/apocalypselabs/symat/plugin/LoadPlugin.java b/src/net/apocalypselabs/symat/plugin/LoadPlugin.java index d859577..9dfb2bd 100644 --- a/src/net/apocalypselabs/symat/plugin/LoadPlugin.java +++ b/src/net/apocalypselabs/symat/plugin/LoadPlugin.java @@ -45,23 +45,29 @@ */ package net.apocalypselabs.symat.plugin; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream; import net.apocalypselabs.symat.CodeRunner; import net.apocalypselabs.symat.Debug; +import org.pushingpixels.flamingo.api.common.JCommandButton; +import org.pushingpixels.flamingo.api.common.RichTooltip; +import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon; +import org.pushingpixels.flamingo.api.common.icon.ResizableIcon; /** - * + * Plugin loader class. * @author Skylar */ public class LoadPlugin { private Plugin p = new Plugin(); - - public LoadPlugin(String path) { + + public LoadPlugin(File f) { try { - File f = new File(path); FileInputStream fin = new FileInputStream(f); ObjectInputStream ois = new ObjectInputStream(fin); p = (Plugin) ois.readObject(); @@ -70,6 +76,29 @@ public class LoadPlugin { Debug.stacktrace(ex); } } + + public LoadPlugin(String path) { + this(new File(path)); + } + + private ResizableIcon getRibbonIcon() { + return ImageWrapperResizableIcon.getIcon( + p.getIcon().getImage(), + new Dimension(100, 76)); + } + + public JCommandButton getRibbonBtn() { + JCommandButton b = new JCommandButton(p.getTitle(), getRibbonIcon()); + b.setActionRichTooltip(new RichTooltip(p.getLongTitle(), + p.getDesc())); + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent evt) { + exec(); + } + }); + return b; + } public void exec() { CodeRunner cr = new CodeRunner(p.getLang()); diff --git a/src/net/apocalypselabs/symat/plugin/Plugin.java b/src/net/apocalypselabs/symat/plugin/Plugin.java index 1a8606b..79f3f90 100644 --- a/src/net/apocalypselabs/symat/plugin/Plugin.java +++ b/src/net/apocalypselabs/symat/plugin/Plugin.java @@ -11,6 +11,8 @@ import javax.swing.ImageIcon; * Plugin container class. */ public class Plugin implements Serializable { + + private static final long serialVersionUID = 13371L; public final int LANG_JS = 0; public final int LANG_PY = 1;