Skip to main content

Code Organization

1 reply [Last post]
nvoxland
Offline
Joined: 2003-06-12

I've been programming Java web applications for several years, but am new to writing Swing apps, and have some questions on organizating my code to keep it maintainable. I would have thought it would be a normal question, but I've looked around the web and in my java books, and can't find anything on the questions I have.

My biggest questions focus on the best way to separate "view" from "control" logic. All the Swing MVC discussions talk about how the built-in controls follow a MVC struture, but what about the components I create? For example, I made a JTaskTree (I control for displaying and manipulating project tasks) that extends from JPanel. In the constructor, I create a JTree with a custom TreeModel and some JButtons with AbstractActions that perform operations on the tree.

When I look at the code, a few bad smells strike me:
1) Everything is being done in the constructor, so not only is it getting very long, but on a more complicated control, a lot of info must be passed as parameters to the constructor (I would prefer a smaller constructor, with a bunch of setXXX methods).

2) There isn't a clean separation of which code builds and lays out the sub-components from the code that modifies the business objects and UI based on user input and external events. I have been trying to wrap the "controller" logic in Action objects, but the code as a whole looks kind of like this:

fileMenu.add(new JCheckBoxMenuItem(
new AbstractAction("Add Time Entry") {
public void actionPerformed(ActionEvent e) {
if (JOptionPane.showConfirm(...) == OK) {
task.addTimeEntry(newEntry);
}
}
}
);

which I feel is an ugly mix of business object calls, responses to actions, and view modifications.

3) It is difficult to find and re-use Actions in multiple places. For example, if I have a "Delete Task" action that can be called from both a menu and by right-clicking on a task, I would like to use the same one for both since they both need to be enabled/disabled together and they do the exact same thing. This problem is compounded when the action needs to be attached to components that are created in different classes.

I have tried a few methods to solve these problems, but none have seemed very successful.

I've tried breaking up the constructor into "standard" methods like createMenuBar, setupLayout, etc. and by having the sub-components constructed together first, then layed out together later. So far, I've found that custom components are different enough that there are not very many standard methods or ways to break up what is being done and it still doesn't solve the problem that the amount of work being done in the constructor is too large.

I've also tried created all my actions as their own classes (rather than anonymous or inner classes). This seems to make them easier to find, but I think this leads to so many classes that before long they will be difficult to find again.

Does anyone have any suggestions, guidelines or can point me to resources on the best way to organize my code?

Thanks,
Nathan

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
zander
Offline
Joined: 2003-06-13

> My biggest questions focus on the best way to separate "view" from "control" logic.

What many seem to miss when they ask this question is that you always have to ask yourself if the structure you created can have multiple views of the same data.

> There isn't a clean separation of which code builds and lays out the sub-components from the code that modifies the business objects and UI based on user input and external events.

If you look at your business objects as a tree of objects that get manipulated (by adding/moving/deleting) then you might want to create an extra object that does this for you.

I always create one object that holds the 'rootnode' of my datastructure. This object receives events to do things like same and load.
Depending on the intelligence of your data-objects you can do the add/delete actions from this controller object, or let the data object do it themselves.
But what you really want to do is to let your new Widget sent events when the user selects something like delete.
The contoller object then listens to it and acts on it.

You may also want to look at this stuff:
https://juipiter.dev.java.net/