Hi Guys
I have a program thats supposed to generate 9 random objects made from lines and then allow me to save the panel showing the state of all 9 objects.
Currently all 9 objects are being generated and when i click save the panel is being saved to a png file. However it seems that the png file and the panel are in two different states. Ive attached pictures at the end.

code for my current GUI where the save button is located:
`import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class GUI extends JFrame{

Random rGen;
BiomorphObject[] morphs = new BiomorphObject[9];
double[] genes;
//Create containers to hold the components
JPanel biomorphPanel  = new JPanel(new BorderLayout());
JPanel buttonsPanel   = new JPanel(new BorderLayout());
JPanel HOF = new JPanel(new BorderLayout());

public GUI(){

JFrame mainFrame = new JFrame("Biomorph");

BiomorphObject object1 = new BiomorphObject();
BiomorphObject object2 = new BiomorphObject();
BiomorphObject object3 = new BiomorphObject();
BiomorphObject object4 = new BiomorphObject();
BiomorphObject object5 = new BiomorphObject();
BiomorphObject object6 = new BiomorphObject();
BiomorphObject object7 = new BiomorphObject();
BiomorphObject object8 = new BiomorphObject();
BiomorphObject object9 = new BiomorphObject();

JButton hof   = new JButton("Hall of Fame");

//Create the buttons
JButton randomButton = new JButton("Random Biomorph");
JButton saveButton   = new JButton("Save");
JButton loadButton   = new JButton("Load");
JButton printButton  = new JButton("Print?");
JButton exitButton   = new JButton("Exit");

//Set the properties of the components
randomButton.setToolTipText("Create New Random Biomorph"); 
randomButton.setPreferredSize(new Dimension(150, 40));
randomButton.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    biomorphPanel.repaint();
  }
});

saveButton.setToolTipText("Save the current Biomorph"); 
saveButton.setPreferredSize(new Dimension(150, 40));
saveButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        BufferedImage bi = new BufferedImage(biomorphPanel.getSize().width, biomorphPanel.getSize().height, BufferedImage.TYPE_INT_ARGB); 
        Graphics g = bi.createGraphics();
        biomorphPanel.paint(g);  
        g.dispose();
        try{ImageIO.write(bi,"png",new File("test.png"));}catch (Exception e1) {}
    }
});


loadButton.setToolTipText("Load previously made Biomorph"); 
loadButton.setPreferredSize(new Dimension(150, 40));

printButton.setToolTipText("Print Biomorph"); 
printButton.setPreferredSize(new Dimension(150, 40));

exitButton.setToolTipText("Close the Application"); 
exitButton.setPreferredSize(new Dimension(150, 40));
exitButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    });

//add the buttons to the panel.     
buttonsPanel.add(randomButton, BorderLayout.WEST);
buttonsPanel.add(saveButton, BorderLayout.CENTER);
buttonsPanel.add(loadButton, BorderLayout.CENTER);
buttonsPanel.add(printButton, BorderLayout.CENTER);
buttonsPanel.add(exitButton, BorderLayout.EAST);
buttonsPanel.setLayout(new FlowLayout());

biomorphPanel.add(object1);
biomorphPanel.add(object2);
biomorphPanel.add(object3);
biomorphPanel.add(object4);
biomorphPanel.add(object5);
biomorphPanel.add(object6);
biomorphPanel.add(object7);
biomorphPanel.add(object8);
biomorphPanel.add(object9);
biomorphPanel.setLayout(new GridLayout(3,3));

HOF.add(hof,BorderLayout.CENTER);

mainFrame.getContentPane().add(HOF, BorderLayout.EAST);
mainFrame.getContentPane().add(biomorphPanel, BorderLayout.CENTER);
mainFrame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);


mainFrame.setVisible(true);
mainFrame.setSize(800,400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(false);
}

}

This is what the panel looks like:
http://s16.postimg.org/iqt2xpc2d/panel.png

and this is what gets saved:
http://s15.postimg.org/dprm8n95n/test.png

If you need more information then please ask

any help will be appreciated.

Line 62 is a terrible mistake.

You have a problem related to a file being written
In the code that writes the file you go out of your way to supress any exceptions and hide/discard any exception messages. You are saying "if anything goes wrong just pretend it didn't and keep going - don't bother me with it".

Nobody here is going to waste another second on ths until you put an e.printStackTrace(); in your catch block and run it a few more times.
(Maybe that's not where the problem is, but it's dumb not to eliminate it first.)

I added the e.printStackTrace(); code in but it doesnt seem to do anything.
Still having the same issue with the different versions being saved

Edited 1 Year Ago by spud91

What does the paint (or paintComponent) method for the panel look like? The random button just seems to repaint without any explicit randomising, so is the randomising embedded in the paint? (In which case, that's your problem.)

This is the code for paintComponent

public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.BLUE);
    Dimension size = getSize();

    int w = size.width;
    int h = size.height;

    Random ran = new Random();
    int x = Math.abs(ran.nextInt(100)) % w + 120;
    int y = Math.abs(ran.nextInt(100)) % h;
    int xMirror = x - 120;
    g2d.drawLine(120, 85, x, y);
    g2d.drawLine(120, 85, 120 - xMirror, y);
    int x1 = x;
    int y1 = y;
    int x2 = Math.abs(ran.nextInt(50)) % w + 120;
    int y2 = Math.abs(ran.nextInt(50)) % h;

    for (int i = 0; i <= 10; i++) {
        int xMirror1 = x1 - 120;
        int xMirror2 = x2 - 120;
        g2d.drawLine(x1, y1, x2, y2);
        g2d.drawLine(120 - xMirror1, y1, 120 - xMirror2, y2);
        x1 = x2;
        y1 = y2;
        x2 = Math.abs(ran.nextInt(100)) % w + 120;
        y2 = Math.abs(ran.nextInt(100)) % h;
    }

That's it, just as I suspected.
Every time you execute paintComponent you get new random shapes.
To get the graphics for the file you call paint, which calls paintComponent...

It's always a mistake to change anything in paintComponent because it can be called at any time (eg when the window is re-sized). You should create a separate method to create new random shapes, and just paint the current shapes in paintComponent

Im a little confused as to how to do that.
In the class where paintComponent is called should i create another method that does the random shapes?

You need to do something like:
1. define some variables/arrays/whatever that can hold the definition of the latest random shapes.
2. write a method that populates that with new random data
3. call that method from your randomButton ActionListener (then call repaint();)
4. in paintComponent use that data to draw all the shapes

Edited 1 Year Ago by JamesCherrill

This article has been dead for over six months. Start a new discussion instead.