1

I am not skilled in GUI design. After much thought, research and experimentation I've developed several design ideas but still none that seems efficient. One design has a Session god object register a listener on every UI element when created, and every object that cares about any action registers a listener on the Session object. This seems simple and robust, as all messaging goes through a central location so it's less likely that anything is lost. It's brute force though, and seems cumbersome and inefficient.

Another design attempts to create subgroups of objects that speak to each other. This avoids the huge top-level Session and seems more efficient, but also seems error prone.

I'm trying to implement a framework for reuse where I group buttons with related purposes into toolbars and have a hierarchical approach to listening for actions performed by toolbars with relevant operations to the listener. I've gotten to this so far:

public class EditorToolBar extends JToolBar {
public static enum Command {
    ZOOMIN,
    ZOOMOUT,
    FINER,
    COARSER,
    RESET
}

private ButtonCommandListener       listener = new ButtonCommandListener();
public EditorToolBar() {
    super("Editor Commands");
    JButton button;
    for (final Command cmd : Command.values()) {
        button = new JButton(cmd.toString());
        button.setEnabled(true);
        button.setToolTipText(cmd.toString() + " Command");
        button.setActionCommand(cmd.toString());
        button.addActionListener(listener);
        add(button);
    }
}
public void addActionListener(ActionListener pNewListener) {
    listener.cActionNotifier.addListener(pNewListener);
}
private class ButtonCommandListener implements ActionListener {
    private NotifierImp<ActionListener>         cActionNotifier = new NotifierImp<ActionListener>();
    public void actionPerformed(ActionEvent pEvent) {
        for (ActionListener listener : cActionNotifier) {
            listener.actionPerformed(pEvent);
        }
    }
}
} // class EditorTooBar

and the listeners implement something like this:

    public void actionPerformed(ActionEvent pEvent) {
    switch (EditorToolBar.Command.valueOf(pEvent.getActionCommand())) {
        case ZOOMIN:
            // do something
            break;
        case ZOOMOUT:
            // do something
            break;
        case FINER:
            // do something
            break;
        case COARSER:
            // do something
            break;
        case RESET:
            // do something
            break;
        default:
            System.out.println("Unknown EditorToolBar Command: "+pEvent.getActionCommand());
            return;
    }

I can enhance the instructor for the enum to also include tooltip text, images, etc. I'd like to reuse this design with just a different enum describing other toolbars. Listeners will distinguish different button actions using ActionEvent.getActionCommand() and use Command.toValue(String). I'd like this to extend to a hierarchy of classes that are listening: a superclass may implement a listener for one type of toolbar, and subclass add to that by listening for a different toolbar type. If the event is not from the toolbar the subclass is interested in, it can forward the event to the superclass. To make this work, I need a way to distinguish between one toolbar and another, but preferably without having to check for every button event possible from that toolbar. Ideally I'd like to have a toolbar factory, and just specifying an enum would be enough to fully describe a toolbar. Not being able to subclass an enum adds to the challenge here.

Is this a promising design pattern to pursue? I've not seen it anywhere else yet. Is there a better way that I should be using rather than inventing something that is inferior? A link to other options would be welcome.

Edit: Based on the answer from yash ahuja I should clarify that when I mention hierarchy I mean similar to the way that key bindings are handled (i.e. do you have a binding? No, then does your container have a binding? ... until someone consumes the key event) not the actual class hierarchy.

ags
  • 719
  • 7
  • 23

2 Answers2

2

As a way to encapsulate functionality, consider combining JToolBar, discussed in How to Use Tool Bars, with Action, discussed in How to Use Actions. The example cited here exports a single tool bar. In contrast, the StyledEditorKit, illustrated here, exports families of Action subtypes that apply to the current selection of a text component.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Rereading the ToolBar tutorial helped by (somewhat opaquely) demonstrating how to "bundle" events from all buttons in a toolbar into one place (does toolbar use setSource() to make the ActionEvents appear to be from one place?). The first cited example illustrates another idea I had by having the model responsible for creating its own control. In the example I assume that the getControl() method is also responsible for connecting the constructed control with the "parent" model before returning it. I'm still looking to factor the implementation of the "machinery" as stated in the OP. – ags Oct 30 '12 at 17:10
  • Yes; `getControlPanel()` returns the already constructed tool bar having bound actions. I've had no practical use for hierarchical event handling, but that is not dispositive. – trashgod Oct 31 '12 at 01:09
1

The design is pretty good but if you create a hierarchy of Tool bars then, in a situation where a particular button is clicked on particular tool bar the corresponding action performed for that button may not be accurate. Also at times multiple events can be triggered. Also there are some tool bars for which it is difficult to identify that under which super class they should belong or if they are implementing features from multiple tool bars you need multiple inheritance which Java does not supports.

Possibly a combination of Strategy Pattern and Factory Pattern could solve these issues. Please rethink on this and design your solution, sorry I don't have exact design or source for your question , I have just put my thoughts for your solution.

Regards, Yash

yash ahuja
  • 470
  • 1
  • 8
  • 23