Java Tutorial/Swing Event/Action
Содержание
- 1 AbstractAction Lookup Property Keys
- 2 ActionMap javax.swing.JComponent.getActionMap()
- 3 Action Usage Example
- 4 Creating an Action
- 5 Disable an Action
- 6 Enabling an Action
- 7 extends AbstractAction
- 8 Get and set Action Command
- 9 Listing the Actions in a Component
- 10 Map actions with keystrokes
- 11 Register action
AbstractAction Lookup Property Keys
One complexity-busting side effect when using AbstractAction is that it lets you disable the Action with setEnabled(false), which, in turn, will disable all components created from it.
ConstantDescriptionNAMEAction name, used as button labelSMALL_ICONIcon for the Action, used as button labelSHORT_DESCRIPTIONShort description of the Action; could be used as tooltip text, but not by defaultLONG_DESCRIPTIONLong description of the Action; could be used for accessibility (see Chapter 22)ACCELERATORKeyStroke string; can be used as the accelerator for the ActionACTION_COMMAND_KEYInputMap key; maps to the Action in the ActionMap of the associated JComponentMNEMONIC_KEYKey code; can be used as mnemonic for actionDEFAULTUnused constant that could be used for your own property
ActionMap javax.swing.JComponent.getActionMap()
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
public class Main {
public static void main(String[] argv) throws Exception {
JButton component = new JButton();
MyAction action = new MyAction();
component.getActionMap().put(action.getValue(Action.NAME), action);
}
}
class MyAction extends AbstractAction {
public MyAction() {
super("my action");
}
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
}
Action Usage Example
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JToolBar;
class PrintHelloAction extends AbstractAction {
private static final Icon printIcon = new ImageIcon("Print.gif");
PrintHelloAction() {
super("Print", printIcon);
putValue(Action.SHORT_DESCRIPTION, "Hello, World");
}
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("Hello, World");
}
}
public class ActionTester {
public static void main(String args[]) {
JFrame frame = new JFrame("Action Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Action printAction = new PrintHelloAction();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
menu.add(new JMenuItem(printAction));
JToolBar toolbar = new JToolBar();
toolbar.add(new JButton(printAction));
JButton enableButton = new JButton("Enable");
ActionListener enableActionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
printAction.setEnabled(true);
}
};
enableButton.addActionListener(enableActionListener);
JButton disableButton = new JButton("Disable");
ActionListener disableActionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
printAction.setEnabled(false);
}
};
disableButton.addActionListener(disableActionListener);
JButton relabelButton = new JButton("Relabel");
ActionListener relabelActionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
printAction.putValue(Action.NAME, "Changed Action Value");
}
};
relabelButton.addActionListener(relabelActionListener);
JPanel buttonPanel = new JPanel();
buttonPanel.add(enableButton);
buttonPanel.add(disableButton);
buttonPanel.add(relabelButton);
frame.setJMenuBar(menuBar);
frame.add(toolbar, BorderLayout.SOUTH);
frame.add(buttonPanel, BorderLayout.NORTH);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Creating an Action
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.KeyStroke;
public class Main {
public static void main(String[] argv) throws Exception {
final Action action = new AbstractAction("Action Name") {
{
putValue(Action.SHORT_DESCRIPTION, "Tool Tip Text");
putValue(Action.LONG_DESCRIPTION, "Help Text");
Icon icon = new ImageIcon("icon.gif");
putValue(Action.SMALL_ICON, icon);
putValue(Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_A));
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control F2"));
}
public void actionPerformed(ActionEvent evt) {
System.out.println("action");
}
};
JButton button = new JButton(action);
}
}
Disable an Action
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
public class ActionDisabled extends JFrame {
public static final String ENABLE = "ENABLE";
public static final String DISABLE = "DISABLE";
private JToolBar toolBar = new JToolBar();
private JMenuBar menuBar = new JMenuBar();
private JMenu testMenu = new JMenu("Test");
private MyAction theAction = new MyAction(this);
private JMenuItem disableActionItem= new JMenuItem("Disable the Action");
public ActionDisabled() {
this.setJMenuBar(menuBar);
menuBar.add(testMenu);
testMenu.add(theAction);
toolBar.add(theAction);
disableActionItem.setActionCommand(DISABLE);
testMenu.add(disableActionItem);
disableActionItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals(DISABLE)) {
theAction.setEnabled(false);
disableActionItem.setText("Enable the Action");
disableActionItem.setActionCommand(ENABLE);
} else {
theAction.setEnabled(true);
disableActionItem.setText("Disable the Action");
disableActionItem.setActionCommand(DISABLE);
}
}
});
this.getContentPane().add(toolBar, BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setBackground(Color.red);
this.setSize(320, 200);
this.setVisible(true);
}
public static void main(String[] args) {
ActionDisabled t = new ActionDisabled();
}
}
class MyAction extends AbstractAction {
JFrame f;
boolean toggle = true;
public MyAction(JFrame f) {
super("Change Color");
this.f = f;
}
public void actionPerformed(ActionEvent e) {
if (toggle) {
f.getContentPane().setBackground(Color.blue);
toggle = false;
} else {
f.getContentPane().setBackground(Color.red);
toggle = true;
}
f.repaint();
}
}
Enabling an Action
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Main {
public static void main(String[] argv) throws Exception {
final Action action = new AbstractAction("Action Name") {
public void actionPerformed(ActionEvent evt) {
System.out.println("action");
}
};
JFrame frame = new JFrame();
JButton button = new JButton(action);
JTextField textfield = new JTextField();
textfield.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("F2"),
action.getValue(Action.NAME));
textfield.getActionMap().put(action.getValue(Action.NAME), action);
}
}
extends AbstractAction
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.UndoManager;
public class UndoEditor extends JFrame {
private UndoManager undoManager = new UndoManager();
private JMenuBar menuBar = new JMenuBar();
private JMenu editMenu = new JMenu("Edit");
private UndoAction undoAction = new UndoAction();
private RedoAction redoAction = new RedoAction();
public UndoEditor() {
setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextPane editor = new JTextPane();
editor.getDocument().addUndoableEditListener(new UndoListener());
menuBar.add(editMenu);
editMenu.add(undoAction);
editMenu.add(redoAction);
this.setJMenuBar(menuBar);
add(new JScrollPane(editor));
setSize(400, 300);
setVisible(true);
}
public static void main(String[] args) {
UndoEditor e = new UndoEditor();
}
class UndoListener implements UndoableEditListener {
public void undoableEditHappened(UndoableEditEvent e) {
undoManager.addEdit(e.getEdit());
undoAction.update();
redoAction.update();
}
}
class UndoAction extends AbstractAction {
public UndoAction() {
this.putValue(Action.NAME, undoManager.getUndoPresentationName());
this.setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
if (this.isEnabled()) {
undoManager.undo();
undoAction.update();
redoAction.update();
}
}
public void update() {
this.putValue(Action.NAME, undoManager.getUndoPresentationName());
this.setEnabled(undoManager.canUndo());
}
}
class RedoAction extends AbstractAction {
public RedoAction() {
this.putValue(Action.NAME, undoManager.getRedoPresentationName());
this.setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
if (this.isEnabled()) {
undoManager.redo();
undoAction.update();
redoAction.update();
}
}
public void update() {
this.putValue(Action.NAME, undoManager.getRedoPresentationName());
this.setEnabled(undoManager.canRedo());
}
}
}
Get and set Action Command
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/*
* ButtonDemo.java requires the following files: images/right.gif
* images/middle.gif images/left.gif
*/
public class ButtonDemo extends JPanel implements ActionListener {
protected JButton b1, b2, b3;
public ButtonDemo() {
ImageIcon leftButtonIcon = createImageIcon("images/right.gif");
ImageIcon middleButtonIcon = createImageIcon("images/middle.gif");
ImageIcon rightButtonIcon = createImageIcon("images/left.gif");
b1 = new JButton("Disable middle button", leftButtonIcon);
b1.setVerticalTextPosition(AbstractButton.CENTER);
b1.setHorizontalTextPosition(AbstractButton.LEADING); // aka LEFT, for
// left-to-right
// locales
b1.setMnemonic(KeyEvent.VK_D);
b1.setActionCommand("disable");
b2 = new JButton("Middle button", middleButtonIcon);
b2.setVerticalTextPosition(AbstractButton.BOTTOM);
b2.setHorizontalTextPosition(AbstractButton.CENTER);
b2.setMnemonic(KeyEvent.VK_M);
b3 = new JButton("Enable middle button", rightButtonIcon);
// Use the default text position of CENTER, TRAILING (RIGHT).
b3.setMnemonic(KeyEvent.VK_E);
b3.setActionCommand("enable");
b3.setEnabled(false);
// Listen for actions on buttons 1 and 3.
b1.addActionListener(this);
b3.addActionListener(this);
b1.setToolTipText("Click this button to disable the middle button.");
b2.setToolTipText("This middle button does nothing when you click it.");
b3.setToolTipText("Click this button to enable the middle button.");
// Add Components to this container, using the default FlowLayout.
add(b1);
add(b2);
add(b3);
}
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
} else {
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = ButtonDemo.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn"t find file: " + path);
return null;
}
}
/**
* Create the GUI and show it. 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("ButtonDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
ButtonDemo newContentPane = new ButtonDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display 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.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Listing the Actions in a Component
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JButton;
public class Main {
public static void main(String[] argv) throws Exception {
JButton component = new JButton("button");
ActionMap map = component.getActionMap();
list(map, map.keys());
list(map, map.allKeys());
}
static void list(ActionMap map, Object[] actionKeys) {
if (actionKeys == null) {
return;
}
for (int i = 0; i < actionKeys.length; i++) {
// Get the action bound to this action key
while (map.get(actionKeys[i]) == null) {
map = map.getParent();
}
Action action = (Action) map.get(actionKeys[i]);
}
}
}
Map actions with keystrokes
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Hashtable;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.TextAction;
import javax.swing.text.Utilities;
public class Main {
public static void main(String[] args) {
JTextArea area = new JTextArea(6, 32);
Keymap parent = area.getKeymap();
Keymap newmap = JTextComponent.addKeymap("KeymapExampleMap", parent);
KeyStroke u = KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK);
Action actionU = new UppercaseAction();
newmap.addActionForKeyStroke(u, actionU);
Action actionList[] = area.getActions();
Hashtable lookup = new Hashtable();
for (int j = 0; j < actionList.length; j += 1)
lookup.put(actionList[j].getValue(Action.NAME), actionList[j]);
KeyStroke L = KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_MASK);
Action actionL = (Action) lookup.get(DefaultEditorKit.selectLineAction);
newmap.addActionForKeyStroke(L, actionL);
area.setKeymap(newmap);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JScrollPane(area), BorderLayout.CENTER);
area.setText("this is a test");
f.setSize(300,300);
f.setVisible(true);
}
}
class UppercaseAction extends TextAction {
public UppercaseAction() {
super("uppercase-word-action");
}
public void actionPerformed(ActionEvent e) {
JTextComponent comp = getTextComponent(e);
if (comp == null)
return;
Document doc = comp.getDocument();
int start = comp.getSelectionStart();
int end = comp.getSelectionEnd();
try {
int left = Utilities.getWordStart(comp, start);
int right = Utilities.getWordEnd(comp, end);
String word = doc.getText(left, right - left);
doc.remove(left, right - left);
doc.insertString(left, word.toUpperCase(), null);
comp.setSelectionStart(start);
comp.setSelectionEnd(end);
} catch (Exception ble) {
return;
}
}
}
Register action
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
public class Main {
public static void main(String[] argv) throws Exception {
JButton component = new JButton();
MyAction action = new MyAction();
component.getActionMap().put(action.getValue(Action.NAME), action);
}
}
class MyAction extends AbstractAction {
public MyAction() {
super("my action");
}
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
}