6
\$\begingroup\$

I am looking for best practices as they apply to constructor usage in common Java class construction.

Example 1

import javax.swing.*;
import java.awt.*;

public class Painter extends JPanel{

  public Painter(){
     buildGUI();
  }

  private void buildGUI(){
    JFrame frame = new JFrame();
    frame.setLayout(new BorderLayout());
    frame.setTitle("Paint drawing demonstration");
    new Center_frame(frame);

    JPanel headerPanel = new JPanel();
    headerPanel.add(new JLabel("The drawing panel is below"));

    Drawing_panel dp = new Drawing_panel();

    frame.add(BorderLayout.NORTH,headerPanel);
    frame.add(BorderLayout.SOUTH,dp);

    frame.pack();
    frame.setVisible(true);
  }

  public static void main(String args[]){
      new Painter();
  }

}//end class Painter

Example2

import javax.swing.*;
import java.awt.*;

public class Painter extends JPanel{

  public Painter(){
       JFrame frame = new JFrame();
       frame.setLayout(new BorderLayout());
       frame.setTitle("Paint drawing demonstration");
       new Center_frame(frame);

       JPanel headerPanel = new JPanel();
       headerPanel.add(new JLabel("The drawing panel is below"));

       Drawing_panel dp = new Drawing_panel();

       frame.add(BorderLayout.NORTH,headerPanel);
       frame.add(BorderLayout.SOUTH,dp);

       frame.pack();
       frame.setVisible(true);
  }

public static void main(String args[]){
    //create a Painter object
    new Painter();
}

}//end class Painter
\$\endgroup\$
  • 1
    \$\begingroup\$ Both of those have serious potential threading problems. You should be using SwingUtilities.invokeAndWait or SwingUtilities.invokeLater at the very least to wrap the frame.setVisible(true) calls. \$\endgroup\$ – Peter Taylor Sep 15 '11 at 17:20
  • \$\begingroup\$ @Peter. Not an expert so forgive the silly question. How can there be a threading problem. The object does not exist until after the constructor completes. So there is no way for another thread to have a reference to the object to call any methods (let alone the constructor). \$\endgroup\$ – Martin York Sep 15 '11 at 20:50
  • 2
    \$\begingroup\$ @Tux-D, it's not a silly question. Lots of people (and even tutorial writers) don't understand the problem, and (threading being what it is) it's one of those bugs which doesn't trigger every time. The root issue is what's going on behind the scenes in the library, and in particular the interaction with the native widget library, which has to take place in the AWT thread to be safe. Reference (although it's out of date - from Java 6 the first exception is no longer applicable). \$\endgroup\$ – Peter Taylor Sep 15 '11 at 21:01
4
\$\begingroup\$

no one from them, this should be standard or base

EDIT: added DefaultCloseOperation for Top-Level Container

import javax.swing.*;
import java.awt.*;

public class Painter {

    private JFrame frame;
    private JPanel headerPanel;
    private Drawing_panel ;

    public Painter() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.setTitle("Paint drawing demonstration");

        //new Center_frame(frame); 
        //no reason for create another new JFrame look for 
        //JDialog instead of JFrame, if you needed multiplayed
        //view then check CardLayout, is very easy for use 

        headerPanel = new JPanel();
        headerPanel.add(new JLabel("The drawing panel is below"));

        dp = new Drawing_panel();

        frame.add(headerPanel, BorderLayout.NORTH);
        frame.add(dp, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Painter p = new Painter();
            }
        });
    }
} 
\$\endgroup\$
  • 1
    \$\begingroup\$ AWT and Swing-related code must happen in the EDT (the AWT event dispatch thread), you are right. But in practice, you won't run into troubles if initialization codes (like this code) happens in another thread. \$\endgroup\$ – barjak Sep 18 '11 at 19:15
  • \$\begingroup\$ @barjak exclent catch, +1 \$\endgroup\$ – mKorbel Sep 18 '11 at 21:24
2
\$\begingroup\$

What is the purpose of your Painter class ? You are just using its constructor to run some code which is completely unrelated to Painter itself. You are doing the same thing with the two other objects you instanciate : Center_frame and Drawing_panel.

When writing a GUI in Swing, you generally write classes that extend JPanel, and the constructors contains the code that initialize the inner components. It's a bad idea to let the constructor have a side effect (the display of a frame) like you have.

Also, try to follow the Java naming conventions : variables and types names use camel case, and variables start with a lowercase.

When initializing a JFrame, you might be interrested in calling the method setDefaultCloseOperation (generally with JFrame.EXIT_ON_CLOSE or JFrame.DISPOSE_ON_CLOSE)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.