Best Practice using reusable Actions on GUI Components
I tried differend things on how to make Actions resuable in my Swing applications. I am not a friend on heavy-weight, 1000+ line classes (with lots of inner/anon classes) and try to split my code up into multiple classes. Thus make them resuseable and exchangeable easily.
For reusing same Actions in an application I made for every Action its own 开发者_Go百科class to use it in JMenuBar and JToolBar. Please have a look at the minimal example below.
Is this a good choosen practice (esp. using static inner classes)?
public class SomeGUI extends JFrame {
public static void main(String[] args)
{
new SomeGUI();
}
public SomeGUI()
{
setJMenuBar(new MyMenuBar());
add(new MyToolBar());
setSize(400, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class MyMenuBar extends JMenuBar {
JMenu menu = new JMenu("File");
public MyMenuBar()
{
add(menu);
menu.add(new JMenuItem(new Actions.NewAction("New", null, "New File", KeyEvent.VK_N)));
}
}
class MyToolBar extends JToolBar {
public MyToolBar()
{
add(new Actions.NewAction("New", null, "New File", KeyEvent.VK_N));
}
}
class Actions {
static class NewAction extends AbstractAction {
public NewAction(String name, ImageIcon icon, String desc, Integer mnemonic)
{
super(name, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent paramActionEvent)
{
System.out.println("do the new action...");
}
}
}
Looking forward for your advises. Thanks in advance.
Is this a good choosen practice (esp. using static inner classes)?
This is the way much of the base Swing code is implemented.
For example take a look at the source code of DefaultEditorKit where all the Actions are defined.
One suggestion would be not to use an aggregate class which holds all actions. Just use a separate file for each class and make it public.
This way for using the class in another project you would just need to copy the file assuming it has no specific dependencies in current project.
What I often do (and it's even easier when using GutsAction
from guts-gui project) is that I group related actions in one class.
I store each action as a final public
field (but if you hate public
fields you can still make them private
and dfine a getter method on each).
Each action is defined as a tiny anonymous class where the final field is declared.
The criteria for grouping are essentially functional but they can also include some context, e.g. you can have a class that include various actions that perform on the currently selected order (from an order JTable
), thus I can put the context (current selected order) in only one class, and I can also put there the necessary methods to enable/disable all actions when selection changes.
Having grouped actions in one class helps avoid proliferation of action classes all over the place and having to manage instantiation of each individual action. It also enables easier Dependency Injection of dependencies common to several actions.
精彩评论