Java AWT 控件、布局管理器和菜单的使用
1. GridBagLayout 布局管理器
GridBagLayout 是一个强大的布局管理器。在特定布局中,操作系统复选框以 2×2 网格定位,每个单元格水平填充为 200,每个组件从左上角稍有嵌入(4 个单位)。列权重设为 1,会使额外的水平空间在各列间均匀分布;第一行默认权重为 0,第二行权重为 1,这意味着额外的垂直空间会添加到第二行。使用 GridBagLayout 时,值得花时间进行实验和探索,理解各种设置的作用后,就能高精度地定位组件。
2. 菜单和菜单栏
2.1 菜单相关类
顶级窗口可关联菜单栏,菜单栏显示顶级菜单选项列表,每个选项关联一个下拉菜单。在 AWT 中,通过
MenuBar
、
Menu
和
MenuItem
类实现。一般来说,菜单栏包含一个或多个
Menu
对象,每个
Menu
对象包含一个
MenuItem
对象列表,每个
MenuItem
对象代表用户可选择的项。由于
Menu
是
MenuItem
的子类,可创建嵌套子菜单层次结构,也可包含可勾选菜单项,即
CheckboxMenuItem
类型,选中时旁边会有复选标记。
2.2 创建菜单的步骤
-
创建菜单栏
:实例化
MenuBar类,该类只有默认构造函数。 -
创建菜单
:使用
Menu类的构造函数创建菜单,构造函数如下:-
Menu( ) throws HeadlessException:创建一个空菜单。 -
Menu(String optionName) throws HeadlessException:创建一个指定名称的菜单。 -
Menu(String optionName, boolean removable) throws HeadlessException:创建一个指定名称的菜单,若removable为true,菜单可移除并浮动,否则将附着在菜单栏上。
-
-
创建菜单项
:使用
MenuItem类的构造函数创建菜单项,构造函数如下:-
MenuItem( ) throws HeadlessException -
MenuItem(String itemName) throws HeadlessException -
MenuItem(String itemName, MenuShortcut keyAccel) throws HeadlessException:itemName是菜单项显示的名称,keyAccel是该菜单项的快捷键。
-
-
添加菜单项到菜单
:使用
add( )方法将菜单项添加到Menu对象中,方法形式为MenuItem add(MenuItem item)。 -
添加菜单到菜单栏
:使用
MenuBar类的add( )方法将Menu对象添加到菜单栏,方法形式为Menu add(Menu menu)。
2.3 菜单项的操作方法
| 方法 | 描述 |
|---|---|
void setEnabled(boolean enabledFlag)
|
启用或禁用菜单项,
enabledFlag
为
true
启用,
false
禁用。
|
boolean isEnabled( )
|
判断菜单项是否启用,启用返回
true
,否则返回
false
。
|
void setLabel(String newName)
|
更改菜单项的名称,
newName
为新名称。
|
String getLabel( )
| 获取菜单项的当前名称。 |
2.4 可勾选菜单项
使用
CheckboxMenuItem
类创建可勾选菜单项,构造函数如下:
-
CheckboxMenuItem( ) throws HeadlessException
-
CheckboxMenuItem(String itemName) throws HeadlessException
-
CheckboxMenuItem(String itemName, boolean on) throws HeadlessException
:前两种形式的可勾选条目初始未选中,第三种形式若
on
为
true
,初始选中,否则未选中。
可使用
getState( )
方法获取可勾选菜单项的状态,使用
setState(boolean checked)
方法设置其状态,
checked
为
true
选中,
false
清除。
2.5 菜单事件处理
菜单仅在
MenuItem
或
CheckboxMenuItem
类型的项被选中时生成事件。每次选中菜单项时,会生成
ActionEvent
对象,默认操作命令字符串是菜单项的名称,可通过
setActionCommand( )
方法指定不同的操作命令字符串。每次勾选或取消勾选复选框菜单项时,会生成
ItemEvent
对象。因此,需实现
ActionListener
和/或
ItemListener
接口来处理这些菜单事件。
ItemEvent
的
getItem( )
方法可返回生成该事件的项的引用,方法形式为
Object getItem( )
。
以下是一个添加嵌套菜单到弹出窗口的示例代码:
// Illustrate menus.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code="MenuDemo" width=250 height=250>
</applet>
*/
// Create a subclass of Frame.
class MenuFrame extends Frame {
String msg = "";
CheckboxMenuItem debug, test;
MenuFrame(String title) {
super(title);
// create menu bar and add it to frame
MenuBar mbar = new MenuBar();
setMenuBar(mbar);
// create the menu items
Menu file = new Menu("File");
MenuItem item1, item2, item3, item4, item5;
file.add(item1 = new MenuItem("New..."));
file.add(item2 = new MenuItem("Open..."));
file.add(item3 = new MenuItem("Close"));
file.add(item4 = new MenuItem("-"));
file.add(item5 = new MenuItem("Quit..."));
mbar.add(file);
Menu edit = new Menu("Edit");
MenuItem item6, item7, item8, item9;
edit.add(item6 = new MenuItem("Cut"));
edit.add(item7 = new MenuItem("Copy"));
edit.add(item8 = new MenuItem("Paste"));
edit.add(item9 = new MenuItem("-"));
Menu sub = new Menu("Special");
MenuItem item10, item11, item12;
sub.add(item10 = new MenuItem("First"));
sub.add(item11 = new MenuItem("Second"));
sub.add(item12 = new MenuItem("Third"));
edit.add(sub);
// these are checkable menu items
debug = new CheckboxMenuItem("Debug");
edit.add(debug);
test = new CheckboxMenuItem("Testing");
edit.add(test);
mbar.add(edit);
// create an object to handle action and item events
MyMenuHandler handler = new MyMenuHandler(this);
// register it to receive those events
item1.addActionListener(handler);
item2.addActionListener(handler);
item3.addActionListener(handler);
item4.addActionListener(handler);
item5.addActionListener(handler);
item6.addActionListener(handler);
item7.addActionListener(handler);
item8.addActionListener(handler);
item9.addActionListener(handler);
item10.addActionListener(handler);
item11.addActionListener(handler);
item12.addActionListener(handler);
debug.addItemListener(handler);
test.addItemListener(handler);
// create an object to handle window events
MyWindowAdapter adapter = new MyWindowAdapter(this);
// register it to receive those events
addWindowListener(adapter);
}
public void paint(Graphics g) {
g.drawString(msg, 10, 200);
if(debug.getState())
g.drawString("Debug is on.", 10, 220);
else
g.drawString("Debug is off.", 10, 220);
if(test.getState())
g.drawString("Testing is on.", 10, 240);
else
g.drawString("Testing is off.", 10, 240);
}
}
class MyWindowAdapter extends WindowAdapter {
MenuFrame menuFrame;
public MyWindowAdapter(MenuFrame menuFrame) {
this.menuFrame = menuFrame;
}
public void windowClosing(WindowEvent we) {
menuFrame.setVisible(false);
}
}
class MyMenuHandler implements ActionListener, ItemListener {
MenuFrame menuFrame;
public MyMenuHandler(MenuFrame menuFrame) {
this.menuFrame = menuFrame;
}
// Handle action events.
public void actionPerformed(ActionEvent ae) {
String msg = "You selected ";
String arg = ae.getActionCommand();
if(arg.equals("New..."))
msg += "New.";
else if(arg.equals("Open..."))
msg += "Open.";
else if(arg.equals("Close"))
msg += "Close.";
else if(arg.equals("Quit..."))
msg += "Quit.";
else if(arg.equals("Edit"))
msg += "Edit.";
else if(arg.equals("Cut"))
msg += "Cut.";
else if(arg.equals("Copy"))
msg += "Copy.";
else if(arg.equals("Paste"))
msg += "Paste.";
else if(arg.equals("First"))
msg += "First.";
else if(arg.equals("Second"))
msg += "Second.";
else if(arg.equals("Third"))
msg += "Third.";
else if(arg.equals("Debug"))
msg += "Debug.";
else if(arg.equals("Testing"))
msg += "Testing.";
menuFrame.msg = msg;
menuFrame.repaint();
}
// Handle item events.
public void itemStateChanged(ItemEvent ie) {
menuFrame.repaint();
}
}
// Create frame window.
public class MenuDemo extends Applet {
Frame f;
public void init() {
f = new MenuFrame("Menu Demo");
int width = Integer.parseInt(getParameter("width"));
int height = Integer.parseInt(getParameter("height"));
setSize(new Dimension(width, height));
f.setSize(width, height);
f.setVisible(true);
}
public void start() {
f.setVisible(true);
}
public void stop() {
f.setVisible(false);
}
}
2.6 弹出菜单
PopupMenu
是另一个与菜单相关的类,它的工作方式与
Menu
类似,但能在特定位置显示菜单,为某些类型的菜单情况提供了灵活有用的替代方案。
3. 对话框
3.1 对话框概述
对话框常用于容纳一组相关控件,主要用于获取用户输入,通常是顶级窗口的子窗口。对话框没有菜单栏,但在其他方面功能类似框架窗口,可像向框架窗口添加控件一样向对话框添加控件。对话框分为模态和非模态两种。模态对话框激活时,所有输入将指向它,直到关闭,在此期间无法访问程序的其他部分;非模态对话框激活时,输入焦点可指向程序中的其他窗口,程序的其他部分仍可活动和访问。在 AWT 中,对话框类型为
Dialog
,常用构造函数如下:
-
Dialog(Frame parentWindow, boolean mode)
-
Dialog(Frame parentWindow, String title, boolean mode)
:
parentWindow
是对话框的所有者,
mode
为
true
时对话框为模态,否则为非模态,
title
是对话框的标题。一般会继承
Dialog
类,添加应用程序所需的功能。
3.2 示例代码:显示非模态对话框
// Demonstrate Dialog box.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code="DialogDemo" width=250 height=250>
</applet>
*/
// Create a subclass of Dialog.
class SampleDialog extends Dialog implements ActionListener {
SampleDialog(Frame parent, String title) {
super(parent, title, false);
setLayout(new FlowLayout());
setSize(300, 200);
add(new Label("Press this button:"));
Button b;
add(b = new Button("Cancel"));
b.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
dispose();
}
public void paint(Graphics g) {
g.drawString("This is in the dialog box", 10, 70);
}
}
// Create a subclass of Frame.
class MenuFrame extends Frame {
String msg = "";
CheckboxMenuItem debug, test;
MenuFrame(String title) {
super(title);
// create menu bar and add it to frame
MenuBar mbar = new MenuBar();
setMenuBar(mbar);
// create the menu items
Menu file = new Menu("File");
MenuItem item1, item2, item3, item4;
file.add(item1 = new MenuItem("New..."));
file.add(item2 = new MenuItem("Open..."));
file.add(item3 = new MenuItem("Close"));
file.add(new MenuItem("-"));
file.add(item4 = new MenuItem("Quit..."));
mbar.add(file);
Menu edit = new Menu("Edit");
MenuItem item5, item6, item7;
edit.add(item5 = new MenuItem("Cut"));
edit.add(item6 = new MenuItem("Copy"));
edit.add(item7 = new MenuItem("Paste"));
edit.add(new MenuItem("-"));
Menu sub = new Menu("Special", true);
MenuItem item8, item9, item10;
sub.add(item8 = new MenuItem("First"));
sub.add(item9 = new MenuItem("Second"));
sub.add(item10 = new MenuItem("Third"));
edit.add(sub);
// these are checkable menu items
debug = new CheckboxMenuItem("Debug");
edit.add(debug);
test = new CheckboxMenuItem("Testing");
edit.add(test);
mbar.add(edit);
// create an object to handle action and item events
MyMenuHandler handler = new MyMenuHandler(this);
// register it to receive those events
item1.addActionListener(handler);
item2.addActionListener(handler);
item3.addActionListener(handler);
item4.addActionListener(handler);
item5.addActionListener(handler);
item6.addActionListener(handler);
item7.addActionListener(handler);
item8.addActionListener(handler);
item9.addActionListener(handler);
item10.addActionListener(handler);
debug.addItemListener(handler);
test.addItemListener(handler);
// create an object to handle window events
MyWindowAdapter adapter = new MyWindowAdapter(this);
// register it to receive those events
addWindowListener(adapter);
}
public void paint(Graphics g) {
g.drawString(msg, 10, 200);
if(debug.getState())
g.drawString("Debug is on.", 10, 220);
else
g.drawString("Debug is off.", 10, 220);
if(test.getState())
g.drawString("Testing is on.", 10, 240);
else
g.drawString("Testing is off.", 10, 240);
}
}
class MyWindowAdapter extends WindowAdapter {
MenuFrame menuFrame;
public MyWindowAdapter(MenuFrame menuFrame) {
this.menuFrame = menuFrame;
}
public void windowClosing(WindowEvent we) {
menuFrame.dispose();
}
}
class MyMenuHandler implements ActionListener, ItemListener {
MenuFrame menuFrame;
public MyMenuHandler(MenuFrame menuFrame) {
this.menuFrame = menuFrame;
}
// Handle action events.
public void actionPerformed(ActionEvent ae) {
String msg = "You selected ";
String arg = ae.getActionCommand();
// Activate a dialog box when New is selected.
if(arg.equals("New...")) {
msg += "New.";
SampleDialog d = new
SampleDialog(menuFrame, "New Dialog Box");
d.setVisible(true);
}
// Try defining other dialog boxes for these options.
else if(arg.equals("Open..."))
msg += "Open.";
else if(arg.equals("Close"))
msg += "Close.";
else if(arg.equals("Quit..."))
msg += "Quit.";
else if(arg.equals("Edit"))
msg += "Edit.";
else if(arg.equals("Cut"))
msg += "Cut.";
else if(arg.equals("Copy"))
msg += "Copy.";
else if(arg.equals("Paste"))
msg += "Paste.";
else if(arg.equals("First"))
msg += "First.";
else if(arg.equals("Second"))
msg += "Second.";
else if(arg.equals("Third"))
msg += "Third.";
else if(arg.equals("Debug"))
msg += "Debug.";
else if(arg.equals("Testing"))
msg += "Testing.";
menuFrame.msg = msg;
menuFrame.repaint();
}
public void itemStateChanged(ItemEvent ie) {
menuFrame.repaint();
}
}
// Create frame window.
public class DialogDemo extends Applet {
Frame f;
public void init() {
f = new MenuFrame("Menu Demo");
int width = Integer.parseInt(getParameter("width"));
int height = Integer.parseInt(getParameter("height"));
setSize(width, height);
f.setSize(width, height);
f.setVisible(true);
}
public void start() {
f.setVisible(true);
}
public void stop() {
f.setVisible(false);
}
}
3.3 文件对话框
Java 提供了内置的文件对话框,让用户指定文件。创建文件对话框需实例化
FileDialog
对象,通常会显示操作系统提供的标准文件对话框。
FileDialog
的构造函数如下:
-
FileDialog(Frame parent)
-
FileDialog(Frame parent, String boxName)
-
FileDialog(Frame parent, String boxName, int how)
:
parent
是对话框的所有者,
boxName
是对话框标题栏显示的名称,若省略则标题为空,
how
若为
FileDialog.LOAD
,对话框用于选择读取的文件,若为
FileDialog.SAVE
,用于选择写入的文件,若省略则用于选择读取的文件。
FileDialog
提供了方法来确定用户选择的文件名称和路径,例如:
-
String getDirectory( )
:返回文件所在目录。
-
String getFile( )
:返回文件名。
以下是激活标准文件对话框的示例代码:
/* Demonstrate File Dialog box.
This is an application, not an applet.
*/
import java.awt.*;
import java.awt.event.*;
// Create a subclass of Frame.
class SampleFrame extends Frame {
SampleFrame(String title) {
super(title);
// remove the window when closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
}
// Demonstrate FileDialog.
class FileDialogDemo {
public static void main(String args[]) {
// create a frame that owns the dialog
Frame f = new SampleFrame("File Dialog Demo");
f.setVisible(true);
f.setSize(100, 100);
FileDialog fd = new FileDialog(f, "File Dialog");
fd.setVisible(true);
}
}
从 JDK 7 开始,可使用
FileDialog
选择文件列表,此功能由
setMultipleMode( )
、
isMultipleMode( )
和
getFiles( )
方法支持。
4. 重写 paint( ) 方法
重写
paint( )
方法时,有时需要调用超类的
paint( )
方法。在 Java 中,组件分为重量级和轻量级两种。重量级组件有自己的本地窗口(称为对等体),轻量级组件完全用 Java 代码实现,使用祖先提供的窗口。AWT 控件均为重量级组件,但如果容器包含轻量级组件,重写该容器的
paint( )
方法时必须调用
super.paint( )
,以确保轻量级子组件能正确绘制。若不确定子组件类型,可调用
Component
类的
isLightweight( )
方法,返回
true
表示组件为轻量级,否则为重量级。以下是重写
paint( )
方法的示例骨架:
public void paint(Graphics g) {
// code to repaint this window
// Call superclass paint()
super.paint(g);
}
总结
本文介绍了 Java AWT 中的布局管理器、菜单、对话框和文件对话框的使用,以及重写
paint( )
方法的注意事项。通过这些知识,可创建功能丰富的图形用户界面。在实际开发中,可根据需求灵活运用这些组件和方法,提高程序的交互性和用户体验。
流程图:创建菜单的流程
graph TD;
A[创建 MenuBar 对象] --> B[创建 Menu 对象];
B --> C[创建 MenuItem 对象];
C --> D[将 MenuItem 添加到 Menu];
D --> E[将 Menu 添加到 MenuBar];
E --> F[将 MenuBar 设置到 Frame];
表格:菜单项操作方法总结
| 方法 | 描述 |
|---|---|
setEnabled
| 启用或禁用菜单项 |
isEnabled
| 判断菜单项是否启用 |
setLabel
| 更改菜单项名称 |
getLabel
| 获取菜单项当前名称 |
getState
| 获取可勾选菜单项状态 |
setState
| 设置可勾选菜单项状态 |
5. 综合应用示例分析
5.1 菜单示例分析
在前面给出的
MenuDemo
示例中,程序创建了一个带有嵌套菜单的窗口。以下是对该示例主要部分的详细分析:
-
菜单框架的创建
:
MenuFrame
类继承自
Frame
,在其构造函数中完成了菜单的创建和添加。
- 创建菜单栏:使用
MenuBar mbar = new MenuBar();
创建菜单栏,并通过
setMenuBar(mbar);
将其添加到框架中。
- 创建菜单和菜单项:分别创建了
File
和
Edit
菜单,并向其中添加了多个菜单项,如
New...
、
Open...
等。
- 处理事件:创建了
MyMenuHandler
对象来处理菜单项的选择事件,以及
MyWindowAdapter
对象来处理窗口关闭事件。
-
事件处理
:
MyMenuHandler
类实现了
ActionListener
和
ItemListener
接口,分别处理
ActionEvent
和
ItemEvent
。
-
actionPerformed
方法:根据用户选择的菜单项,更新显示信息并调用
repaint
方法重绘窗口。
-
itemStateChanged
方法:当可勾选菜单项的状态改变时,调用
repaint
方法重绘窗口。
5.2 对话框示例分析
DialogDemo
示例在
MenuDemo
的基础上,添加了对话框的功能。当用户选择
New...
菜单项时,会弹出一个非模态对话框。
-
对话框的创建
:
SampleDialog
类继承自
Dialog
,在其构造函数中设置了布局、大小,并添加了标签和按钮。
-
事件处理
:在
SampleDialog
类中实现了
ActionListener
接口,当用户点击
Cancel
按钮时,调用
dispose
方法关闭对话框。
-
菜单事件处理
:在
MyMenuHandler
类的
actionPerformed
方法中,当用户选择
New...
菜单项时,创建并显示
SampleDialog
对象。
5.3 文件对话框示例分析
FileDialogDemo
示例展示了如何使用
FileDialog
打开标准文件对话框。
-
文件对话框的创建
:在
main
方法中,创建了一个
SampleFrame
对象,并实例化了
FileDialog
对象,设置其可见性后显示文件对话框。
-
获取文件信息
:
FileDialog
提供了
getDirectory
和
getFile
方法,可用于获取用户选择的文件目录和文件名。
6. 实际应用场景
6.1 开发桌面应用程序
在开发 Java 桌面应用程序时,可使用 AWT 组件创建用户界面。例如,在文本编辑器中:
- 使用菜单提供文件操作(如新建、打开、保存)、编辑操作(如剪切、复制、粘贴)等功能。
- 使用对话框获取用户输入,如保存文件时的文件名输入、设置参数等。
- 使用文件对话框让用户选择要打开或保存的文件。
6.2 开发图形化工具
在开发图形化工具时,可利用 AWT 的布局管理器和控件创建直观的界面。例如,在绘图工具中:
- 使用
GridBagLayout
布局管理器精确排列绘图工具按钮和画布。
- 使用菜单提供绘图模式选择、颜色设置等功能。
- 使用对话框设置绘图参数,如图形大小、线条粗细等。
7. 注意事项和技巧
7.1 重写 paint( ) 方法
-
当容器中包含轻量级组件时,重写
paint( )方法必须调用super.paint(g);,以确保轻量级组件正确绘制。 -
可在
paint( )方法中添加自定义的绘图代码,如绘制文本、图形等。
7.2 事件处理
-
对于菜单和对话框的事件处理,需实现相应的监听器接口(如
ActionListener、ItemListener),并在监听器方法中编写处理逻辑。 -
可使用
setActionCommand方法为菜单项设置自定义的操作命令字符串,方便事件处理。
7.3 资源管理
-
当对话框关闭时,调用
dispose方法释放系统资源,避免资源泄漏。 - 在使用文件对话框时,及时处理用户选择的文件信息,避免数据丢失。
表格:注意事项总结
| 注意事项 | 描述 |
|---|---|
| 重写 paint( ) |
包含轻量级组件时调用
super.paint(g)
|
| 事件处理 | 实现监听器接口并编写处理逻辑 |
| 资源管理 |
关闭对话框调用
dispose
,处理文件信息
|
流程图:文件对话框使用流程
graph TD;
A[创建 Frame 对象] --> B[创建 FileDialog 对象];
B --> C[设置 FileDialog 可见性];
C --> D[用户选择文件];
D --> E[获取文件目录和文件名];
E --> F[处理文件信息];
8. 总结与展望
通过本文的介绍,我们了解了 Java AWT 中布局管理器、菜单、对话框和文件对话框的使用,以及重写
paint( )
方法的注意事项。这些知识为开发 Java 图形用户界面提供了基础。
在未来的开发中,可进一步探索 AWT 的其他功能,如更多的布局管理器、控件和事件处理机制。同时,也可结合其他 Java 库,如 Swing 或 JavaFX,开发出更加美观、功能强大的图形用户界面。
列表:未来探索方向
-
学习更多 AWT 布局管理器的使用,如
BorderLayout、CardLayout等。 - 研究 AWT 控件的高级特性,如自定义控件外观和行为。
- 结合 Swing 或 JavaFX 开发跨平台的图形用户界面。
超级会员免费看
80

被折叠的 条评论
为什么被折叠?



