Commentary - Build window in main()
Subclassing JFrame
The most common way to build a graphical user interface is to subclass JFrame. If you haven't already, read GUI 7 - DogYears - Listeners for an example of this. Below you'll find the DogYears program rewritten in a style that builds the window entirely in main().
Writing a GUI in main()
You may sometimes see a GUI constructed entirely in the main() method.
Scaling problems. Why is it that writing the GUI in main() is less common,
except for simple programs? I've never tried it for larger programs, but
it doesn't seem to be appropriate as programs get larger.
As the amount of code increases, it's common to write private utility
methods that help you manage the user interface, for example, clearInputFields()
,
disableEditingControls()
, etc. If you build the window in main()
and store the components in final local variables, no other method
can reference them. You could pass them as parameters, but things are starting
to get uglier. I don't see a clean way around this, but perhaps there is one.
Anonymous inner classes
Anonymous inner classes are very useful, altho they have a somewhat cryptic syntax.
One use. They are often used when only one reference
to class is needed, in which case they are defined at the point the
reference is needed. In the example below, an anonymous class is
created for the button action listener, in the addActionListener()
call.
Inside methods. Unlike other inner classes, they can be created inside of a method, at the point an object reference is needed.
Interface name. Following the new
keyword, you can
write an interface name, followed by "()". This creates an anonymous class
that implements that interface.
No constructor. Note that no constructor is possible (there's no name).
Final method variables/parameters. Like other inner classes, an anonymous inner class method can refer to static class variables in the enclosing class. It can also refer to final variables in the enclosing method, but not to either other local variables in the method or to any of the instance variables in the class.
Requires anonymous inner listeners and final local variables
You'll see in the example below how the JFrame subclass style was transformed into the all-in-main style by making an anonymous inner class listener and changing instance variables to final local variables.
Source code: DogYears entirely in main()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// File : gui-tutorial/DogYears2main.java // Purpose: Dog years conversion program with anonymous listener. // This builds the GUI entirely in main, with final // local vars and anon innner class listener. // Author : Fred Swartz - 2006-11-09 import java.awt.*; import javax.swing.*; import java.awt.event.*; // Needed for ActionListener ///////////////////////////////////////////////// class DogYears2main class DogYears2main { //===================================================== constants private static final int DOG_YEARS_PER_HUMAN_YEAR = 7; public static void main(String[] args) { //Note 1 //======================================= final variables final JTextField humanYearsTF = new JTextField(3); final JTextField dogYearsTF = new JTextField(3); // 1... Create/initialize components JButton convertBtn = new JButton("Convert"); convertBtn.addActionListener(new ActionListener() { //Note 2 public void actionPerformed(ActionEvent e) { //... Get the value from the dog years textfield. String dyStr = dogYearsTF.getText(); int dogYears = Integer.parseInt(dyStr); //... Convert it - each dog year is worth 7 human years. int humanYears = dogYears * DOG_YEARS_PER_HUMAN_YEAR; //... Convert to string and set human yrs textfield humanYearsTF.setText("" + humanYears); } }); // 2... Create content panel, set layout JPanel content = new JPanel(); content.setLayout(new FlowLayout()); // 3... Add the components to the content panel. content.add(new JLabel("Dog Years")); content.add(dogYearsTF); // Add input field content.add(convertBtn); // Add button content.add(new JLabel("Human Years")); content.add(humanYearsTF); // Add output field // 4... Create window and display it. JFrame window = new JFrame("Dog Year Converter"); window.setContentPane(content); window.pack(); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setLocationRelativeTo(null); // Center window. window.setVisible(true); } } |
Notes
- The GUI can be built inside main by using "final" instead of instance variables, and anonymous inner class listeners. But subclassing JFrame is a more common style, .
- "Anonymous inner class" listeners are a common way to attach listeners to GUI components. They are used in many styles pf GUI implemenation