控制台程序。
定义事件监听器的类必须实现监听器接口。所有的事件监听器接口都扩展了java.util.EventListener接口。这个接口没有声明任何方法,仅仅用于表示监听器对象。使用EventListener类型的变量可以保存任意事件监听器对象的引用。
要为特定的事件类型实现监听器,只需要实现对应接口中的方法即可。让应用程序类成为窗口事件的监听器,就可以处理SketcherFrame窗口的一些窗口事件。接下来必须创建Sketcher对象,作为事件的监听器。
1 // Main window for the Sketcher application 2 import javax.swing.*; 3 import static java.awt.event.InputEvent.*; // For modifier constants 4 5 @SuppressWarnings("serial") 6 public class SketcherFrame extends JFrame { 7 // Constructor 8 public SketcherFrame(String title) { 9 setTitle(title); // Set the window title 10 setDefaultCloseOperation(EXIT_ON_CLOSE); 11 12 setJMenuBar(menuBar); // Add the menu bar to the window 13 14 JMenu fileMenu = new JMenu("File"); // Create File menu 15 JMenu elementMenu = new JMenu("Elements"); // Create Elements menu 16 fileMenu.setMnemonic('F'); // Create shortcut 17 elementMenu.setMnemonic('E'); // Create shortcut 18 19 // Construct the file drop-down menu 20 newItem = fileMenu.add("New"); // Add New item 21 openItem = fileMenu.add("Open"); // Add Open item 22 closeItem = fileMenu.add("Close"); // Add Close item 23 fileMenu.addSeparator(); // Add separator 24 saveItem = fileMenu.add("Save"); // Add Save item 25 saveAsItem = fileMenu.add("Save As..."); // Add Save As item 26 fileMenu.addSeparator(); // Add separator 27 printItem = fileMenu.add("Print"); // Add Print item 28 29 // Add File menu accelerators 30 newItem.setAccelerator(KeyStroke.getKeyStroke('N',CTRL_DOWN_MASK )); 31 openItem.setAccelerator(KeyStroke.getKeyStroke('O', CTRL_DOWN_MASK)); 32 saveItem.setAccelerator(KeyStroke.getKeyStroke('S', CTRL_DOWN_MASK)); 33 printItem.setAccelerator(KeyStroke.getKeyStroke('P', CTRL_DOWN_MASK)); 34 35 // Construct the Element drop-down menu 36 elementMenu.add(lineItem = new JRadioButtonMenuItem("Line", true)); 37 elementMenu.add(rectangleItem = new JRadioButtonMenuItem("Rectangle", false)); 38 elementMenu.add(circleItem = new JRadioButtonMenuItem("Circle", false)); 39 elementMenu.add(curveItem = new JRadioButtonMenuItem("Curve", false)); 40 ButtonGroup types = new ButtonGroup(); 41 types.add(lineItem); 42 types.add(rectangleItem); 43 types.add(circleItem); 44 types.add(curveItem); 45 46 // Add element type accelerators 47 lineItem.setAccelerator(KeyStroke.getKeyStroke('L', CTRL_DOWN_MASK)); 48 rectangleItem.setAccelerator(KeyStroke.getKeyStroke('E', CTRL_DOWN_MASK)); 49 circleItem.setAccelerator(KeyStroke.getKeyStroke('I', CTRL_DOWN_MASK)); 50 curveItem.setAccelerator(KeyStroke.getKeyStroke('V', CTRL_DOWN_MASK)); 51 52 elementMenu.addSeparator(); 53 JMenu colorMenu = new JMenu("Color"); // Color submenu 54 elementMenu.add(colorMenu); // Add the submenu 55 colorMenu.add(redItem = new JCheckBoxMenuItem("Red", false)); 56 colorMenu.add(yellowItem = new JCheckBoxMenuItem("Yellow", false)); 57 colorMenu.add(greenItem = new JCheckBoxMenuItem("Green", false)); 58 colorMenu.add(blueItem = new JCheckBoxMenuItem("Blue", true)); 59 60 // Add element color accelerators 61 redItem.setAccelerator(KeyStroke.getKeyStroke('R', CTRL_DOWN_MASK)); 62 yellowItem.setAccelerator(KeyStroke.getKeyStroke('Y', CTRL_DOWN_MASK)); 63 greenItem.setAccelerator(KeyStroke.getKeyStroke('G', CTRL_DOWN_MASK)); 64 blueItem.setAccelerator(KeyStroke.getKeyStroke('B', CTRL_DOWN_MASK)); 65 66 menuBar.add(fileMenu); // Add the file menu 67 menuBar.add(elementMenu); // Add the element menu 68 } 69 70 private JMenuBar menuBar = new JMenuBar(); // Window menu bar 71 72 // File menu items 73 private JMenuItem newItem, openItem, closeItem, 74 saveItem, saveAsItem, printItem; 75 76 // Element menu items 77 private JRadioButtonMenuItem lineItem, rectangleItem, circleItem, // Types 78 curveItem, textItem; 79 private JCheckBoxMenuItem redItem, yellowItem, // Colors 80 greenItem, blueItem ; 81 }
快捷键是一种唯一的组合键,用于直接通过键盘选择菜单栏上的菜单以显示下拉菜单。setMnemoric()方法的作用是实现快捷键,并在菜单项标签中为快捷键字母加上下划线。菜单栏上每个菜单项的快捷键都必须是唯一的组合键。Windows中的典型快捷键是Alt键加菜单项标签中的大写字母。
加速键也是一种组合键,按下这种组合键,就可以直接从下拉菜单中选择菜单项,而不必先显示下拉菜单。在Windows下,Ctrl键常常和大写字母组合使用,作为菜单项的加速键。要为菜单项定义加速键,应调用封装了菜单项的对象的setAccelerator()方法。例如,对于Line菜单项,可以编写如下代码:
lineItem.setAccelerator(KeyStroke.getKeyStroke('L',InputEvent.CTRL_DOWN_MASK));
javax.swing.KeyStroke类定义了组合键。KeyStroke类中的静态方法getKeyStroke()返回对应于参数的KeyStroke对象。第一个参数是组合键中的字母,第二个参数指定一个或多个修饰键。只有大写字母才能用于表示组合键中的字母,小写字母会选择非字母键,例如数字小键盘和功能键。修饰符被指定为java.awt.event包中的InputEvent类所定义的单比特(single-bit)常量。InputEvent类定义的常量标识了键盘上的控制键和鼠标按钮。
1 // Sketching application 2 import javax.swing.*; 3 import java.awt.*; 4 import java.awt.event.*; 5 6 public class Sketcher implements WindowListener { 7 public static void main(String[] args) { 8 theApp = new Sketcher(); // Create the application object 9 SwingUtilities.invokeLater(new Runnable() { 10 public void run() { 11 theApp.createGUI(); // Call GUI creator 12 } 13 }); 14 } 15 16 // Method to create the application GUI 17 private void createGUI() { 18 window = new SketcherFrame("Sketcher"); // Create the app window 19 Toolkit theKit = window.getToolkit(); // Get the window toolkit 20 Dimension wndSize = theKit.getScreenSize(); // Get screen size 21 22 // Set the position to screen center & size to half screen size 23 window.setSize(wndSize.width/2, wndSize.height/2); // Set window size 24 window.setLocationRelativeTo(null); // Center window 25 window.addWindowListener(this); // theApp as window listener 26 window.setVisible(true); 27 } 28 29 // Handler for window closing event 30 public void windowClosing(WindowEvent e) { 31 window.dispose(); // Release the window resources 32 System.exit(0); // End the application 33 } 34 35 // Listener interface methods you must implement -but don't need 36 public void windowOpened(WindowEvent e) {} 37 public void windowClosed(WindowEvent e) {} 38 public void windowIconified(WindowEvent e) {} 39 public void windowDeiconified(WindowEvent e) {} 40 public void windowActivated(WindowEvent e) {} 41 public void windowDeactivated(WindowEvent e) {} 42 43 private SketcherFrame window; // The application window 44 private static Sketcher theApp; // The application object 45 }
建立窗口组件后,createGUI()方法就调用窗口对象的addWindowListener()方法。addWindowListener()方法的参数是对接受窗口事件的监听器对象的引用,这里是变量this,表示应用程序对象theApp。如果其他监听器对象要注册为接受这个事件,只需要添加对addWindowListener()方法的更多调用,对每个监听器调用一次即可。
在Sketcher类中实现WindowListener接口时,必须实现这个接口声明的所有7个方法。否则类就是抽象的,就不能创建Sketcher类型的对象。这里只有windowClosing()方法包含代码,其他方法的方法体都是空的,因为不需要它们。