Often menus and tool bars contain some common actions. For example, you can save a file by choosing File , Save , or by clicking the save button in the tool bar. Swing provides the Action interface, which can be used to create action objects for processing actions. Using Action objects, common action processing can be centralized and separated from the other application code.
The Action interface is a subinterface of ActionListener , as shown in Figure 29.8. Additionally, it defines several methods for checking whether the action is enabled, for enabling and disabling the action, and for retrieving and setting the associated action value using a key. The key can be any string, but four keys have predefined meanings:
Key | Description |
---|---|
Action. NAME | A name for the action |
Action.SMALL_ICON | A small icon for the action |
Action.SHORT_DESCRIPTION | A tool tip for the action |
Action.LONG_DESCRIPTION | A description for online help |
AbstractAction is a default implementation of the Action interface, as shown in Figure 29.8. It implements all the methods in the Action interface except the actionPerformed method. Additionally, it defines the getKeys() method.
Since AbstractAction is an abstract class, you cannot create an instance using its constructor. However, you can create a concrete subclass of AbstractAction and implement the actionPerformed method. This subclass can be conveniently defined as an anonymous inner class. For example, the following code creates an Action object for terminating a program:
Action exitAction = new AbstractAction( "Exit" ) { public void actionPerformed(ActionEvent e) { System.exit( ); } };
Certain containers, such as JMenu and JToolBar , know how to add an Action object. When an Action object is added to such a container, the container automatically creates an appropriate component for the Action object and registers a listener with the Action object. Here is an example of adding an Action object to a menu and a tool bar:
jMenu.add(exitAction); jToolBar.add(exitAction);
Several Swing components , such as JButton , JRadioButton , and JCheckBox , contain constructors to create instances from Action objects. For example, you can create a JButton from an Action object, as follows :
JButton jbt = new JButton(exitAction);
Action objects can also be associated with mnemonic and accelerator keys. To associate actions with a mnemonic key (e.g., ALT+E), use the following statement:
exitAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_E));
To associate actions with an accelerator key (e.g., CTRL+E), use the following statement:
KeyStroke exitKey = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK); exitAction.putValue(Action.ACCELERATOR_KEY, exitKey);
Listing 29.4 gives an example that creates three menu items, Left, Center, and Right, three tool bar buttons, Left, Center, and Right, and three regular buttons, Left, Center, and Right, in a panel, as shown in Figure 29.9. The panel that holds the buttons uses the FlowLayout . The actions of the left, center, and right buttons set the alignment of the FlowLayout to left, right, and center, respectively. The actions of the menu items, the tool bar buttons, and the buttons in the panel can be processed through common action handlers using the Action interface.
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class ActionInterfaceDemo extends JApplet { 6 private JPanel buttonPanel = new JPanel(); 7 private FlowLayout flowLayout = new FlowLayout(); 8 9 public ActionInterfaceDemo() { 10 // Create image icons 11 ImageIcon leftImageIcon = new ImageIcon(getClass().getResource( 12 "image/leftAlignment.png" )); 13 ImageIcon centerImageIcon = new ImageIcon(getClass().getResource( 14 "image/centerAlignment.png" )); 15 ImageIcon rightImageIcon = new ImageIcon(getClass().getResource( 16 "image/rightAlignment.png" )); 17 18 // Create actions 19 Action leftAction = new MyAction( "Left" , leftImageIcon, 20 "Left alignment for the buttons in the panel" , 21 new Integer(KeyEvent.VK_L), 22 KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK)); 23 Action centerAction = new MyAction( "Center" , centerImageIcon, 24 "Center alignment for the buttons in the panel" , 25 new Integer(KeyEvent.VK_C), 26 KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK)); 27 Action rightAction = new MyAction( "Right" , rightImageIcon, 28 "Right alignment for the buttons in the panel" , 29 new Integer(KeyEvent.VK_R), 30 KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK)); 31 32 // Create menus 33 JMenuBar jMenuBar1 = new JMenuBar(); 34 JMenu jmenuAlignment = new JMenu( "Alignment" ); 35 setJMenuBar(jMenuBar1); 36 jMenuBar1.add(jmenuAlignment); 37 38 // Add actions to the menu 39 jmenuAlignment.add(leftAction); 40 jmenuAlignment.add(centerAction); 41 jmenuAlignment.add(rightAction); 42 43 // Add actions to the toolbar 44 JToolBar jToolBar1 = new JToolBar(JToolBar.VERTICAL); 45 jToolBar1.setBorder(BorderFactory.createLineBorder(Color.red)); 46 jToolBar1.add(leftAction); 47 jToolBar1.add(centerAction); 48 jToolBar1.add(rightAction); 49 50 // Add buttons to the button panel 51 buttonPanel.setLayout(flowLayout); 52 JButton jbtLeft = new JButton(leftAction); 53 JButton jbtCenter = new JButton(centerAction); 54 JButton jbtRight = new JButton(rightAction); 55 buttonPanel.add(jbtLeft); 56 buttonPanel.add(jbtCenter); 57 buttonPanel.add(jbtRight); 58 59 // Add tool bar to the east and panel to the center 60 add(jToolBar1, BorderLayout.EAST); 61 add(buttonPanel, BorderLayout.CENTER); 62 } 63 64 private class MyAction extends AbstractAction { 65 String name; 66 67 MyAction(String name, Icon icon) { 68 super (name, icon); 69 this .name = name; 70 } 71 72 MyAction(String name, Icon icon, String desc, Integer mnemonic, 73 KeyStroke accelerator) { 74 super (name, icon); 75 putValue(Action.SHORT_DESCRIPTION, desc); 76 putValue(Action.MNEMONIC_KEY, mnemonic); 77 putValue(Action.ACCELERATOR_KEY, accelerator); 78 this .name = name; 79 } 80 81 public void actionPerformed(ActionEvent e) { 82 if (name.equals( "Left" )) 83 flowLayout.setAlignment(FlowLayout.LEFT); 84 else if (name.equals( "Center" )) 85 flowLayout.setAlignment(FlowLayout.CENTER); 86 else if (name.equals( "Right" )) 87 flowLayout.setAlignment(FlowLayout.RIGHT); 88 89 buttonPanel.revalidate(); 90 } 91 } 92 } |
The inner class MyAction extends AbstractAction with a constructor to construct an action with a name and an icon (lines 67 “70) and another constructor to construct an action with a name, icon, description, mnemonic, and accelerator (lines 72 “79). The constructors invoke the putValue method to associate the name, icon, description, mnemonic, and accelerator. It implements the actionPerformed method to set a new alignment in the panel of the FlowLayout (lines 81 “90). The revalidate() method validates the new alignment (line 89).
Three actions, leftAction , centerAction , and rightAction , were created from the MyAction class (lines 19 “30). Each action has a name, icon, decription, mnemonic, and accelerator. The actions are for the menu items and the buttons in the tool bar and in the panel. The menu and toolbar know how to add these objects automatically (lines 39 “41, 46 “48). Three regular buttons are created with the properties taken from the actions (lines 51 “54).