控制台程序。
为了标识元素的类型,可以为菜单已提供的4中元素定义常量,用作ID。这有助于执行菜单项监听器的操作,还提供了一种标识颜色类型的方式。我们会累积许多应用程序范围的常量,所以把它们定义为可以静态导入的类中的静态域会比较方便。为了导入静态域,类必须在指定的包中,所以先建立包。
为了把类放在Constants包中,需要在硬盘的合适位置建立以Constants命名的目录,然后在编译Constants包中的类时,使用-classpath选项标识Constants目录的路径。
1 // Defines application wide constants 2 package Constants; 3 import java.awt.Color; 4 5 public class SketcherConstants { 6 // Element type definitions 7 public final static int LINE = 101; 8 public final static int RECTANGLE = 102; 9 public final static int CIRCLE = 103; 10 public final static int CURVE = 104; 11 12 // Initial conditions 13 public final static int DEFAULT_ELEMENT_TYPE = LINE; 14 public final static Color DEFAULT_ELEMENT_COLOR = Color.BLUE; 15 }
将上述代码保存为Constants目录下的SketcherConstants.java。类中的每个元素类型ID都是整数常量,并且值都是唯一的。
1 // Main window for the Sketcher application 2 import javax.swing.*; 3 import static java.awt.event.InputEvent.*; // For modifier constants 4 import java.awt.event.*; 5 import java.awt.Color; 6 import static java.awt.Color.*; 7 import static Constants.SketcherConstants.*; 8 9 @SuppressWarnings("serial") 10 public class SketcherFrame extends JFrame { 11 // Constructor 12 public SketcherFrame(String title) { 13 setTitle(title); // Set the window title 14 setJMenuBar(menuBar); // Add the menu bar to the window 15 setDefaultCloseOperation(EXIT_ON_CLOSE); 16 17 18 JMenu fileMenu = new JMenu("File"); // Create File menu 19 JMenu elementMenu = new JMenu("Elements"); // Create Elements menu 20 fileMenu.setMnemonic('F'); // Create shortcut 21 elementMenu.setMnemonic('E'); // Create shortcut 22 23 // Construct the file drop-down menu 24 newItem = fileMenu.add("New"); // Add New item 25 openItem = fileMenu.add("Open"); // Add Open item 26 closeItem = fileMenu.add("Close"); // Add Close item 27 fileMenu.addSeparator(); // Add separator 28 saveItem = fileMenu.add("Save"); // Add Save item 29 saveAsItem = fileMenu.add("Save As..."); // Add Save As item 30 fileMenu.addSeparator(); // Add separator 31 printItem = fileMenu.add("Print"); // Add Print item 32 33 // Add File menu accelerators 34 newItem.setAccelerator(KeyStroke.getKeyStroke('N',CTRL_DOWN_MASK )); 35 openItem.setAccelerator(KeyStroke.getKeyStroke('O', CTRL_DOWN_MASK)); 36 saveItem.setAccelerator(KeyStroke.getKeyStroke('S', CTRL_DOWN_MASK)); 37 printItem.setAccelerator(KeyStroke.getKeyStroke('P', CTRL_DOWN_MASK)); 38 39 // Construct the Elements drop-down menu 40 elementMenu.add(lineItem = new JRadioButtonMenuItem("Line", elementType==LINE)); 41 elementMenu.add(rectangleItem = new JRadioButtonMenuItem("Rectangle", elementType==RECTANGLE)); 42 elementMenu.add(circleItem = new JRadioButtonMenuItem("Circle", elementType==CIRCLE)); 43 elementMenu.add(curveItem = new JRadioButtonMenuItem("Curve", elementType==CURVE)); 44 ButtonGroup types = new ButtonGroup(); 45 types.add(lineItem); 46 types.add(rectangleItem); 47 types.add(circleItem); 48 types.add(curveItem); 49 50 // Add element type accelerators 51 lineItem.setAccelerator(KeyStroke.getKeyStroke('L', CTRL_DOWN_MASK)); 52 rectangleItem.setAccelerator(KeyStroke.getKeyStroke('E', CTRL_DOWN_MASK)); 53 circleItem.setAccelerator(KeyStroke.getKeyStroke('I', CTRL_DOWN_MASK)); 54 curveItem.setAccelerator(KeyStroke.getKeyStroke('V', CTRL_DOWN_MASK)); 55 56 elementMenu.addSeparator(); 57 JMenu colorMenu = new JMenu("Color"); // Color submenu 58 elementMenu.add(colorMenu); // Add the submenu 59 colorMenu.add(redItem = new JCheckBoxMenuItem("Red", elementColor.equals(RED))); 60 colorMenu.add(yellowItem = new JCheckBoxMenuItem("Yellow", elementColor.equals(YELLOW))); 61 colorMenu.add(greenItem = new JCheckBoxMenuItem("Green", elementColor.equals(GREEN))); 62 colorMenu.add(blueItem = new JCheckBoxMenuItem("Blue", elementColor.equals(BLUE))); 63 ButtonGroup colors = new ButtonGroup(); // Color menu items button group 64 colors.add(redItem); 65 colors.add(yellowItem); 66 colors.add(greenItem); 67 colors.add(blueItem); 68 69 // Add element color accelerators 70 redItem.setAccelerator(KeyStroke.getKeyStroke('R', CTRL_DOWN_MASK)); 71 yellowItem.setAccelerator(KeyStroke.getKeyStroke('Y', CTRL_DOWN_MASK)); 72 greenItem.setAccelerator(KeyStroke.getKeyStroke('G', CTRL_DOWN_MASK)); 73 blueItem.setAccelerator(KeyStroke.getKeyStroke('B', CTRL_DOWN_MASK)); 74 75 // Add type menu item listeners 76 lineItem.addActionListener(new TypeListener(LINE)); 77 rectangleItem.addActionListener(new TypeListener(RECTANGLE)); 78 circleItem.addActionListener(new TypeListener(CIRCLE)); 79 curveItem.addActionListener(new TypeListener(CURVE)); 80 81 // Add color menu item listeners 82 redItem.addActionListener(new ColorListener(RED)); 83 yellowItem.addActionListener(new ColorListener(YELLOW)); 84 greenItem.addActionListener(new ColorListener(GREEN)); 85 blueItem.addActionListener(new ColorListener(BLUE)); 86 87 menuBar.add(fileMenu); // Add the file menu 88 menuBar.add(elementMenu); // Add the element menu 89 } 90 91 // Handles element type menu items 92 class TypeListener implements ActionListener { 93 // Constructor 94 TypeListener(int type) { 95 this.type = type; 96 } 97 98 // Sets the element type 99 public void actionPerformed(ActionEvent e) { 100 elementType = type; 101 } 102 103 private int type; // Store the type for the menu 104 } 105 106 // Handles color menu items 107 class ColorListener implements ActionListener { 108 public ColorListener(Color color) { 109 this.color = color; 110 } 111 112 public void actionPerformed(ActionEvent e) { 113 elementColor = color; 114 } 115 116 private Color color; 117 } 118 119 private JMenuBar menuBar = new JMenuBar(); // Window menu bar 120 121 // File menu items 122 private JMenuItem newItem, openItem, closeItem, 123 saveItem, saveAsItem, printItem; 124 125 // Element menu items 126 private JRadioButtonMenuItem lineItem, rectangleItem, circleItem, // Types 127 curveItem, textItem; 128 private JCheckBoxMenuItem redItem, yellowItem, // Colors 129 greenItem, blueItem ; 130 private Color elementColor = DEFAULT_ELEMENT_COLOR; // Current element color 131 private int elementType = DEFAULT_ELEMENT_TYPE; // Current element type 132 }
Sketcher类和以前一样:
1 // Sketching application 2 import javax.swing.*; 3 import java.awt.*; 4 import java.awt.event.*; 5 6 public class Sketcher { 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 26 window.addWindowListener(new WindowHandler()); // Add window listener 27 window.setVisible(true); 28 } 29 30 // Handler class for window events 31 class WindowHandler extends WindowAdapter { 32 // Handler for window closing event 33 @Override 34 public void windowClosing(WindowEvent e) { 35 window.dispose(); // Release the window resources 36 System.exit(0); // End the application 37 } 38 } 39 40 private SketcherFrame window; // The application window 41 private static Sketcher theApp; // The application object 42 }
构建元素对象时,使用elementType和elementColor成员来设置每个菜单项的状态。只选中了对应于elementType中设置的默认类型的元素类型菜单项,因为只有这个比较生成了true,作为JRadioButtonMenuItem构造函数的参数。
因为现在有自己的包来包含SketcherConstants类定义,所以必须使用-classpath选项,告诉编译器在哪里能找到这个类。假定Constants目录是C:/Packages目录的子目录,当前目录中包含Sketcher.java和SketcherFrame.java文件,可以使用下列命令编译Sketcher:
javac -classpath ".;c:/Packages" Sketcher.java
-classpath选项定义了两条路径:当前路径,由句点指定;C:/Packages,这是包含源文件Sketcher.java的Constants目录的路径。这个命令应编译所有的代码,包括自定义的包。