package com.han; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.net.URL; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.SwingUtilities; /** * An Action can be used to separate functionality and state from a component. * For example, if you have two or more components that perform the same * function, consider using an Action object to implement the function. An * Action object is an action listener that provides not only action-event * handling, but also centralized handling of the state of action-event-firing * components such as tool bar buttons, menu items, common buttons, and text * fields. The state that an action can handle includes text, icon, mnemonic, * enabled, and selected status. * <p> * This relies on having the Java Look and Feel Graphics Repository * (jlfgr-1_0.jar) in the class path. You can download this file from: * * <pre> * {@link http://www.oracle.com/technetwork/java/repository-140393.html} * </pre> * * Put it in the class path using one of the following commands<br> * (assuming jlfgr-1_0.jar is in a subdirectory named jars):<br> * * java -cp .;jars/jlfgr-1_0.jar ActionDemo [Microsoft Windows]<br> * java -cp .:jars/jlfgr-1_0.jar ActionDemo [UNIX]<br> * * @author HAN * */ @SuppressWarnings("serial") public class ActionDemo extends JPanel implements ItemListener { // Define some properties associated with buttons/"mainMenu". private String[] names = { "Go left", "Do something", "Go right" }; private Integer[] mnemonics = { new Integer(KeyEvent.VK_L), new Integer(KeyEvent.VK_M), new Integer(KeyEvent.VK_R) }; private String[] toolTipTexts = { "This is the left button", "This is the middle button", "This is the right button" }; // Define the names for AbleMenu items. private static String[] namesAbleMenu = { "First action enabled", "Second action enabled", "Third action enabled" }; // Define properties related to image icons. private String imageDir = "/images/jlfgr-1_0/toolbarButtonGraphics/navigation/"; private String[] icon24Names = { "Back24.gif", "Up24.gif", "Forward24.gif" }; private String[] icon24Captions = icon24Names; private String[] icon16Names = { "Back16.gif", "Up16.gif", "Forward16.gif" }; private String[] icon16Captions = icon16Names; /** * There are three actions: leftAction, middleAction, rightAction. */ private static Action[] actions = new Action[3]; ActionDemo() { super(new BorderLayout());// because by default JPanel uses FlowLayout. // Create a scrolled text area. JTextArea textArea = new JTextArea(); textArea.setEditable(false); textArea.setLineWrap(false); textArea.setWrapStyleWord(false); JScrollPane scrollPane = new JScrollPane(textArea); // Create the actions shared by the tool bar and menu. for (int i = 0; i < names.length; i++) { Icon icon24 = createImageIcon(imageDir + icon24Names[i], icon24Captions[i]); Icon icon16 = createImageIcon(imageDir + icon16Names[i], icon16Captions[i]); actions[i] = new SharedAction(names[i], icon24, icon16, toolTipTexts[i], mnemonics[i], textArea); } // Create a tool bar. JToolBar toolBar = createToolBar(); // Lay out the content pane. add(scrollPane, BorderLayout.CENTER); add(toolBar, BorderLayout.NORTH); setPreferredSize(new Dimension(450, 150)); } private JToolBar createToolBar() { // TODO Auto-generated method stub // JToolBar uses the BoxLayout by default. JToolBar toolBar = new JToolBar("Navigation tool bar"); for (int i = 0; i < actions.length; i++) { JButton button = new JButton(actions[i]); toolBar.add(button); } return toolBar; } private static JMenuBar createMenuBar() { // TODO Auto-generated method stub JMenuBar menuBar = new JMenuBar(); JMenu mainMenu = new JMenu("Menu"); JMenu ableMenu = new JMenu("Action state"); menuBar.add(mainMenu); menuBar.add(ableMenu); // Declare and allocate memory address for "cbmis". JCheckBoxMenuItem[] cbmis = new JCheckBoxMenuItem[3]; for (int i = 0; i < actions.length; i++) { // add JMenuItem to "mainMenu". mainMenu.add(new JMenuItem(actions[i])); // Initialize "cbmis" and add them to "ableMenu". cbmis[i] = new JCheckBoxMenuItem(new AbleMenuAction( namesAbleMenu[i], cbmis, actions)); ableMenu.add(cbmis[i]); } return menuBar; } /** * Return an Icon, or {@code null} if the path is invalid. * * @param path * - the image icon path * @param caption * - the image description, which would allow assistive * technologies to help visually impaired user understand what * information the icon conveys. * @return an Icon object, or <code>null</code> if the given path is not * valid. */ private Icon createImageIcon(String path, String caption) { // TODO Auto-generated method stub URL imgURL = getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL, caption); } else { System.err.println("Couldn't find file: " + path); return null; } } @Override public void itemStateChanged(ItemEvent e) { // TODO Auto-generated method stub // You can put the responses to the item selection action. However, // since we have used the Action object for the JCheckBoxMenuItem, the // items' selection state can be listened and processed in the Action. } /** * Define actions for the mainMenu and toolBar buttons. * * @author HAN * */ private class SharedAction extends AbstractAction { private JTextArea textArea; private String newline = System.getProperty("line.separator"); SharedAction(String text, Icon buttonIcon, Icon menuIcon, String toolTipText, Integer mnemonic, JTextArea textArea) { this.textArea = textArea; putValue(NAME, text); putValue(LARGE_ICON_KEY, buttonIcon); putValue(SMALL_ICON, menuIcon); putValue(SHORT_DESCRIPTION, toolTipText); putValue(MNEMONIC_KEY, mnemonic); } // Methods inherited from interface must be overridden. @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // Display some informations as we want to the text area. textArea.append("Action event detected: "); Object triggerComponent = e.getSource(); if (triggerComponent instanceof JButton) { if (((JButton) triggerComponent).getText().equals(names[0])) { textArea.append("Action for first button"); } else if (((JButton) triggerComponent).getText().equals( names[1])) { textArea.append("Action for second button"); } else if (((JButton) triggerComponent).getText().equals( names[2])) { textArea.append("Action for third button"); } } else if (triggerComponent instanceof JMenuItem) { if (((JMenuItem) triggerComponent).getText().equals(names[0])) { textArea.append("Action for first mainMenu item"); } else if (((JMenuItem) triggerComponent).getText().equals( names[1])) { textArea.append("Action for second mainMenu item"); } else if (((JMenuItem) triggerComponent).getText().equals( names[2])) { textArea.append("Action for third mainMenu item"); } } textArea.append(newline); textArea.setTabSize(4); textArea.append("\t"); textArea.append("Event source: " + e.getSource()); textArea.append(newline); } } /** * Create and show GUI. For thread safety, this method should be invoked * from the event-dispatching thread. */ private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("Action demo apps"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Set up the content pane, where the "main GUI" lives. frame.setContentPane(new ActionDemo()); // Set up the menu bar and add it to frame. JMenuBar menuBar = createMenuBar(); frame.setJMenuBar(menuBar); // Show the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event-dispatching thread: // creating and showing this application's GUI. SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // TODO Auto-generated method stub createAndShowGUI(); } }); } } /** * Define actions for the ableMenu. * * @author HAN * */ @SuppressWarnings("serial") class AbleMenuAction extends AbstractAction { private JCheckBoxMenuItem[] cbmis; private Action[] actions; AbleMenuAction(String name, JCheckBoxMenuItem[] cbmis, Action[] actions) { super(name); this.cbmis = cbmis; this.actions = actions; putValue(SELECTED_KEY, true); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) e.getSource(); boolean isSelected = cbmi.isSelected(); if (cbmi == cbmis[0]) { actions[0].setEnabled(isSelected); } else if (cbmi == cbmis[1]) { actions[1].setEnabled(isSelected); } else if (cbmi == cbmis[2]) { actions[2].setEnabled(isSelected); } } }