控制台程序。
为了标识元素的类型,可以为菜单已提供的4中元素定义常量,用作ID。这有助于执行菜单项监听器的操作,还提供了一种标识颜色类型的方式。我们会累积许多应用程序范围的常量,所以把它们定义为可以静态导入的类中的静态域会比较方便。为了导入静态域,类必须在指定的包中,所以先建立包。
为了把类放在Constants包中,需要在硬盘的合适位置建立以Constants命名的目录,然后在编译Constants包中的类时,使用-classpath选项标识Constants目录的路径。
// Defines application wide constants
package Constants;
import java.awt.Color; public class SketcherConstants {
// Element type definitions
public final static int LINE = 101;
public final static int RECTANGLE = 102;
public final static int CIRCLE = 103;
public final static int CURVE = 104; // Initial conditions
public final static int DEFAULT_ELEMENT_TYPE = LINE;
public final static Color DEFAULT_ELEMENT_COLOR = Color.BLUE;
}
将上述代码保存为Constants目录下的SketcherConstants.java。类中的每个元素类型ID都是整数常量,并且值都是唯一的。
// Main window for the Sketcher application
import javax.swing.*;
import static java.awt.event.InputEvent.*; // For modifier constants
import java.awt.event.*;
import java.awt.Color;
import static java.awt.Color.*;
import static Constants.SketcherConstants.*; @SuppressWarnings("serial")
public class SketcherFrame extends JFrame {
// Constructor
public SketcherFrame(String title) {
setTitle(title); // Set the window title
setJMenuBar(menuBar); // Add the menu bar to the window
setDefaultCloseOperation(EXIT_ON_CLOSE); JMenu fileMenu = new JMenu("File"); // Create File menu
JMenu elementMenu = new JMenu("Elements"); // Create Elements menu
fileMenu.setMnemonic('F'); // Create shortcut
elementMenu.setMnemonic('E'); // Create shortcut // Construct the file drop-down menu
newItem = fileMenu.add("New"); // Add New item
openItem = fileMenu.add("Open"); // Add Open item
closeItem = fileMenu.add("Close"); // Add Close item
fileMenu.addSeparator(); // Add separator
saveItem = fileMenu.add("Save"); // Add Save item
saveAsItem = fileMenu.add("Save As..."); // Add Save As item
fileMenu.addSeparator(); // Add separator
printItem = fileMenu.add("Print"); // Add Print item // Add File menu accelerators
newItem.setAccelerator(KeyStroke.getKeyStroke('N',CTRL_DOWN_MASK ));
openItem.setAccelerator(KeyStroke.getKeyStroke('O', CTRL_DOWN_MASK));
saveItem.setAccelerator(KeyStroke.getKeyStroke('S', CTRL_DOWN_MASK));
printItem.setAccelerator(KeyStroke.getKeyStroke('P', CTRL_DOWN_MASK)); // Construct the Elements drop-down menu
elementMenu.add(lineItem = new JRadioButtonMenuItem("Line", elementType==LINE));
elementMenu.add(rectangleItem = new JRadioButtonMenuItem("Rectangle", elementType==RECTANGLE));
elementMenu.add(circleItem = new JRadioButtonMenuItem("Circle", elementType==CIRCLE));
elementMenu.add(curveItem = new JRadioButtonMenuItem("Curve", elementType==CURVE));
ButtonGroup types = new ButtonGroup();
types.add(lineItem);
types.add(rectangleItem);
types.add(circleItem);
types.add(curveItem); // Add element type accelerators
lineItem.setAccelerator(KeyStroke.getKeyStroke('L', CTRL_DOWN_MASK));
rectangleItem.setAccelerator(KeyStroke.getKeyStroke('E', CTRL_DOWN_MASK));
circleItem.setAccelerator(KeyStroke.getKeyStroke('I', CTRL_DOWN_MASK));
curveItem.setAccelerator(KeyStroke.getKeyStroke('V', CTRL_DOWN_MASK)); elementMenu.addSeparator();
JMenu colorMenu = new JMenu("Color"); // Color submenu
elementMenu.add(colorMenu); // Add the submenu
colorMenu.add(redItem = new JCheckBoxMenuItem("Red", elementColor.equals(RED)));
colorMenu.add(yellowItem = new JCheckBoxMenuItem("Yellow", elementColor.equals(YELLOW)));
colorMenu.add(greenItem = new JCheckBoxMenuItem("Green", elementColor.equals(GREEN)));
colorMenu.add(blueItem = new JCheckBoxMenuItem("Blue", elementColor.equals(BLUE)));
ButtonGroup colors = new ButtonGroup(); // Color menu items button group
colors.add(redItem);
colors.add(yellowItem);
colors.add(greenItem);
colors.add(blueItem); // Add element color accelerators
redItem.setAccelerator(KeyStroke.getKeyStroke('R', CTRL_DOWN_MASK));
yellowItem.setAccelerator(KeyStroke.getKeyStroke('Y', CTRL_DOWN_MASK));
greenItem.setAccelerator(KeyStroke.getKeyStroke('G', CTRL_DOWN_MASK));
blueItem.setAccelerator(KeyStroke.getKeyStroke('B', CTRL_DOWN_MASK)); // Add type menu item listeners
lineItem.addActionListener(new TypeListener(LINE));
rectangleItem.addActionListener(new TypeListener(RECTANGLE));
circleItem.addActionListener(new TypeListener(CIRCLE));
curveItem.addActionListener(new TypeListener(CURVE)); // Add color menu item listeners
redItem.addActionListener(new ColorListener(RED));
yellowItem.addActionListener(new ColorListener(YELLOW));
greenItem.addActionListener(new ColorListener(GREEN));
blueItem.addActionListener(new ColorListener(BLUE)); menuBar.add(fileMenu); // Add the file menu
menuBar.add(elementMenu); // Add the element menu
} // Handles element type menu items
class TypeListener implements ActionListener {
// Constructor
TypeListener(int type) {
this.type = type;
} // Sets the element type
public void actionPerformed(ActionEvent e) {
elementType = type;
} private int type; // Store the type for the menu
} // Handles color menu items
class ColorListener implements ActionListener {
public ColorListener(Color color) {
this.color = color;
} public void actionPerformed(ActionEvent e) {
elementColor = color;
} private Color color;
} private JMenuBar menuBar = new JMenuBar(); // Window menu bar // File menu items
private JMenuItem newItem, openItem, closeItem,
saveItem, saveAsItem, printItem; // Element menu items
private JRadioButtonMenuItem lineItem, rectangleItem, circleItem, // Types
curveItem, textItem;
private JCheckBoxMenuItem redItem, yellowItem, // Colors
greenItem, blueItem ;
private Color elementColor = DEFAULT_ELEMENT_COLOR; // Current element color
private int elementType = DEFAULT_ELEMENT_TYPE; // Current element type
}
Sketcher类和以前一样:
// Sketching application
import javax.swing.*;
import java.awt.*;
import java.awt.event.*; public class Sketcher {
public static void main(String[] args) {
theApp = new Sketcher(); // Create the application object
SwingUtilities.invokeLater(new Runnable() {
public void run() {
theApp.createGUI(); // Call GUI creator
}
});
} // Method to create the application GUI
private void createGUI() {
window = new SketcherFrame("Sketcher"); // Create the app window
Toolkit theKit = window.getToolkit(); // Get the window toolkit
Dimension wndSize = theKit.getScreenSize(); // Get screen size // Set the position to screen center & size to half screen size
window.setSize(wndSize.width/2, wndSize.height/2); // Set window size
window.setLocationRelativeTo(null); // Center window window.addWindowListener(new WindowHandler()); // Add window listener
window.setVisible(true);
} // Handler class for window events
class WindowHandler extends WindowAdapter {
// Handler for window closing event
@Override
public void windowClosing(WindowEvent e) {
window.dispose(); // Release the window resources
System.exit(0); // End the application
}
} private SketcherFrame window; // The application window
private static Sketcher theApp; // The application object
}
构建元素对象时,使用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目录的路径。这个命令应编译所有的代码,包括自定义的包。