A common practice in Swing programs, and even in Sun’s tutorials, is to subclass components to use them. Here’s a typical Hello World example.
class Main { public static void main(String[] args) { MyFrame frame=new MyFrame(); frame.setVisible(true); } } class MyFrame extends JFrame { MyFrame() { super("My Frame"); setSize(400,400); setLayout(new FlowLayout()); add(new JButton("Hello World")); } }
There are a number of reasons that programmers do this.
There are also a number of reasons not to do this.
The first alternative is to create the JFrame in the main method:
class Main { public static void main(String[] args) { JFrame frame=new JFrame("My Frame"); frame.setSize(400,400); frame.setLayout(new FlowLayout()); frame.add(new JButton("Hello World")); frame.setVisible(true); } }
You might not always want the frame to be initialised in the same place you use it, you might prefer a dedicated place for this:
class Main { public static void main(String[] args) { JFrame frame=MainFrameUtility.createMainFrame(); frame.setVisible(true); } } class MainFrameUtility { public static JFrame createMainFrame() { JFrame frame=new JFrame("My Frame"); frame.setSize(400,400); frame.setLayout(new FlowLayout()); frame.add(new JButton("Hello World")); return frame; } }
The next problem is when you want to access the button later for some reason. Here is the subclassing way of doing it:
class MainFrame extends JFrame { private JButton button=new JButton("Hello World"); public MainFrame() { super("My Frame"); setSize(400,400); setLayout(new FlowLayout()); add(button); } public JButton getButton() { return button; } }
Here is a way of doing this using composition instead of inheritance:
class MainFrame { private JFrame frame; private JButton button; public MainFrame(JFrame frame,JButton button) { this.frame=frame; this.button=button; } public JFrame getJFrame() { return frame; } public JButton getJButton() { return button; } } class MainFrameUtility { public static JFrame createMainFrame() { JFrame frame=new JFrame("My Frame"); frame.setSize(400,400); frame.setLayout(new FlowLayout()); JButton button=new JButton("Hello World"); frame.add(button); return new MainFrame(frame,button); } }
A more optimal way of doing this follows, but the ideas are the same:
interface MainFrame { JButton getButton(); JFrame getFrame(); } final class MainFrameUtility() { private MainFrameUtility() { throw new UnsupportedOperationException(); } public static MainFrame createMainFrame() { final JFrame frame=new JFrame("My Frame"); frame.setSize(400,400); frame.setLayout(new FlowLayout()); final JButton button=new JButton("Hello World"); frame.add(button); return new MainFrame() { public JFrame getJFrame() { return frame; } public JButton getJButton() { return button; } }; } }
Things to do: