这些Java教程是为JDK 8编写的。本页中描述的示例和实践不利用后续版本引入的改进,并可能使用不再可用的技术。
有关Java SE 9和后续版本中更新的语言特性的摘要,请参见Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息,请参见JDK发行说明。
对话框窗口是一个独立的子窗口,用于在主Swing应用程序窗口之外显示临时通知。大多数对话框向用户呈现错误消息或警告,但对话框也可以呈现图像、目录树或与管理它们的主Swing应用程序兼容的任何内容。
为了方便起见,几个Swing组件类可以直接实例化和显示对话框。要创建简单的标准对话框,可以使用JOptionPane
类。ProgressMonitor
类可以显示操作的进度的对话框。另外两个类JColorChooser
和JFileChooser
也提供了标准对话框。要显示打印对话框,可以使用Printing
API。要创建自定义对话框,直接使用JDialog
类。
简单对话框的代码可以很简洁。例如,下面是一个信息对话框:
以下是创建并显示该对话框的代码:
JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。");
本节的其余部分包括以下主题:
每个对话框都依赖于一个Frame组件。当该Frame被销毁时,其依赖的对话框也被销毁。当Frame被最小化时,其依赖的对话框也从屏幕上消失。当Frame被还原时,其依赖的对话框重新显示在屏幕上。Swing的JDialog类从AWT的Dialog
类继承了这种行为。
对话框可以是模态的。当模态对话框可见时,它会阻止用户在程序中的所有其他窗口上进行输入。JOptionPane创建的JDialog
是模态的。要创建非模态对话框,必须直接使用JDialog
类。
从JDK 7开始,您可以使用新的Modality API修改对话框窗口的模态行为。详细信息请参见新的Modality API。
JDialog
类是AWT java.awt.Dialog
类的子类。它添加了一个根容器和对Dialog
对象的默认关闭操作的支持。这些都是JFrame
具有的相同功能,直接使用JDialog
与使用JFrame
非常相似。如果您要直接使用JDialog
,则应该理解使用顶级容器和如何创建框架中的内容,尤其是响应窗口关闭事件。
即使您使用JOptionPane
来实现对话框,实际上仍然在使用JDialog
。原因是JOptionPane
只是一个可以自动创建JDialog
并将自身添加到JDialog
的内容面板的容器。
这是一个显示对话框的应用程序的图片。
使用JOptionPane
,您可以快速创建和自定义几种不同类型的对话框。 JOptionPane
提供了对标准对话框进行布局、提供图标、指定对话框标题和文本以及自定义按钮文本的支持。其他功能允许您自定义对话框显示的组件并指定对话框在屏幕上的位置。您甚至可以指定选项面板将自己放入JInternalFrame
而不是JDialog
。
创建JOptionPane
时,特定于外观的代码会向JOptionPane
添加组件,并确定这些组件的布局。
JOptionPane
的图标支持使您可以轻松地指定对话框显示的图标。您可以使用自定义图标、没有图标或四个标准的JOptionPane
图标(问题、信息、警告和错误)中的任何一个。每种外观和感觉都有其自己的四个标准图标的版本。下图显示了Java(和Windows)外观中使用的图标。
图标描述 | Java外观 | Windows外观 |
---|---|---|
问题 | ||
信息 | ||
警告 | ||
错误 |
对于大多数简单的模态对话框,您可以使用JOptionPane
的showXxxDialog
方法来创建和显示对话框。如果您的对话框应该是一个内部窗口,那么在show
后面添加Internal
— 例如,showMessageDialog
变成showInternalMessageDialog
。如果您需要控制对话框的窗口关闭行为,或者如果您不希望对话框是模态的,那么您应该直接实例化JOptionPane
并将其添加到JDialog
实例中。然后调用JDialog
上的setVisible(true)
使其显示。
最有用的两个showXxxDialog
方法是showMessageDialog
和showOptionDialog
。 showMessageDialog
方法显示一个简单的单按钮对话框。 showOptionDialog
方法显示一个自定义对话框,它可以显示带有自定义按钮文本的各种按钮,并且可以包含一个标准文本消息或一组组件。
另外两个showXxxDialog
方法使用较少。 showConfirmDialog
方法要求用户确认某些事情,但提供标准的按钮文本(例如Yes/No或本地化的等效文本),而不是根据用户情况定制的按钮文本(例如Start/Cancel)。第四个方法showInputDialog
用于显示一个模态对话框,从用户那里获取一个字符串,可以使用文本字段、不可编辑的组合框或列表。
以下是一些示例,取自DialogDemo.java
,演示了如何使用showMessageDialog
、showOptionDialog
和JOptionPane
构造函数。有关更多示例代码,请参见DialogDemo.java
和其他在使用对话框的示例中列出的程序。
showMessageDialog
showMessageDialog
的一些示例:
//默认标题和图标 JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。"); |
|
//自定义标题和警告图标 JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。", "无聊的警告", JOptionPane.WARNING_MESSAGE); |
|
//自定义标题和错误图标 JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。", "无聊的错误", JOptionPane.ERROR_MESSAGE); |
|
//自定义标题和无图标 JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。", "一个普通消息", JOptionPane.PLAIN_MESSAGE); |
|
//自定义标题和自定义图标 JOptionPane.showMessageDialog(frame, "鸡蛋不应该是绿色的。", "无聊的自定义对话框", JOptionPane.INFORMATION_MESSAGE, icon); |
showOptionDialog
//自定义按钮文本 Object[] options = {"是的,请", "不,谢谢", "没有鸡蛋,没有火腿!"}; int n = JOptionPane.showOptionDialog(frame, "您想要一些绿色的鸡蛋搭配火腿吗?", "一个愚蠢的问题", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); |
JOptionPane
(构造函数)
JOptionPane
。然后,您必须将选项窗格添加到JDialog
中,在选项窗格上注册属性更改监听器,并显示对话框。有关详细信息,请参见停止自动关闭对话框。
final JOptionPane optionPane = new JOptionPane( "唯一关闭此对话框的方法是通过\n" + "按下以下按钮之一。\n" + "您理解吗?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION); |
所有showXxxDialog
方法和JOptionPane
构造函数的参数都是标准化的,尽管每个方法和构造函数的参数数量不同。下面的列表描述了每个参数。要查看特定方法的精确参数列表,请参阅对话框 API。
Component parentComponent
showXxxDialog
方法的第一个参数始终是父组件,它必须是一个 Frame、一个 Frame 内的组件或者为 null。如果指定了 Frame 或 Dialog,则对话框将显示在 Frame 的中心并遵循该 Frame 的焦点行为。如果指定了 Frame 内的组件,则对话框将显示在该组件的中心并遵循该组件的 Frame 的焦点行为。如果指定为 null,则外观会选择适当的位置来放置对话框 - 通常是屏幕的中心 - 并且对话框不一定会遵循任何可见 Frame 或 Dialog 的焦点行为。
JOptionPane
构造函数不包括此参数。相反,您在创建包含 JOptionPane
的 JDialog
时指定父窗体,并使用 JDialog
的 setLocationRelativeTo
方法设置对话框位置。
Object message
\n
) 来将消息拆分为多行。例如:
"完成句子:\n \"绿色的鸡蛋和...\""
String title
int optionType
DEFAULT_OPTION
、YES_NO_OPTION
、YES_NO_CANCEL_OPTION
、OK_CANCEL_OPTION
。
int messageType
PLAIN_MESSAGE
(无图标)、ERROR_MESSAGE
、INFORMATION_MESSAGE
、WARNING_MESSAGE
、QUESTION_MESSAGE
。
Icon icon
Object[] options
Object initialValue
您可以让选项窗口显示其默认图标,也可以使用消息类型或图标参数指定图标。默认情况下,使用showMessageDialog
创建的选项窗口显示信息图标,使用showConfirmDialog
或showInputDialog
创建的选项窗口显示问号图标,使用JOptionPane
构造函数创建的选项窗口不显示图标。要指定对话框显示标准图标或无图标,请指定与所需图标相对应的消息类型。要指定自定义图标,请使用图标参数。图标参数的优先级高于消息类型;只要图标参数具有非空值,对话框就会显示指定的图标。
当您使用JOptionPane
创建对话框时,可以使用标准按钮文本(可能会根据外观和语言环境而有所不同),也可以指定不同的文本。默认情况下,选项窗口类型决定显示多少个按钮。例如,YES_NO_OPTION
对话框有两个按钮,YES_NO_CANCEL_OPTION
对话框有三个按钮。
下面的代码取自DialogDemo.java
,创建了两个是/否对话框。第一个对话框使用showConfirmDialog
实现,它使用外观词汇来表示两个按钮。第二个对话框使用showOptionDialog
,以便可以自定义词汇。除了词汇变化外,对话框是相同的。
//默认图标,自定义标题 int n = JOptionPane.showConfirmDialog( frame, "你想要绿色的鸡蛋和火腿吗?", "一个无聊的问题", JOptionPane.YES_NO_OPTION); |
|
Object[] options = {"是的,请", "绝不!"}; int n = JOptionPane.showOptionDialog(frame, "你想要绿色的鸡蛋和火腿吗?", "一个愚蠢的问题", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, //不使用自定义图标 options, //按钮标题 options[0]); //默认按钮标题 |
如前面的代码片段所示,showMessageDialog
、showConfirmDialog
和showOptionDialog
方法返回一个整数,指示用户的选择。该整数的取值为YES_OPTION
、NO_OPTION
、CANCEL_OPTION
、OK_OPTION
和CLOSED_OPTION
。除了CLOSED_OPTION
外,每个选项对应于用户按下的按钮。当返回CLOSED_OPTION
时,表示用户显式关闭了对话框窗口,而不是选择了选项窗口内部的按钮。
即使您更改了标准对话框按钮显示的字符串,返回值仍然是预定义的整数之一。例如,YES_NO_OPTION
对话框始终返回以下值之一:YES_OPTION
,NO_OPTION
或CLOSED_OPTION
。
唯一不返回整数的showXxxDialog
形式是showInputDialog
,它返回一个Object
。这个Object
通常是反映用户选择的String
。以下是使用showInputDialog
创建一个对话框,让用户选择三个字符串的示例:
Object[] possibilities = {"火腿", "鸡肉罐头", "山药"}; String s = (String)JOptionPane.showInputDialog( frame, "完成句子:\n" + "\"绿色的鸡蛋和...\"", "自定义对话框", JOptionPane.PLAIN_MESSAGE, icon, possibilities, "火腿"); //如果返回了一个字符串,就这样显示。 if ((s != null) && (s.length() > 0)) { setLabel("绿色的鸡蛋和... " + s + "!"); return; } //如果执行到这里,返回值为null/空。 setLabel("来吧,完成这个句子!");
如果您不介意限制用户的选择,可以使用少量参数的showInputDialog
方法,或者为对象数组指定null
。在Java外观中,将null
替换为possibilities
会得到一个带有文本字段的对话框,效果如下:
由于用户可以在文本字段中输入任何内容,您可能希望检查返回值,并要求用户重新尝试如果无效。另一种方法是在返回之前创建一个自定义对话框,验证用户输入的数据。请参见CustomDialog.java
中验证数据的示例。
如果您正在设计自定义对话框,您需要设计对话框的API,以便可以查询用户选择了什么。例如,CustomDialog
具有一个getValidatedText
方法,用于返回用户输入的文本。
默认情况下,当用户点击JOptionPane
创建的按钮时,对话框会关闭。但是如果你想在关闭对话框之前检查用户的答案怎么办?在这种情况下,你必须实现自己的属性更改监听器,以便当用户点击按钮时,对话框不会自动关闭。
DialogDemo
包含两个实现了属性更改监听器的对话框。其中一个对话框是自定义的模态对话框,在CustomDialog
中实现,它使用JOptionPane
获取标准图标和布局辅助。另一个对话框的代码如下,它使用了标准的Yes/No JOptionPane
。虽然这个对话框的写法有点无用,但是它的代码足够简单,可以用作更复杂对话框的模板。
除了设置属性更改监听器之外,以下代码还调用了JDialog
的setDefaultCloseOperation
方法,并实现了一个窗口监听器,以正确处理窗口关闭尝试。如果你不关心用户显式关闭窗口时是否收到通知,则忽略粗体代码。
final JOptionPane optionPane = new JOptionPane( "关闭此对话框的唯一方法是通过\n" + "按下以下按钮之一。\n" + "你明白吗?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION); final JDialog dialog = new JDialog(frame, "点击一个按钮", true); dialog.setContentPane(optionPane); dialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE); dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { setLabel("阻止用户关闭窗口的尝试。"); } }); optionPane.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { String prop = e.getPropertyName(); if (dialog.isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) { //如果你要在关闭窗口之前检查一些东西, //可以在这里处理。 dialog.setVisible(false); } } }); dialog.pack(); dialog.setVisible(true); int value = ((Integer)optionPane.getValue()).intValue(); if (value == JOptionPane.YES_OPTION) { setLabel("很好。"); } else if (value == JOptionPane.NO_OPTION) { setLabel("尝试使用窗口装饰关闭不自动关闭的对话框。你不能!"); }
下表列出了常用的 JOptionPane
和 JDialog
的构造方法和方法。其他常用的方法由 Dialog
、Window
和 Component
类定义,包括 pack
、setSize
和 setVisible
。
API 如下所示:
显示标准模态对话框(使用JOptionPane
类的方法)static void showMessageDialog(Component, Object)
方法或构造函数 | 用途 |
---|---|
JOptionPane() JOptionPane(Object) JOptionPane(Object, int) JOptionPane(Object, int, int) JOptionPane(Object, int, int, 图标) JOptionPane(Object, int, int, 图标, 对象数组) JOptionPane(Object, int, int, 图标, 对象数组, 对象) |
创建JOptionPane 实例。有关参数及其效果的讨论,请参阅创建和显示简单对话框。 |
static Frame getFrameForComponent(Component) static JDesktopPane getDesktopPaneForComponent(Component) |
方便的JOptionPane 类方法,用于查找指定组件所在的frame或desktop pane。 |
int getMaxCharactersPerLineCount() | 确定选项面板文本中将自动插入换行符的位置。(默认值为Integer.MAX_VALUE 。)要使用此方法,必须创建一个JOptionPane 子类。例如,以下代码将导致选项面板每行只有一个单词,因为字符串中的每个单词都是5个字符或更少:
JOptionPane op = new JOptionPane("This is the text.") { public int getMaxCharactersPerLineCount() { return 5; } }; |
JDialog
构造方法和方法JDialog()
JDialog
Frame
JFrame
true
false
void setContentPane(Container)
DISPOSE_ON_CLOSE
DO_NOTHING_ON_CLOSE
HIDE_ON_CLOSE
响应窗口关闭事件void setLocationRelativeTo(Component)static void setDefaultLookAndFeelDecorated(boolean)
这个表格列出了使用JOptionPane
或JDialog
的示例。要查找其他使用对话框的示例,请参阅进度条、颜色选择器和文件选择器的示例列表。
示例 | 描述位置 | 备注 |
---|---|---|
DialogDemo ,CustomDialog |
本节 | 使用JOptionPane 和JDialog 创建多种对话框。 |
Framework |
— | 当用户选择退出菜单项时弹出确认对话框。 |
ListDialog |
如何使用BoxLayout | 实现一个包含滚动列表和两个按钮的模态对话框。除了工具方法getFrameForComponent 外,不使用JOptionPane 。 |