diff --git a/src/net/apocalypselabs/symat/FileUtils.java b/src/net/apocalypselabs/symat/FileUtils.java index 4bb2df3..4609faf 100644 --- a/src/net/apocalypselabs/symat/FileUtils.java +++ b/src/net/apocalypselabs/symat/FileUtils.java @@ -123,7 +123,7 @@ public class FileUtils { java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); byte[] array = md.digest(md5.getBytes()); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < array.length; ++i) { sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3)); } diff --git a/src/net/apocalypselabs/symat/Functions.java b/src/net/apocalypselabs/symat/Functions.java index c1809a5..6986735 100644 --- a/src/net/apocalypselabs/symat/Functions.java +++ b/src/net/apocalypselabs/symat/Functions.java @@ -45,6 +45,7 @@ */ package net.apocalypselabs.symat; +import java.io.IOException; import static java.lang.Math.*; import java.util.HashMap; import javax.swing.JOptionPane; @@ -218,6 +219,18 @@ public class Functions { showGraph(); graphwin.drawDot(x, y); } + + public String readfile(String path) throws IOException { + return FileUtils.readFile(path); + } + + public void savefile(String content, String path) throws IOException { + FileUtils.saveFile(content, path, false); + } + + public String md5sum(String data) { + return FileUtils.MD5(data); + } // TODO: Make globals work! diff --git a/src/net/apocalypselabs/symat/Graph.java b/src/net/apocalypselabs/symat/Graph.java index 1dad9ea..701a98b 100644 --- a/src/net/apocalypselabs/symat/Graph.java +++ b/src/net/apocalypselabs/symat/Graph.java @@ -57,7 +57,6 @@ import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; import org.math.plot.plotObjects.BaseLabel; import org.matheclipse.core.eval.EvalUtilities; -import org.matheclipse.parser.client.math.MathException; /** * diff --git a/src/net/apocalypselabs/symat/GraphScale.form b/src/net/apocalypselabs/symat/GraphScale.form deleted file mode 100644 index 34b88bc..0000000 --- a/src/net/apocalypselabs/symat/GraphScale.form +++ /dev/null @@ -1,73 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/net/apocalypselabs/symat/GraphScale.java b/src/net/apocalypselabs/symat/GraphScale.java deleted file mode 100644 index 9612cff..0000000 --- a/src/net/apocalypselabs/symat/GraphScale.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * CODE LICENSE ===================== - * Copyright (c) 2015, Apocalypse Laboratories - * All rights reserved. - * - * 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 (the "graphics") included with this - * software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute - * the graphics or any program, source code repository, or other digital storage - * media containing them without written permission from Apocalypse Laboratories. - * 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 Apocalypse Laboratories. If Apocalypse Laboratories allows or denies - * you permission, that decision is considered final and binding. - */ -package net.apocalypselabs.symat; - -import java.math.BigDecimal; -import java.math.RoundingMode; - -/** - * This is a panel for scale settings. It is shown in a JOptionPane. - * @author Skylar - */ -public class GraphScale extends javax.swing.JPanel { - - /** - * Creates new form GraphSettings - */ - public GraphScale() { - initComponents(); - } - - public GraphScale(int scale) { - this(); - scaleSpinner.setValue(scale); - } - - /** - * 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") - // //GEN-BEGIN:initComponents - private void initComponents() { - - scaleSpinner = new javax.swing.JSpinner(); - helpLbl = new javax.swing.JLabel(); - scaleLbl = new javax.swing.JLabel(); - - scaleSpinner.setModel(new javax.swing.SpinnerNumberModel()); - scaleSpinner.setEditor(new javax.swing.JSpinner.NumberEditor(scaleSpinner, "")); - scaleSpinner.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - scaleSpinnerStateChanged(evt); - } - }); - - helpLbl.setText("Set detail level for graph (larger is finer):"); - - scaleLbl.setText("1 tick = 1 x"); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(helpLbl) - .addGroup(layout.createSequentialGroup() - .addComponent(scaleSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(scaleLbl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(helpLbl) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(scaleSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(scaleLbl)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - }// //GEN-END:initComponents - - private void scaleSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_scaleSpinnerStateChanged - double scale = Graph.getScale((int) scaleSpinner.getValue()); - BigDecimal bd = new BigDecimal(scale); - bd = bd.setScale(6, RoundingMode.HALF_UP); - scaleLbl.setText("1 tick = " + String.valueOf(bd.doubleValue()) + " x"); - }//GEN-LAST:event_scaleSpinnerStateChanged - - /** - * Get the chosen scale. - * - * @return the scale. - */ - public int getScale() { - return (int) scaleSpinner.getValue(); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel helpLbl; - private javax.swing.JLabel scaleLbl; - private javax.swing.JSpinner scaleSpinner; - // End of variables declaration//GEN-END:variables -} diff --git a/src/net/apocalypselabs/symat/MainGUI.form b/src/net/apocalypselabs/symat/MainGUI.form index 62b6b61..10a24d8 100644 --- a/src/net/apocalypselabs/symat/MainGUI.form +++ b/src/net/apocalypselabs/symat/MainGUI.form @@ -30,8 +30,8 @@ - + @@ -50,6 +50,7 @@ + @@ -79,7 +80,7 @@ - + @@ -194,8 +195,10 @@ - - + + + + @@ -207,6 +210,7 @@ + @@ -286,6 +290,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -310,7 +334,7 @@ - + @@ -423,7 +447,7 @@ - + @@ -486,7 +510,7 @@ - + diff --git a/src/net/apocalypselabs/symat/MainGUI.java b/src/net/apocalypselabs/symat/MainGUI.java index 9fe2db3..7cfcd88 100644 --- a/src/net/apocalypselabs/symat/MainGUI.java +++ b/src/net/apocalypselabs/symat/MainGUI.java @@ -1,41 +1,41 @@ -/* +/* * CODE LICENSE ===================== * Copyright (c) 2015, Apocalypse Laboratories * All rights reserved. - * + * * 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 + * + * 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, + * + * 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 + * + * 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 + * + * 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 + * 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 (the "graphics") included with this * software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute - * the graphics or any program, source code repository, or other digital storage + * the graphics or any program, source code repository, or other digital storage * media containing them without written permission from Apocalypse Laboratories. * This ban on distribution only applies to publicly available systems. * A password-protected network file share, USB drive, or other storage scheme that @@ -54,7 +54,6 @@ import java.awt.Image; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -66,31 +65,55 @@ import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import javax.swing.ListModel; import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; /** * This class is like the Force: A light theme, a dark theme, and it binds the * app together. Also like duct tape, but that's not as cool. * - * @author Skylar + * Contains a bunch of important variables and constants that are used all over. + * + * There should be only one MainGUI per app instance, the important things are + * static. + * + * @author Skylar Ittner */ public class MainGUI extends javax.swing.JFrame { // TODO: Add more code comments and stuff in case anybody else reads this - public static final String VERSION_NAME = "1.2"; // For display - public static final String APP_NAME = "SyMAT "+VERSION_NAME; // For display - public static final double APP_CODE = 14; // Version code, for updates and //needs - public static final String API_URL = "https://apis.symatapp.com/"; // API base URL - public static String argfile = ""; - public static Font ubuntuRegular; // Ubuntu font for uniform display + /** + * Version name, as it should be displayed. + */ + public static final String VERSION_NAME = "1.3"; + /** + * Program name, with version name + */ + public static final String APP_NAME = "SyMAT " + VERSION_NAME; + /** + * Version number, for updates and //needs in scripts + */ + public static final double APP_CODE = 15; + /** + * Base URL for building API calls + */ + public static final String API_URL = "https://apis.symatapp.com/"; + + public static String argfile = ""; // For opening file from args + /** + * Ubuntu regular font. + */ + public static Font ubuntuRegular; public static boolean skipPython = false; // Skip python init on start? public static boolean skipEditor = false; // Skip editor init on start? private static boolean recentItemsMinimized = false; - public static boolean updateAvailable = false; + public static boolean updateAvailable = false; // Update available? public static String updateString = ""; - - // Logo for frames + + /** + * Application icon, for setting frame icons. + */ public static ArrayList symatlogo = new ArrayList<>(); /** @@ -99,11 +122,10 @@ public class MainGUI extends javax.swing.JFrame { */ public MainGUI() { initComponents(); - + // Set icon - String[] sizes = {"16","32","48","64","128","256"}; setIconImages(symatlogo); - + // Center screen setLocationRelativeTo(null); @@ -170,16 +192,13 @@ public class MainGUI extends javax.swing.JFrame { updateDisplay(); setVisible(true); if (PrefStorage.getSetting("framemaxed", "no").equals("yes")) { - java.awt.EventQueue.invokeLater(new Runnable() { - @Override - public void run() { -// try { + java.awt.EventQueue.invokeLater(() -> { + // try { // Thread.sleep(500); // } catch (InterruptedException ex) { // // } - setExtendedState(MAXIMIZED_BOTH); - } + setExtendedState(MAXIMIZED_BOTH); }); } } @@ -325,6 +344,7 @@ public class MainGUI extends javax.swing.JFrame { arrangeWindowsBtn = new javax.swing.JButton(); displaySettingsBtn = new javax.swing.JButton(); helpBtn = new javax.swing.JButton(); + notepadBtn = new javax.swing.JButton(); jPanel5 = new javax.swing.JPanel(); wikiBtn = new javax.swing.JButton(); jLabel4 = new javax.swing.JLabel(); @@ -360,6 +380,7 @@ public class MainGUI extends javax.swing.JFrame { }); tabs.setBackground(new Color(240,240,240)); + tabs.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT); tabs.setOpaque(true); jPanel4.setFocusable(false); @@ -421,7 +442,7 @@ public class MainGUI extends javax.swing.JFrame { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(graphBtn) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 506, Short.MAX_VALUE)) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 477, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -482,6 +503,19 @@ public class MainGUI extends javax.swing.JFrame { } }); + notepadBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/apocalypselabs/symat/images/notepad.png"))); // NOI18N + notepadBtn.setText("Notepad"); + notepadBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); + notepadBtn.setFocusable(false); + notepadBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + notepadBtn.setOpaque(false); + notepadBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + notepadBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + notepadBtnActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( @@ -493,8 +527,10 @@ public class MainGUI extends javax.swing.JFrame { .addComponent(arrangeWindowsBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(helpBtn) - .addGap(77, 77, 77) - .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(notepadBtn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) + .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -503,7 +539,8 @@ public class MainGUI extends javax.swing.JFrame { .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(arrangeWindowsBtn, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(displaySettingsBtn, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(helpBtn, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(helpBtn, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(notepadBtn, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); @@ -553,7 +590,7 @@ public class MainGUI extends javax.swing.JFrame { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(forumBtn) .addGap(12, 12, 12) - .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 571, Short.MAX_VALUE)) + .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 542, Short.MAX_VALUE)) ); jPanel5Layout.setVerticalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -636,7 +673,7 @@ public class MainGUI extends javax.swing.JFrame { .addGroup(recentItemsPanelLayout.createSequentialGroup() .addComponent(recentItemsTitle) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 256, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(recentFileBtn) .addContainerGap()) @@ -666,7 +703,7 @@ public class MainGUI extends javax.swing.JFrame { .addComponent(appPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(mainPaneLayout.createSequentialGroup() .addComponent(recentItemsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 189, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 157, Short.MAX_VALUE) .addComponent(jLabel2))) .addContainerGap()) ); @@ -678,8 +715,8 @@ public class MainGUI extends javax.swing.JFrame { getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(mainPane) .addComponent(tabs) + .addComponent(mainPane) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -780,6 +817,10 @@ public class MainGUI extends javax.swing.JFrame { loadFrame(new WebBrowser("Community Forum", "http://forum.symatapp.com/", WebBrowser.FORUM_LOGO)); }//GEN-LAST:event_forumBtnActionPerformed + private void notepadBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_notepadBtnActionPerformed + loadFrame(new Notepad()); + }//GEN-LAST:event_notepadBtnActionPerformed + /* End the button handlers. */ @@ -871,14 +912,6 @@ public class MainGUI extends javax.swing.JFrame { } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException e) { java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, e); } - - if (PrefStorage.getSetting("theme").equals("glass")) { - try { - UIManager.setLookAndFeel("com.seaglasslookandfeel.SeaGlassLookAndFeel"); - } catch (Exception ex) { - - } - } // // @@ -893,12 +926,12 @@ public class MainGUI extends javax.swing.JFrame { ubuntuRegular = Font.getFont(Font.SANS_SERIF); System.err.println("Error loading fonts: " + ex.getMessage()); } - + // Set icon - String[] sizes = {"16","32","48","64","128","256"}; + String[] sizes = {"16", "32", "48", "64", "128", "256"}; for (String s : sizes) { symatlogo.add(new ImageIcon( - MainGUI.class.getResource("logo-filled"+s+".png")).getImage()); + MainGUI.class.getResource("logo-filled" + s + ".png")).getImage()); } // Command line args @@ -924,13 +957,10 @@ public class MainGUI extends javax.swing.JFrame { } Platform.setImplicitExit(false); - + /* Create and display the form */ - java.awt.EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - new SplashScreen().setVisible(true); - } + java.awt.EventQueue.invokeLater(() -> { + new SplashScreen().setVisible(true); }); } @@ -951,6 +981,7 @@ public class MainGUI extends javax.swing.JFrame { public static javax.swing.JPanel jPanel5; public static javax.swing.JScrollPane jScrollPane1; public static javax.swing.JDesktopPane mainPane; + public static javax.swing.JButton notepadBtn; public static javax.swing.JButton recentFileBtn; public static javax.swing.JList recentFileList; public static javax.swing.JPanel recentItemsPanel; diff --git a/src/net/apocalypselabs/symat/Notepad.form b/src/net/apocalypselabs/symat/Notepad.form index f54b41e..aea084b 100644 --- a/src/net/apocalypselabs/symat/Notepad.form +++ b/src/net/apocalypselabs/symat/Notepad.form @@ -1,14 +1,54 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -26,83 +66,33 @@ - + - + - + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/net/apocalypselabs/symat/Notepad.java b/src/net/apocalypselabs/symat/Notepad.java index 8d14008..f2ded17 100644 --- a/src/net/apocalypselabs/symat/Notepad.java +++ b/src/net/apocalypselabs/symat/Notepad.java @@ -1,41 +1,41 @@ -/* +/* * CODE LICENSE ===================== * Copyright (c) 2015, Apocalypse Laboratories * All rights reserved. - * + * * 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 + * + * 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, + * + * 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 + * + * 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 + * + * 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 + * 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 (the "graphics") included with this * software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute - * the graphics or any program, source code repository, or other digital storage + * the graphics or any program, source code repository, or other digital storage * media containing them without written permission from Apocalypse Laboratories. * This ban on distribution only applies to publicly available systems. * A password-protected network file share, USB drive, or other storage scheme that @@ -45,7 +45,12 @@ */ package net.apocalypselabs.symat; +import java.awt.Font; +import javax.swing.JOptionPane; + /** + * + * A simple persistent notepad. * * @author Skylar */ @@ -56,9 +61,7 @@ public class Notepad extends javax.swing.JInternalFrame { */ public Notepad() { initComponents(); - page1.setText(PrefStorage.getSetting("notepad1", "")); - page2.setText(PrefStorage.getSetting("notepad2", "")); - page3.setText(PrefStorage.getSetting("notepad3", "")); + textBox.setText(PrefStorage.getSetting("notepad")); } /** @@ -70,81 +73,91 @@ public class Notepad extends javax.swing.JInternalFrame { // //GEN-BEGIN:initComponents private void initComponents() { - jTabbedPane1 = new javax.swing.JTabbedPane(); - jScrollPane1 = new javax.swing.JScrollPane(); - page1 = new javax.swing.JEditorPane(); - jScrollPane2 = new javax.swing.JScrollPane(); - page2 = new javax.swing.JEditorPane(); - jScrollPane3 = new javax.swing.JScrollPane(); - page3 = new javax.swing.JEditorPane(); + jScrollPane4 = new javax.swing.JScrollPane(); + textBox = new javax.swing.JEditorPane(); + jMenuBar1 = new javax.swing.JMenuBar(); + jMenu1 = new javax.swing.JMenu(); + eraseBtn = new javax.swing.JMenuItem(); + saveBtn = new javax.swing.JMenuItem(); setClosable(true); setIconifiable(true); setMaximizable(true); setResizable(true); setTitle("Notepad"); + setFrameIcon(new javax.swing.ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/notepad.png"))); // NOI18N + + jScrollPane4.setFont(Font.getFont(Font.MONOSPACED)); - page1.addKeyListener(new java.awt.event.KeyAdapter() { - public void keyPressed(java.awt.event.KeyEvent evt) { - page1KeyPressed(evt); + textBox.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + textBoxKeyTyped(evt); } }); - jScrollPane1.setViewportView(page1); + jScrollPane4.setViewportView(textBox); - jTabbedPane1.addTab("Page 1", jScrollPane1); + jMenu1.setText("File"); - page2.addKeyListener(new java.awt.event.KeyAdapter() { - public void keyPressed(java.awt.event.KeyEvent evt) { - page2KeyPressed(evt); + eraseBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK)); + eraseBtn.setText("Erase"); + eraseBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + eraseBtnActionPerformed(evt); } }); - jScrollPane2.setViewportView(page2); + jMenu1.add(eraseBtn); - jTabbedPane1.addTab("Page 2", jScrollPane2); - - page3.addKeyListener(new java.awt.event.KeyAdapter() { - public void keyPressed(java.awt.event.KeyEvent evt) { - page3KeyPressed(evt); + saveBtn.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK)); + saveBtn.setText("Save"); + saveBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveBtnActionPerformed(evt); } }); - jScrollPane3.setViewportView(page3); + jMenu1.add(saveBtn); + + jMenuBar1.add(jMenu1); - jTabbedPane1.addTab("Page 3", jScrollPane3); + setJMenuBar(jMenuBar1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE) + .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 290, Short.MAX_VALUE) + .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE) ); pack(); }// //GEN-END:initComponents - private void page1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_page1KeyPressed - PrefStorage.saveSetting("notepad1", page1.getText()); - }//GEN-LAST:event_page1KeyPressed + private void eraseBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_eraseBtnActionPerformed + int ans = JOptionPane.showInternalConfirmDialog(this, "Erase notepad contents?", "Are you sure?", JOptionPane.YES_NO_OPTION); + if (ans == JOptionPane.YES_OPTION) { + textBox.setText(""); + setTitle("Notepad *"); + } + }//GEN-LAST:event_eraseBtnActionPerformed - private void page2KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_page2KeyPressed - PrefStorage.saveSetting("notepad2", page2.getText()); - }//GEN-LAST:event_page2KeyPressed + private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed + PrefStorage.saveSetting("notepad", textBox.getText()); + setTitle("Notepad"); + }//GEN-LAST:event_saveBtnActionPerformed - private void page3KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_page3KeyPressed - PrefStorage.saveSetting("notepad3", page3.getText()); - }//GEN-LAST:event_page3KeyPressed + private void textBoxKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_textBoxKeyTyped + setTitle("Notepad *"); + }//GEN-LAST:event_textBoxKeyTyped // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JScrollPane jScrollPane2; - private javax.swing.JScrollPane jScrollPane3; - private javax.swing.JTabbedPane jTabbedPane1; - private javax.swing.JEditorPane page1; - private javax.swing.JEditorPane page2; - private javax.swing.JEditorPane page3; + private javax.swing.JMenuItem eraseBtn; + private javax.swing.JMenu jMenu1; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JScrollPane jScrollPane4; + private javax.swing.JMenuItem saveBtn; + private javax.swing.JEditorPane textBox; // End of variables declaration//GEN-END:variables } diff --git a/src/net/apocalypselabs/symat/functions.py b/src/net/apocalypselabs/symat/functions.py index be6330e..3183acc 100644 --- a/src/net/apocalypselabs/symat/functions.py +++ b/src/net/apocalypselabs/symat/functions.py @@ -29,4 +29,8 @@ def drawdot(x, y): def simplify(expr): return _.simplify(expr) def vpa(expr): - return _.vpa(expr) \ No newline at end of file + return _.vpa(expr) +def readfile(path): + return _.readfile(path) +def savefile(data,path): + _.savefile(data,path) \ No newline at end of file diff --git a/src/net/apocalypselabs/symat/icons/notepad.png b/src/net/apocalypselabs/symat/icons/notepad.png new file mode 100644 index 0000000..c9bac0c Binary files /dev/null and b/src/net/apocalypselabs/symat/icons/notepad.png differ diff --git a/src/net/apocalypselabs/symat/images/notepad.png b/src/net/apocalypselabs/symat/images/notepad.png new file mode 100644 index 0000000..f13b87a Binary files /dev/null and b/src/net/apocalypselabs/symat/images/notepad.png differ diff --git a/src/net/apocalypselabs/symat/resources/jsfunctions.txt b/src/net/apocalypselabs/symat/resources/jsfunctions.txt index c556653..25234c1 100644 --- a/src/net/apocalypselabs/symat/resources/jsfunctions.txt +++ b/src/net/apocalypselabs/symat/resources/jsfunctions.txt @@ -14,6 +14,8 @@ plotname()|Gets the title of the graph window. xlim(min,max)|Sets the x-axis min and max values. Cannot be used after a formula has been graphed. plotclr()|Reset the graph. drawdot(x, y)|Places a dot at the given coordinates. +readfile("")|Read a text file from the given filename. +savefile(data,"")|Save the text data to a file. abs(0)|Absolute value of number. asin(0)| acos(0)| diff --git a/src/net/apocalypselabs/symat/resources/pyfunctions.txt b/src/net/apocalypselabs/symat/resources/pyfunctions.txt index 4e26858..feea00f 100644 --- a/src/net/apocalypselabs/symat/resources/pyfunctions.txt +++ b/src/net/apocalypselabs/symat/resources/pyfunctions.txt @@ -13,6 +13,8 @@ xlim(min,max)|Sets the x-axis min and max values. Cannot be used after a formul plotclr()|Reset the graph. drawdot(x, y)|Places a dot at the given coordinates. simplify('')|Simplify the given function. +readfile("")|Read a text file from the given filename. +savefile(data,"")|Save the text data to a file. vpa('')|Computes numerical value or simplifies. fabs(0)|Absolute value of number. asin(0)|