文档

Java™ 教程
隐藏目录
如何制作对话框
教程:使用Swing创建GUI
课程:使用Swing组件
部分:如何使用不同的组件

如何创建对话框

对话框窗口是一个独立的子窗口,用于在主Swing应用程序窗口之外显示临时通知。大多数对话框向用户呈现错误消息或警告,但对话框也可以呈现图像、目录树或与管理它们的主Swing应用程序兼容的任何内容。

为了方便起见,几个Swing组件类可以直接实例化和显示对话框。要创建简单的标准对话框,可以使用JOptionPane类。ProgressMonitor类可以显示操作的进度的对话框。另外两个类JColorChooserJFileChooser也提供了标准对话框。要显示打印对话框,可以使用Printing API。要创建自定义对话框,直接使用JDialog类。

简单对话框的代码可以很简洁。例如,下面是一个信息对话框:

An informational dialog requires minimal code

以下是创建并显示该对话框的代码:

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的内容面板的容器。

DialogDemo示例

这是一个显示对话框的应用程序的图片。

DialogDemo允许您弹出多种类型的对话框

请尝试以下操作: 
  1. 点击"Launch"按钮使用Java™ Web Start来运行Dialog Demo(下载JDK 7或更高版本)。或者,要自己编译和运行示例,请参考示例索引启动DialogDemo示例

  2. 点击"Show it!"按钮。
    一个模态对话框将出现。在关闭它之前,应用程序将无响应,但如果需要,它将重绘自身。您可以通过点击对话框中的按钮或显式地使用对话框窗口装饰来关闭对话框。
  3. 在"More Dialogs"面板中,点击底部的单选按钮,然后再点击"Show it!"按钮。
    一个非模态对话框将出现。请注意,在非模态对话框显示时,DialogDemo窗口仍然完全可用。
  4. 在非模态对话框显示时,将DialogDemo窗口最小化。
    对话框将从屏幕上消失,直到您将DialogDemo窗口还原。

JOptionPane功能

使用JOptionPane,您可以快速创建和自定义几种不同类型的对话框。 JOptionPane提供了对标准对话框进行布局、提供图标、指定对话框标题和文本以及自定义按钮文本的支持。其他功能允许您自定义对话框显示的组件并指定对话框在屏幕上的位置。您甚至可以指定选项面板将自己放入JInternalFrame而不是JDialog

创建JOptionPane时,特定于外观的代码会向JOptionPane添加组件,并确定这些组件的布局。

JOptionPane的图标支持使您可以轻松地指定对话框显示的图标。您可以使用自定义图标、没有图标或四个标准的JOptionPane图标(问题、信息、警告和错误)中的任何一个。每种外观和感觉都有其自己的四个标准图标的版本。下图显示了Java(和Windows)外观中使用的图标。

JOptionPane使用的图标
图标描述 Java外观 Windows外观
问题 对话框询问问题的Java外观图标 对话框询问问题的Windows外观图标
信息 信息对话框的Java外观图标 信息对话框的Windows外观图标
警告 警告对话框的Java外观图标 警告对话框的Windows外观图标
错误 错误对话框的Java外观图标 错误对话框的Windows外观图标

创建和显示简单对话框

对于大多数简单的模态对话框,您可以使用JOptionPaneshowXxxDialog方法来创建和显示对话框。如果您的对话框应该是一个内部窗口,那么在show后面添加Internal — 例如,showMessageDialog变成showInternalMessageDialog。如果您需要控制对话框的窗口关闭行为,或者如果您不希望对话框是模态的,那么您应该直接实例化JOptionPane并将其添加到JDialog实例中。然后调用JDialog上的setVisible(true)使其显示。

最有用的两个showXxxDialog方法是showMessageDialogshowOptionDialogshowMessageDialog方法显示一个简单的单按钮对话框。 showOptionDialog方法显示一个自定义对话框,它可以显示带有自定义按钮文本的各种按钮,并且可以包含一个标准文本消息或一组组件。

另外两个showXxxDialog方法使用较少。 showConfirmDialog方法要求用户确认某些事情,但提供标准的按钮文本(例如Yes/No或本地化的等效文本),而不是根据用户情况定制的按钮文本(例如Start/Cancel)。第四个方法showInputDialog用于显示一个模态对话框,从用户那里获取一个字符串,可以使用文本字段、不可编辑的组合框或列表。

以下是一些示例,取自DialogDemo.java,演示了如何使用showMessageDialogshowOptionDialogJOptionPane构造函数。有关更多示例代码,请参见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
显示一个模态对话框,其中包含指定的按钮、图标、消息、标题等。使用此方法,您可以更改标准对话框按钮上显示的文本。您还可以进行许多其他类型的自定义。
不同词汇的Yes/No/Cancel;showOptionDialog
//自定义按钮文本
Object[] options = {"是的,请",
                    "不,谢谢",
                    "没有鸡蛋,没有火腿!"};
int n = JOptionPane.showOptionDialog(frame,
    "您想要一些绿色的鸡蛋搭配火腿吗?",
    "一个愚蠢的问题",
    JOptionPane.YES_NO_CANCEL_OPTION,
    JOptionPane.QUESTION_MESSAGE,
    null,
    options,
    options[2]);
JOptionPane(构造函数)
创建一个具有指定按钮、图标、消息、标题等的JOptionPane。然后,您必须将选项窗格添加到JDialog中,在选项窗格上注册属性更改监听器,并显示对话框。有关详细信息,请参见停止自动关闭对话框
明确使用JOptionPane构造函数
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 构造函数不包括此参数。相反,您在创建包含 JOptionPaneJDialog 时指定父窗体,并使用 JDialogsetLocationRelativeTo 方法设置对话框位置。

Object message
此必需的参数指定对话框在其主区域中显示的内容。通常,您指定一个字符串,这将导致对话框显示具有指定文本的标签。您可以通过在消息字符串中放置换行符 (\n) 来将消息拆分为多行。例如:
"完成句子:\n \"绿色的鸡蛋和...\""
String title
对话框的标题。
int optionType
指定出现在对话框底部的按钮集合。从以下标准集合中选择:DEFAULT_OPTIONYES_NO_OPTIONYES_NO_CANCEL_OPTIONOK_CANCEL_OPTION
int messageType
此参数确定对话框中显示的图标。从以下值中选择:PLAIN_MESSAGE(无图标)、ERROR_MESSAGEINFORMATION_MESSAGEWARNING_MESSAGEQUESTION_MESSAGE
Icon icon
在对话框中显示的图标。
Object[] options
通常用于指定每个按钮在对话框底部显示的字符串。有关更多信息,请参阅自定义标准对话框中的按钮文本。还可以用于指定要由按钮显示的图标或要添加到按钮行的非按钮组件。
Object initialValue
指定要选择的默认值。

您可以让选项窗口显示其默认图标,也可以使用消息类型或图标参数指定图标。默认情况下,使用showMessageDialog创建的选项窗口显示信息图标,使用showConfirmDialogshowInputDialog创建的选项窗口显示问号图标,使用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]); //默认按钮标题

如前面的代码片段所示,showMessageDialogshowConfirmDialogshowOptionDialog方法返回一个整数,指示用户的选择。该整数的取值为YES_OPTIONNO_OPTIONCANCEL_OPTIONOK_OPTIONCLOSED_OPTION。除了CLOSED_OPTION外,每个选项对应于用户按下的按钮。当返回CLOSED_OPTION时,表示用户显式关闭了对话框窗口,而不是选择了选项窗口内部的按钮。

即使您更改了标准对话框按钮显示的字符串,返回值仍然是预定义的整数之一。例如,YES_NO_OPTION对话框始终返回以下值之一:YES_OPTIONNO_OPTIONCLOSED_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。虽然这个对话框的写法有点无用,但是它的代码足够简单,可以用作更复杂对话框的模板。

除了设置属性更改监听器之外,以下代码还调用了JDialogsetDefaultCloseOperation方法,并实现了一个窗口监听器,以正确处理窗口关闭尝试。如果你不关心用户显式关闭窗口时是否收到通知,则忽略粗体代码。

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("尝试使用窗口装饰关闭不自动关闭的对话框。你不能!");
}

对话框 API

下表列出了常用的 JOptionPaneJDialog 的构造方法和方法。其他常用的方法由 DialogWindowComponent 类定义,包括 packsetSizesetVisible

API 如下所示:

显示标准模态对话框(使用 JOptionPane 类的方法)static void showMessageDialog(Component, Object)
static void showMessageDialog(Component, Object, String, int)
static void showMessageDialog(Component, Object, String, int, Icon)创建和显示简单对话框static int showOptionDialog(Component, Object, String, int, int, Icon, Object[], Object)创建和显示简单对话框static int showConfirmDialog(Component, Object)
static int showConfirmDialog(Component, Object, String, int)
static int showConfirmDialog(Component, Object, String, int, int)
static int showConfirmDialog(Component, Object, String, int, int, Icon)创建和显示简单对话框static String showInputDialog(Object)
static String showInputDialog(Component, Object)
static String showInputDialog(Component, Object, String, int)
static String showInputDialog(Component, Object, String, int, Icon, Object[], Object)创建和显示简单对话框static void showInternalMessageDialog(...)
static void showInternalOptionDialog(...)
static void showInternalConfirmDialog(...)
static String showInternalInputDialog(...)JOptionPane API文档
使用JOptionPane的方法
方法或构造函数 用途
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类方法,用于查找指定组件所在的framedesktop pane
int getMaxCharactersPerLineCount() 确定选项面板文本中将自动插入换行符的位置。(默认值为Integer.MAX_VALUE。)要使用此方法,必须创建一个JOptionPane子类。例如,以下代码将导致选项面板每行只有一个单词,因为字符串中的每个单词都是5个字符或更少:
JOptionPane op = new JOptionPane("This is the text.") {
    public int getMaxCharactersPerLineCount() {
        return 5;
    }
};

常用的 JDialog 构造方法和方法JDialog()
JDialog(Dialog)
JDialog(Dialog, boolean)
JDialog(Dialog, String)
JDialog(Dialog, String, boolean)
JDialog(Dialog, String, boolean, GraphicsConfiguration)
JDialog(Frame)
JDialog(Frame, boolean)
JDialog(Frame, String)
JDialog(Frame, String, boolean)
JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Window owner)
JDialog(Window owner, Dialog.ModalityType modalityType)
JDialog(Window owner, String title)
JDialog(Window owner, String title, Dialog.ModalityType modalityType)
JDialog(Window owner, String title, Dialog.ModalityType modalityType, GraphicsConfiguration gc)JDialogFrameJFrametruefalsevoid setContentPane(Container)
Container getContentPane()使用顶层容器void setDefaultCloseOperation(int)
int getDefaultCloseOperation()DISPOSE_ON_CLOSEDO_NOTHING_ON_CLOSEHIDE_ON_CLOSE响应窗口关闭事件void setLocationRelativeTo(Component)static void setDefaultLookAndFeelDecorated(boolean)
static boolean isDefaultLookAndFeelDecorated()指定窗口装饰

使用对话框的示例

这个表格列出了使用JOptionPaneJDialog的示例。要查找其他使用对话框的示例,请参阅进度条颜色选择器文件选择器的示例列表。

示例 描述位置 备注
DialogDemo
CustomDialog
本节 使用JOptionPaneJDialog创建多种对话框。
Framework 当用户选择退出菜单项时弹出确认对话框。
ListDialog 如何使用BoxLayout 实现一个包含滚动列表和两个按钮的模态对话框。除了工具方法getFrameForComponent外,不使用JOptionPane

上一页:如何使用组合框
下一页:如何使用编辑窗格和文本窗格