Basic Java GUI, why one works and other doesn't

Started by
3 comments, last by Lothia 16 years, 5 months ago
Hi, I am wondering why the second of these two examples doesn't work. I know this is all very basic, but in my head they should be doing the same thing. Top one is right, also I am wondering, when is PaintComponenet every called? I have seen all examples like this never calling it but it seems to go. Never seen an explanation as to why.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class PowerPaintGUI extends JPanel {
  
  /**
   * Created private so that doing the pack(); will be easier (I think).
   */
  //private JFrame my_frame;
  
  /**
   * Panel that will be our entire drawing panel
   */
  private JPanel my_paint_panel = new JPanel();
  
  /**
   * Constructor that creates the basic Frame. 
   * Might add it so it also creates the menu as well. I do not know yet.
   */
  public PowerPaintGUI() {
    JPanel panel = new JPanel();
    setBackground(Color.WHITE);
    setPreferredSize(new Dimension(400, 300));
  }
  
  /**
   * Basic paint program it says.
   */
  public void paintComponent(final Graphics the_graphics) {
    super.paintComponent(the_graphics);
    final Graphics2D g2d = (Graphics2D) the_graphics;
    //put code here that uses g2d to paint things
    Shape s = new Rectangle2D.Double(10, 10, 80, 80);
    g2d.setPaint(Color.RED);
    g2d.draw(s);
  }
  
  /**
   * 
   * @param the_args just a input nothing more
   */
  
  //Works when like this but never when panel is being created outa main. 
  //want to make it so I can add the panel to the frame... but not working right now
  public static void main(final String[] the_args) {
    final PowerPaintGUI panel = new PowerPaintGUI();
    final JFrame frame = new JFrame("EllipsePanel Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(panel);
    frame.pack();
    frame.setVisible(true);
  }

}
Second one which is how I want it, the basic Panel created in the constructor not in the main. Or if nothing else have it all added together in a start() method. The bottom one does not automatically call the paintcomponenet.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class PowerPaintGUI extends JPanel {
  
  /**
   * Created private so that doing the pack(); will be easier (I think).
   */
  //private JFrame my_frame;
  
  /**
   * Panel that will be our entire drawing panel
   */
  private JPanel my_paint_panel = new JPanel();
  
  /**
   * Constructor that creates the basic Frame. 
   * Might add it so it also creates the menu as well. I do not know yet.
   */
  public PowerPaintGUI() {
    my_paint_panel = new JPanel();
    my_paint_panel.setBackground(Color.WHITE);
    my_paint_panel.setPreferredSize(new Dimension(400, 300));
    
    final JFrame frame = new JFrame("EllipsePanel Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(my_paint_panel);
    frame.pack();
    frame.setVisible(true);
  }
  
  /**
   * Basic paint program it says.
   */
  public void paintComponent(final Graphics the_graphics) {
    super.paintComponent(the_graphics);
    final Graphics2D g2d = (Graphics2D) the_graphics;
    //put code here that uses g2d to paint things
    Shape s = new Rectangle2D.Double(10, 10, 80, 80);
    g2d.setPaint(Color.RED);
    g2d.draw(s);
  }
  
  /**
   * 
   * @param the_args just a input nothing more
   */
  
  //Works when like this but never when panel is being created outa main. 
  //want to make it so I can add the panel to the frame... but not working right now
  public static void main(final String[] the_args) {
    final PowerPaintGUI panel = new PowerPaintGUI();

  }

}
Advertisement
I'd suspect this is the problem:
public PowerPaintGUI() {    my_paint_panel = new JPanel();    my_paint_panel.setBackground(Color.WHITE);    my_paint_panel.setPreferredSize(new Dimension(400, 300));    final JFrame frame = new JFrame("EllipsePanel Demo");    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    frame.add(my_paint_panel);    frame.pack();    frame.setVisible(true);  }



First, frame that you allocate is not referenced anywhere, and it might be garbage collected after the constructor is over.

In addition, it's generally not advised to call non-static object's method in constructor. setVisible might break the excpected calling order.

But above all, it's very bad practice for logical children to allocate their own parents.

PowerPaintGUI will be contained within *a* frame. As such, if you need *the* frame, *the* frame should create new PowerPaintGUI.

Quote:Second one which is how I want it


Simply put: you want it done wrong, since you're completely inverting the ownership and logical containment.

Go with first example.


But in neither case should PowerPaintGUI contain its frame. There is no connection whatsover between a Panel and the owning container. It's just bad design practice to introduce such dependency.

If you do for some reason need one of owners, pass it as parameter to PowerPaintGUI constructor.
Okay, so I took stuff out of the constructor and tried to make it so that it is all called in a Start Method, how ever, I still get the same error where it does not draw the pictures. I have a blank constructor and just call it so I can call the start.
I am wondering, since I am extending JPanel, I do not need to crate my own JPanel, but IF I put the JPanel BG and size calls in the constructor how can i add them to the frame.
This is kinda how I want it more then in main.
PLease assist.

import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Shape;import java.awt.geom.Ellipse2D;import java.awt.geom.Rectangle2D;import javax.swing.JFrame;import javax.swing.JPanel;public class PowerPaintGUI extends JPanel {    /**   * Created private so that doing the pack(); will be easier (I think).   */  private JFrame my_frame;    /**   * Panel that will be our entire drawing panel   */  private JPanel my_paint_panel = new JPanel();    /**   * Constructor that creates the basic Frame.    * Might add it so it also creates the menu as well. I do not know yet.   */  public PowerPaintGUI() {      }    /**   * Basic paint program it says.   */  public void paintComponent(final Graphics the_graphics) {    super.paintComponent(the_graphics);    final Graphics2D g2d = (Graphics2D) the_graphics;    //put code here that uses g2d to paint things    Shape s = new Rectangle2D.Double(10, 10, 80, 80);    g2d.setPaint(Color.RED);    g2d.draw(s);  }    public void start() {    my_frame = new JFrame("EllipsePanel Demo");    my_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        my_paint_panel = new JPanel();    my_paint_panel.setBackground(Color.WHITE);    my_paint_panel.setPreferredSize(new Dimension(400, 300));        my_frame.add(my_paint_panel);    my_frame.pack();    my_frame.setVisible(true);  }    /**   *    * @param the_args just a input nothing more   */    //Works when like this but never when panel is being created outa main.   //want to make it so I can add the panel to the frame... but not working right now  public static void main(final String[] the_args) {    PowerPaintGUI panel = new PowerPaintGUI();    panel.start();  }}
my_paint_panel = new JPanel();    my_paint_panel.setBackground(Color.WHITE);    my_paint_panel.setPreferredSize(new Dimension(400, 300));        my_frame.add(my_paint_panel);    my_frame.pack();    my_frame.setVisible(true);


You never add your PowerPaintGUI which has overriden paintComponent method to the frame - so it never gets called.

You create a generic JPanel, which uses its own generic paintComponent.

This is also the problem in both of your original examples.
So what is the easiest way to add my paintcomponent?

This topic is closed to new replies.

Advertisement