Search code examples
javauser-interfaceswingstandardscoding-style

Java/Swing GUI best practices (from a code standpoint)


As a contrast to this wiki, I am looking for the proper way to implement Swing GUI controls from a coding standpoint.

I have been on a quest to learn Java and its GUI tools but I find internet tutorial after internet tutorial that throws everything in main and I know this isn't right.

I've also tried RAD systems like Netbeans and other "visual" editors but by the time I get to coding I've got a heap of code that I don't know half of what it does, so I'm intent on learning to hand code swing, and I know the basic controls and layout, but want to do it the right way.

Is there a model or standard I'm missing?

example questions...

do I extend JFrame and create my own frame object? (I would assume yes)

do I encapsulate the main menu inside that frame object? or do I create its own? etc...

How to I separate "View" logic from "Application" logic?

Basically, I'm looking for what the industry standard is, on how to organize GUI code.


Solution

  • Since there seems to be some argument about what constitutes "best practices", I'll give you what I have found works best for me, and my reasoning:

    1. Each window should extend either JFrame or JDialog (depending on the type of window). This makes it easy to control the properties of the window without specifying a specific object every time. This is more of the general case, though, as I have been known to do it both ways.

    2. The main() method should be in a separate class. This increases the likelihood of being able to use your window classes elsewhere, as they are not tied to specific implementations. Technically it doesn't make a difference, but application startup code just doesn't belong in a window.

    3. Listeners should be in anonymous inner classes. Your top-level class should not implement any listeners. This prevents hacks like calling the listener methods from anywhere except the object to which they are attached.

    Here is a simple application with a single frame to demonstrate these practices:

    public class Main {
        public static void main(String[] args) {
            final String text = args[0];
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    final MyWindow wnd = new MyWindow(text);
                    wnd.setVisible(true);
                }
            });
        }
    }
    
    public class MyWindow extends JFrame {
        public MyWindow(String text) {
            super("My Window");
    
            setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    MyWindow.this.setVisible(false);
                    MyWindow.this.dispose();
                }
            });
    
            final JButton btn = new JButton(text);
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(MyWindow.this, "Button Pressed", "Hey", JOptionPane.INFORMATION_MESSAGE);
                }
            });
    
            setLayout(new FlowLayout());
            add(btn);
            pack();
        }
    }