Java之事件处理
监听器
ActionListener接口 ——通常用自己创建的新类implements接口
建议使用匿名内部类实现,因为内部类可以访问类内的变量,而匿名类可以大大简化代码,不需要构造函数。
实例:处理按钮点击事件
1 package button; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a button panel 9 */ 10 public class ButtonFrame extends JFrame 11 { 12 private JPanel buttonPanel; 13 private static final int DEFAULT_WIDTH = 300; 14 private static final int DEFAULT_HEIGHT = 200; 15 16 public ButtonFrame() 17 { 18 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 19 20 // create buttons 21 JButton yellowButton = new JButton("Yellow"); 22 JButton blueButton = new JButton("Blue"); 23 JButton redButton = new JButton("Red"); 24 25 buttonPanel = new JPanel(); 26 27 // add buttons to panel 28 buttonPanel.add(yellowButton); 29 buttonPanel.add(blueButton); 30 buttonPanel.add(redButton); 31 32 // add panel to frame 33 add(buttonPanel); 34 35 // create button actions 36 ColorAction yellowAction = new ColorAction(Color.YELLOW); 37 ColorAction blueAction = new ColorAction(Color.BLUE); 38 ColorAction redAction = new ColorAction(Color.RED); 39 40 // associate actions with buttons 41 yellowButton.addActionListener(yellowAction); 42 blueButton.addActionListener(blueAction); 43 redButton.addActionListener(redAction); 44 } 45 46 /** 47 * An action listener that sets the panel's background color. 48 */ 49 private class ColorAction implements ActionListener 50 { 51 private Color backgroundColor; 52 53 public ColorAction(Color c) 54 { 55 backgroundColor = c; 56 } 57 58 public void actionPerformed(ActionEvent event) 59 { 60 buttonPanel.setBackground(backgroundColor); 61 } 62 } 63 }
实例:改变观感
1 package plaf; 2 3 import java.awt.event.*; 4 import javax.swing.*; 5 6 /** 7 * A frame with a button panel for changing look and feel 8 */ 9 public class PlafFrame extends JFrame 10 { 11 private JPanel buttonPanel; 12 public PlafFrame() 13 { 14 buttonPanel = new JPanel(); 15 16 UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); 17 for (UIManager.LookAndFeelInfo info : infos) 18 makeButton(info.getName(), info.getClassName()); 19 20 add(buttonPanel); 21 pack(); 22 } 23 24 /** 25 * Makes a button to change the pluggable look and feel. 26 * @param name the button name 27 * @param plafName the name of the look and feel class 28 */ 29 void makeButton(String name, final String plafName) 30 { 31 // add button to panel 32 33 JButton button = new JButton(name); 34 buttonPanel.add(button); 35 36 // set button action 37 38 button.addActionListener(new ActionListener() 39 { 40 public void actionPerformed(ActionEvent event) 41 { 42 // button action: switch to the new look and feel 43 try 44 { 45 UIManager.setLookAndFeel(plafName); 46 SwingUtilities.updateComponentTreeUI(PlafFrame.this); 47 pack(); 48 } 49 catch (Exception e) 50 { 51 e.printStackTrace(); 52 } 53 } 54 }); 55 } 56 }
适配器
由WindowAdapter类实现的WindowListener接口中的众多方法
由于ActionListener接口只有一个方法所以不需要提供适配器类
动作
Action接口 由AbstractAction类实现 包含以下方法:
void actionPerformed(ActionEvent event); //扩展于ActionListener接口 void setEnabled(boolean b); //启用或禁用这个这个动作 boolean isEnabled(); //检查动作是否启用 void putValue(String key, Object value); //存储名/值对到动作对象中 Object getvalue(String key); //检索动作对象中的任意名/值对 void addPropertyChangeListener(PropertyChangeListener listener); void remove PropertyChangeListener(PropertyChangeListener listener);
//最后两个方法能够让其他对象在动作对象的属性发生变化时得到通告
名称 | 值 |
NAME | 动作名称,显示在按钮和菜单上 |
SMALL_ICON | 存储小图标的地方;显示在按钮、菜单项或工具栏中 |
SHORT_DESCRIPTION | 图标的简要说明;显示在工具提示中 |
LONG_DESCRIPTION | 图标的详细说明;显示在在线帮助中。没有Swing组件使用这个值 |
MNEMONIC_KEY | 快捷键缩写;显示在菜单项中 |
ACCELERATOR_KEY | 存储加速击键的地方;Swing组件不使用这个值 |
ACTION_COMMAND_KEY | 历史遗留;仅在旧版本的registerKeyboardAction方法中使用 |
DEFAULT | 常用的综合属性;Swing组件不使用这个值 |
键盘事件
KeyStroke类将击键与动作相关联
每个组件可以有三个输入映射InputMap和一个动作映射ActionMap 用get获取 put改变
标志 | 激活动作 |
WHEN_FOCUSED | 当这个组件拥有键盘焦点时 |
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT | 当这个组件包含了拥有键盘焦点的组件时 |
WHEN_IN_FOCUSED_WINDOW | 当这个组件被包含在一个拥有键盘焦点组件的窗口中时 |
动作实例:
1 package action; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a panel that demonstrates color change actions. 9 */ 10 public class ActionFrame extends JFrame 11 { 12 private JPanel buttonPanel; 13 private static final int DEFAULT_WIDTH = 300; 14 private static final int DEFAULT_HEIGHT = 200; 15 16 public ActionFrame() 17 { 18 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 19 20 buttonPanel = new JPanel(); 21 22 // define actions 23 Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"), 24 Color.YELLOW); 25 Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE); 26 Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED); 27 28 // add buttons for these actions 29 buttonPanel.add(new JButton(yellowAction)); 30 buttonPanel.add(new JButton(blueAction)); 31 buttonPanel.add(new JButton(redAction)); 32 33 // add panel to frame 34 add(buttonPanel); 35 36 // associate the Y, B, and R keys with names 37 InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 38 imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow"); 39 imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue"); 40 imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red"); 41 42 // associate the names with actions 43 ActionMap amap = buttonPanel.getActionMap(); 44 amap.put("panel.yellow", yellowAction); 45 amap.put("panel.blue", blueAction); 46 amap.put("panel.red", redAction); 47 } 48 49 public class ColorAction extends AbstractAction 50 { 51 /** 52 * Constructs a color action. 53 * @param name the name to show on the button 54 * @param icon the icon to display on the button 55 * @param c the background color 56 */ 57 public ColorAction(String name, Icon icon, Color c) 58 { 59 putValue(Action.NAME, name); 60 putValue(Action.SMALL_ICON, icon); 61 putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase()); 62 putValue("color", c); 63 } 64 65 public void actionPerformed(ActionEvent event) 66 { 67 Color c = (Color) getValue("color"); 68 buttonPanel.setBackground(c); 69 } 70 } 71 }
鼠标事件
如果只希望用户点击按钮或菜单,则不需要显式地处理鼠标事件。然而,如果希望用户使用鼠标画图,就需要捕获鼠标移动点击和拖动事件。
鼠标点击事件:
MouseHandler类 extends MouseAdapter类 implement MouseListener接口
鼠标第一次被按下时,调用mouse Pressed方法;鼠标被释放时调用mouseReleased方法;最后调用mouseClicked方法。如果只对最终的点击事件感兴趣,可以忽略前两个方法。
扩展——getModifiersEx方法能够准确地报告鼠标事件的鼠标按钮和键盘修饰符。有下列掩码
BUTTON1_DOWN_MASK
BUTTON2_DOWN_MASK
BUTTON3_DOWN_MASK
SHIFT_DOWN_MASK
CTRL_DOWN_MASK
ALT_DOWN_MASK
ALT_GRAPH_DOWN_MASK
META_DOWN_MASK
鼠标移动与拖动事件:
MouseMotionHandler类 implement MouseMotionListener接口
鼠标移动调用mouseMoved方法,鼠标拖动调用mouseDragged方法。
鼠标光标可以参考Cursor类的getPredefinedCursor方法。
1 package mouse; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.awt.geom.*; 6 import java.util.*; 7 import javax.swing.*; 8 9 /** 10 * A component with mouse operations for adding and removing squares. 11 */ 12 public class MouseComponent extends JComponent 13 { 14 private static final int DEFAULT_WIDTH = 300; 15 private static final int DEFAULT_HEIGHT = 200; 16 17 private static final int SIDELENGTH = 10; 18 private ArrayList<Rectangle2D> squares; 19 private Rectangle2D current; // the square containing the mouse cursor 20 21 public MouseComponent() 22 { 23 squares = new ArrayList<>(); 24 current = null; 25 26 addMouseListener(new MouseHandler()); 27 addMouseMotionListener(new MouseMotionHandler()); 28 } 29 30 public void paintComponent(Graphics g) 31 { 32 Graphics2D g2 = (Graphics2D) g; 33 34 // draw all squares 35 for (Rectangle2D r : squares) 36 g2.draw(r); 37 } 38 39 /** 40 * Finds the first square containing a point. 41 * @param p a point 42 * @return the first square that contains p 43 */ 44 public Rectangle2D find(Point2D p) 45 { 46 for (Rectangle2D r : squares) 47 { 48 if (r.contains(p)) return r; 49 } 50 return null; 51 } 52 53 /** 54 * Adds a square to the collection. 55 * @param p the center of the square 56 */ 57 public void add(Point2D p) 58 { 59 double x = p.getX(); 60 double y = p.getY(); 61 62 current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, 63 SIDELENGTH); 64 squares.add(current); 65 repaint(); 66 } 67 68 /** 69 * Removes a square from the collection. 70 * @param s the square to remove 71 */ 72 public void remove(Rectangle2D s) 73 { 74 if (s == null) return; 75 if (s == current) current = null; 76 squares.remove(s); 77 repaint(); 78 } 79 80 private class MouseHandler extends MouseAdapter 81 { 82 public void mousePressed(MouseEvent event) 83 { 84 // add a new square if the cursor isn't inside a square 85 current = find(event.getPoint()); 86 if (current == null) add(event.getPoint()); 87 } 88 89 public void mouseClicked(MouseEvent event) 90 { 91 // remove the current square if double clicked 92 current = find(event.getPoint()); 93 if (current != null && event.getClickCount() >= 2) remove(current); 94 } 95 } 96 97 private class MouseMotionHandler implements MouseMotionListener 98 { 99 public void mouseMoved(MouseEvent event) 100 { 101 // set the mouse cursor to cross hairs if it is inside 102 // a rectangle 103 104 if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor()); 105 else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 106 } 107 108 public void mouseDragged(MouseEvent event) 109 { 110 if (current != null) 111 { 112 int x = event.getX(); 113 int y = event.getY(); 114 115 // drag the current rectangle to center it at (x, y) 116 current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); 117 repaint(); 118 } 119 } 120 } 121 122 public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 123 }
AWT事件继承层次
事件 | 接口 | 方法 | 访问方法 | 事件源 | |
语义事件类 | ActionEvent | ActionListener | actionPerformed |
getActionCommand getModifiers |
AbstractButton JComboBox JTextField Timer |
AdjustmentEvent | AdjustmentListener | adjustmentValueChanged |
getAdjustable getAdjustmentType getValue |
JScrollbar | |
ItemEvent | ItemListener | itemStateChanged |
getIten getItemSelectable getStateChange |
AbstractButton JComboBox |
|
低级事件类 | FocusEvent | FocusListener |
focusGained focusLost |
isTemporary | Component |
KeyEvent | KeyListener |
keyPressed keyReleased keyTyped |
getKeyChar getKeyCode getKeyModifiersText getKeyText isActionKey |
Component | |
MouseEvent | MouseListener |
mousePressed mouseReleased mouseEntered mouseExited mouseClicked |
getClickCount getX getY getPoint translatePoint |
Component | |
MouseEvent | MouseMotionListener |
mouseDragged mouseMoved |
Component | ||
MouseWheelEvent | MouseWheelListener | mouseWheelMoved |
getWheelRotation getScrollAmount |
Component | |
WindowEvent | WindowListener |
windowClosing windowOpened windowIconified windowDeiconified windowClosed windowActivated windowDeactivated |
getWindow |
Window | |
WindowEvent | WindowFocusListener |
windowGainFocus windowLostFocus |
getOppositeWindow | Window | |
WindowEvent | WindowStateListener | windowStateChanged |
getOldState getNewState |
Window |