2

So I have this code. And I'm trying to implement click to save on the JMenuBar and click to load. I am having trouble serializing the JPanel.

How could I save the current plot view? the layout is set to AbsoluteLayout so the GroupLayout issue is not a problem. I've read through Google searches and I know this is not recommended but how else could I save and load it?

package tester;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
import static tester.Plot.XMAX;
import static tester.Plot.XMIN;
import static tester.Plot.YMAX;
import static tester.Plot.YMIN;
import java.io.*;

/**
 *
 * @author Sana
 */
public class NewJFrame2 extends javax.swing.JFrame{

    public class Plot extends JPanel implements java.io.Serializable {

    public double xmin=0;
    public double xmax=0;
    public double ymin=0;
    public double ymax=0;
    public static final int XMIN = 45;
    public static final int XMAX = 420;
    public static final int YMIN = 300;
    public static final int YMAX = 25;
    Plottable2D plotFunction;
    Shape myShape;
    double[]xS;
    double[]yS;
    Graphics2D g2d;


    public void setAxis(double[] a){
       xmin=a[0];
       xmax=a[1];
       ymin=a[2];
       ymax=a[3];
    }

    public void setFunction(Plottable2D plotFunction){
        this.plotFunction = plotFunction; 
        xS = new double[100];
        for (int i=0;i<99;i++)
            xS=HW6ArrayMath.linspace(xmin, xmax, 99);
        yS = plotFunction.evaluate(xS);

        //repaint();

    }


    @Override
    public void paintComponent(Graphics g){
        Plot myPlot = (Plot) jPanel1;

        g.setColor(Color.white);
        g.fillRect(0, 0, getWidth(), getHeight());

        myPlot.setAxis(new double[] {0,1,0,1});
        myPlot.setFunction(new MyFunction());
        Graphics2D g2d = (Graphics2D) g;

        String xminString = "" + xmin;
        String xmaxString = "" + xmax;
        String yminString = "" + ymin;
        String ymaxString = "" + ymax;

        g2d.setColor(Color.BLUE);
        g2d.drawLine(XMIN,YMIN,XMAX,YMIN);
        g2d.drawString(xminString,XMIN, YMIN+10);
        g2d.drawString(xmaxString,XMAX, YMIN+10);
        g2d.drawLine(XMIN,YMIN, XMIN, YMAX);
        g2d.drawString(yminString,XMIN-15,YMIN);
        g2d.drawString(ymaxString,XMIN-15,YMAX); 


        for (int i=0;i<99-1;i++){
            double a = (xS[i]*(XMAX-XMIN))+XMIN;
            double b = (YMIN-(yS[i]*(YMIN-YMAX)));
            double c = (xS[i+1]*(XMAX-XMIN))+XMIN;
            double d = (YMIN-((yS[i+1]*(YMIN-YMAX))));
            g2d.draw(new Line2D.Double(a, b, c,d));
        }
    }

}


    /**
     * Creates new form NewJFrame2
     */
    public NewJFrame2() {
        initComponents();

    }

    /**
     * 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">                          
    private void initComponents() {

        jPanel1 = new Plot();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jMenuBar2 = new javax.swing.JMenuBar();
        jMenu3 = new javax.swing.JMenu();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jPanel1.setBackground(new java.awt.Color(255, 240, 240));
        jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel2.setText("X Axis");
        jPanel1.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(250, 330, -1, -1));

        jLabel3.setText("Y Axis");
        jPanel1.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 151, -1, -1));

        getContentPane().add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(57, 46, 520, 360));

        jLabel1.setText("My Plot");
        getContentPane().add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(300, 30, 40, -1));

        jMenu3.setText("File");

        jMenuItem2.setLabel("Save");
        jMenuItem2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jMenuItem2MouseClicked(evt);
            }
        });
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu3.add(jMenuItem2);

        jMenuItem3.setLabel("Load");
        jMenuItem3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jMenuItem3MouseClicked(evt);
            }
        });
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        jMenu3.add(jMenuItem3);

        jMenuBar2.add(jMenu3);

        setJMenuBar(jMenuBar2);

        pack();
    }// </editor-fold>                        

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {                                           
        try {  
       ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Sana\\Documents\\NetBeansProjects\\MyPlot.ser"));

       out.writeObject(jLabel1);
       out.writeObject(jLabel2);
       out.writeObject(jLabel3);
       out.close();

        }
        catch(Exception e) {
            e.printStackTrace();
    }        
    }                                          

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {                                           
        // TODO add your handling code here:
    }                                          

    private void jMenuItem2MouseClicked(java.awt.event.MouseEvent evt) {                                        

    }                                       


    private void jMenuItem3MouseClicked(java.awt.event.MouseEvent evt) {                                        
       try { 
           FileInputStream saveFile = new FileInputStream("MyPlot.ser");
           ObjectInputStream restore = new ObjectInputStream(saveFile);
           jPanel1 = (Plot) restore.readObject();
           restore.close();
       }catch (Exception exc){
       exc.printStackTrace();
       }

       repaint();
    }                                       


    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame2().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JMenu jMenu3;
    private javax.swing.JMenuBar jMenuBar2;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   
}

Right now its giving this error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javax.swing.plaf.synth.SynthLookAndFeel.paintRegion(SynthLookAndFeel.java:371)
    at javax.swing.plaf.synth.SynthLookAndFeel.update(SynthLookAndFeel.java:335)
    at javax.swing.plaf.synth.SynthRootPaneUI.update(SynthRootPaneUI.java:119)
    at javax.swing.JComponent.paintComponent(JComponent.java:780)
    at javax.swing.JComponent.paint(JComponent.java:1056) etc.
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Sana
  • 73
  • 1
  • 1
  • 5
  • See [What is a stack trace, and how can I use it to debug my application errors?](http://stackoverflow.com/q/3988788/418556) & [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/q/218384/418556) – Andrew Thompson May 15 '15 at 23:16

1 Answers1

7

You're going about this the wrong way. You should be serializing the data that the plotview reads from, not the plotview itself.

Make an object to contain your data:

public class PlotViewData implements Serializable {
    public double xmin=0; //Should be private
    public double xmax=0;
    public double ymin=0;
    public double ymax=0;
    public static final int XMIN = 45;
    public static final int XMAX = 420;
    public static final int YMIN = 300;
    public static final int YMAX = 25;
    //Extra data with getters and setters goes here.
}

And then serialize and read from that object, the components should be re-created by your application.

Thomas Nairn
  • 1,186
  • 8
  • 34
  • So I already have a class Plot inside class NewJFrame2 so I should add another inner class in NewJFrame2? I've also tried adding just the xS array to the out object but it says "non-static variable cannot be referenced from static context" – Sana May 15 '15 at 15:00
  • Avoid inner classes, take a step back and visualize what your application is actually plotting. Data - That's all it is, you need a data holder class and by making it an inner class, you inherently force the usage of that data to the Plot, who's to say that you won't decide to use that data elsewhere? (The reason you're getting that error is because you didn't make the inner class static). Separate your views and data. – Thomas Nairn May 15 '15 at 15:02
  • I need to use inner class because of my project spec. So I created the myData inner class and now Plot cant access the "non-static" setxMin from static context. I keep running into this issue. If I make Plot static then "Plot myPlot = (Plot) jPanel1;" shows an error – Sana May 15 '15 at 16:02