tags:

views:

151

answers:

4

I have made a Swing application which is rather simple in functionality. However the code which it consist of became rather large and very messy in my opinion. All the swing components and actions is in one file. So for instance if I was to make a even larger application with more functionality the code will be rather hard to go through.

So my question is how to make a good structure of the code. Or if there's a good webpage I can read about it, and if possible some code examples. I have checked Sun's tutorial about Swing, but those a rather simplistic examples they've shown.

UPDATE: I have pondering a while and check for some examples. I don't know if I got the MVC pattern correct. Anyway my idea is to seperate each JFrame to their own class file. Afterward I have one MainFrame which is the main window for the application. From that JFrame I create one instance of each JFrame I have. And call those frame from the MainFrame with Actions. I don't know if this is a good idea. However it makes the code significant easier to read anyway.

Here's an example of how I meant

class Main implements ActionListener {

    private JFrame frame = new JFrame();
    private JButton button1 = new JButton();
    private JPanel panel = new JPanel();

    private FirstFrame frame1 = new FirstFrame();
    private SecondFrame frame2 = new SecondFrame();
    private ThirdFrame frame3 = new ThirdFrame();

    public Main() {
     button1.addActionListener(this);
    }

    public createGUI() {
     frame.setTitle("Main");
     frame.setSize(400,300);
     panel.add(button);

     frame.setVisible(true);
     frame.setLocationRelativeTo(null);
    }

    public static void main(String args[]) {
     new Main().createGUI();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
     if(e.getSource() == button1)
     {
      frame1.enable();
     }
    }
}
+7  A: 

Use Model-View-Controller design pattern. It deals with separating user interface code from Business logic.

EDIT :

As OP is looking for organized code rather than flexible design, I have removed the NetBeans UI Designer part from my answer.

missingfaktor
I have used visual UI addons for Eclipse, but my experience is it will add alot of scrap code. Is this the same case for Netbeans?
starcorn
however, if there's resource to read I like to learn to code manually as well
starcorn
+4  A: 

Organizing user interface code of any significant size is a problem with surprisingly little written about it, considering that every application has the same problem. There are some techniques that can help:

  1. Refactoring - to clean up after the code gets untidy.
  2. Model View Controller pattern - to separate concerns.
  3. OO Design - use many small, cooperating classes instead of big chunks of code.
  4. "On event Do action" - idiom for separating the actions from the views.
  5. UML Component models - visualize design concepts above the class level.
  6. Dependency Inversion Principle - organize code dependencies.

The basic design techniques have been around for quite some time, and are well understood, but applying the techniques on a larger scale is something that seems to be designed individually for each application.

One approach that I have seen applied effectively is to separate out the Events, Listeners, Actions, etc into their own classes and either organize them into packages by type, or use a consistent naming convention across packages so that a component and its associated classes are easily identifiable (XDialog, XDialogMouseListener, XDialogCancelAction, etc).

Another approach would be to look at some large open source applications (Eclipse, Firefox, ...), and see how they organize their GUI code.

richj
How to seperate the code? Since I have some views. Which depends on actions, thus I can't seperate it.
starcorn
If you split an action from a view and it no longer compiles, then you can introduce extra methods to allow the separate classes access to the missing functionality. The extra methods should be organized into interfaces. The interface can be declared with package level access if the methods should not be publicly available.
richj
In MVC views would not normally depend on actions, although in MV2 the view and the controller can be more closely coupled. Introducing interfaces allows you to use the Dependency Inversion Principle to reverse the direction of any dependencies that go the wrong way.
richj
+2  A: 

I tend to pull as much non-GUI related functionality out of the Swing components as possible. That means you have some extra indirection. However:

  1. the Swing layer does nothing but GUI interaction
  2. the business functionality is a lot easier to test and consequently maintain

I'm not necessarily talking about a complete MVC model (although that's no bad thing). It's more of a class/package organisation issue.

Brian Agnew
+1 for pragmatism, I do the same thing. Particularly with a GUI designer like JFormDesigner which makes it really easy to add actions and action handlers for buttons, etc. It makes sense to have all that in a single class, which calls helper classes. For example, my print action is just a wrapper which calls new PrintTask().print(myJob). PrintTask is a separate (not inner) class, which has nothing to do with the GUI.
Sam Barnum
+1  A: 

The thing to keep to the front of your mind is that UI programming is just like other types of programming. Don't think that it is special and that you can ignore sensible practices. Unfortunately most tutorial code is very bad, and code in production presumably tends to be far worse.

Key points:

  • Use a layered design. That isn't just persistence-business-ui. Split it finer. For instance, a layout layer shouldn't be creating components (other than for layout, typically JPanels).
  • Prefer composition to inheritance. There is very little point subclassing the likes of JFrame and JPanel, so don't do it.
  • Keep the UI thin. For instance renderers should have very little logic in them. For one thing this makes testing much easier (that's automated testing, large scale testing by hand is counter-productive).
Tom Hawtin - tackline