12.2.7 使用JOptionPane

12.2.7 使用JOptionPane

通过JOptionPane可以非常方便地创建一些简单的对话框,Swing已经为这些对话框添加了相应的组件,无须程序员手动添加组件。JOptionPane提供了如下4个方法来创建对话框。

方法 描述
showMessageDialog/showInternalMessageDialog 消息对话框,告知用户某事已发生,用户只能单击“确定”按钮,类似于JavaScriptalert函数。
showConfirmDialog/showInternalConfirmDialog 确认对话框,向用户确认某个问题,用户可以选择yesnocancel等选项。类似于JavaScriptcomfirm函数。该方法返回用户单击了哪个按钮。
showInputDialog/showInternalInputDialog 输入对话框,提示要求输入某些信息,类似于JavaScriptprompt函数。该方法返回用户输入的字符串。
showOptionDialog/showInternalOptionDialog 自定义选项对话框,允许使用自定义选项,可以取代showConfirmDialog所产生的对话框,只是用起来更复杂。

JOptionPane产生的所有对话框都是模式的,在用户完成与对话框的交互之前,showXxxDialog方法都将一直阻塞当前线程

JOptionPane对话框 区域划分

JOptionPane所产生的对话框总是具有如图12.10所示的布局:
这里有一张图片
上面这些方法都提供了相应的showInternalXxxDialog版本,这种方法以InternalFrame的方式打开对话框。
下面就图12.10中所示的4个区域分别进行介绍

(1)输入区

如果创建的对话框无须接收用户输入,则输入区不存在。输入区组件可以是普通文本框组件,也可以是下拉列表框组件。
如果调用上面的showInternalXxxDialog()方法时指定了一个数组类型的selectionValues参数,则输入区包含一个下拉列表框组件。

(2)图标区

左上角的图标会随创建的对话框所包含消息类型的不同而不同,JOptionPane可以提供如下5种消息类型。

messageType参数 描述
ERROR_MESSAGE 错误消息,其图标是一个红色的X图标,如图12.10所示
INFORMATION_MESSAGE 普通消息,其默认图标是蓝色的感叹号。
WARNING_MESSAGE 警告消息,其默认图标是黄色感叹号。
QUESTION_MESSAGE 问题消息,其默认图标是绿色问号。
PLAIN_MESSAGE 普通消息,没有默认图标

实际上,JOptionPane的所有showXxxDialog()方法都可以提供一个可选的icon参数,用于指定该对话框的图标。

调用showXxxDialog方法时还可以指定一个可选的title参数,该参数指定所创建对话框的标题

(3)消息区

不管是哪种对话框,其消息区总是存在的,消息区的内容通过message参数来指定,根据message参数的类型不同,消息区显示的内容也是不同的。该message参数可以是如下几种类型

  • String类型:将该字符串对象包装成JLabel对象,然后显示在对话框中。
  • Icon:将该Icon被包装成JLabe后作为对话框的消息
  • Component:将该Component在对话框的消息区中显示出来。
  • Object[]:对象数组被解释为在纵向排列的一系列message对象,每个message对象根据其实际类型又可以是字符串、图标、组件、对象数组等。
  • 其他类型:系统调用该对象的toString方法返回一个字符串,并将该字符串对象包装成JLabel对象,然后显示在对话框中。

大部分时候对话框的消息区都是普通字符串,但使用Component作为消息区组件则更加灵活,因为该Component参数几乎可以是任何对象,从而可以让对话框的消息区包含任何内容。

(4)按钮区

对话框底部的按钮区也是一定存在的,但所包含的按钮则会随对话框的类型、选项类型而改变。

输入框和消息框的按钮

对于调用showInputDialog()showMessageDialog()方法得到的对话框,底部总是包含“确定”和“取消”两个标准按钮。

确认对话框的按钮

对于showConfirmDialog()所打开的确认对话框,则可以指定一个整数类型的optionType参数,该参数可以取如下几个值。

optionType参数 描述
DEFAULT_OPTION 按钮区只包含一个“确定”按钮。
YES_NO_OPTION 按钮区包含“是”、“否”两个按钮。
YES_NO_CANCEL_OPTION 按钮区包含“是”、“否”、“取消”三个按钮。
OK_CANCEL_OPTION 按钮区包含“确定”、“取消”两个按钮。

选项对话框的按钮

方法 描述
static int showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue) Brings up a dialog with a specified icon, where the initial choice is determined by the initialValue parameter and the number of choices is determined by the optionType parameter.

如果使用showOptionDialog方法来创建选项对话框,则可以通过指定一个Object[]类型的options参数来设置按钮区能使用的选项按钮。与前面的message参数类似的是,options数组的数组元素可以是如下几种类型。

描述
String 使用该字符串来创建一个JButton,并将其显示在按钮区。
Icon 使用该Icon来创建一个JButton,并将其显示在按钮区。
Component 直接将该组件显示在按钮区。
其他类型 系统调用该对象的toString方法返回一个字符串,并使用该字符串来创建一个JButton,并将其显示在按钮区。

对话框的返回值

当用户与对话框交互结束后,不同类型对话框的返回值如下。
showMessageDialog:无返回值。
showInputDialog:返回用户输入或选择的字符串。
showConfirmDialog:返回一个整数代表用户选择的选项。
showOptionDialog:返回一个整数代表用户选择的选项,如果用户选择第一项,则返回0;如果选择第二项,则返回1……依此类推。

showConfirmDialog所产生的对话框,有如下几个返回值

showConfirmDialog返回值 描述
YES_OPTION 用户单击了“是”按钮后返回。
NO_OPTION 用户单击了“否”按钮后返回。
CANCEL_OPTION 用户单击了“取消”按钮后返回。
OK_OPTION 用户单击了“确定”按钮后返回
CLOSED_OPTION 用户单击了对话框右上角的“x”按钮后返回。

对于showOptionDialog方法所产生的对话框,也可能返回一个CLOSED_OPTION值,当用户单击了对话框右上角的“x”按钮后将返回该值
图12.11已经非常清楚地显示了JOptionPane所支持的4种对话框,以及所有对话框的通用选项、每个对话框的特定选项。

程序 对话框

下面程序允许使用JOptionPane来弹出各种对话框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import java.util.Date;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class JOptionPaneTest {
JFrame jf = new JFrame("测试JOptionPane");
// 分别定义6个面板用于定义对话框的几种选项
private ButtonPanel messagePanel;
private ButtonPanel messageTypePanel;
private ButtonPanel msgPanel;
private ButtonPanel confirmPanel;
private ButtonPanel optionsPanel;
private ButtonPanel inputPanel;
private String messageString = "消息区内容";
private Icon messageIcon = new ImageIcon("ico/heart.png");
private Object messageObject = new Date();
private Component messageComponent = new JButton("组件消息");
private JButton msgBn = new JButton("消息对话框");
private JButton confrimBn = new JButton("确认对话框");
private JButton inputBn = new JButton("输入对话框");
private JButton optionBn = new JButton("选项对话框");

public void init() {
JPanel top = new JPanel();
top.setBorder(new TitledBorder(new EtchedBorder(), "对话框的通用选项", TitledBorder.CENTER, TitledBorder.TOP));
top.setLayout(new GridLayout(1, 2));
// 消息类型Panel,该Panel中的选项决定对话框的图标
messageTypePanel = new ButtonPanel("选择消息的类型", new String[] { "ERROR_MESSAGE", "INFORMATION_MESSAGE",
"WARNING_MESSAGE", "QUESTION_MESSAGE", "PLAIN_MESSAGE" });
// 消息内容类型的Panel,该Panel中的选项决定对话框的消息区的内容
messagePanel = new ButtonPanel("选择消息内容的类型", new String[] { "字符串消息", "图标消息", "组件消息", "普通对象消息", "Object[]消息" });
top.add(messageTypePanel);
top.add(messagePanel);
JPanel bottom = new JPanel();
bottom.setBorder(new TitledBorder(new EtchedBorder(), "弹出不同的对话框", TitledBorder.CENTER, TitledBorder.TOP));
bottom.setLayout(new GridLayout(1, 4));
// 创建用于弹出消息对话框的Panel
msgPanel = new ButtonPanel("消息对话框", null);
msgBn.addActionListener(new ShowAction());
msgPanel.add(msgBn);
// 创建用于弹出确认对话框的Panel
confirmPanel = new ButtonPanel("确认对话框",
new String[] { "DEFAULT_OPTION", "YES_NO_OPTION", "YES_NO_CANCEL_OPTION", "OK_CANCEL_OPTION" });
confrimBn.addActionListener(new ShowAction());
confirmPanel.add(confrimBn);
// 创建用于弹出输入对话框的Panel
inputPanel = new ButtonPanel("输入对话框", new String[] { "单行文本框", "下拉列表选择框" });
inputBn.addActionListener(new ShowAction());
inputPanel.add(inputBn);
// 创建用于弹出选项对话框的Panel
optionsPanel = new ButtonPanel("选项对话框", new String[] { "字符串选项", "图标选项", "对象选项" });
optionBn.addActionListener(new ShowAction());
optionsPanel.add(optionBn);
bottom.add(msgPanel);
bottom.add(confirmPanel);
bottom.add(inputPanel);
bottom.add(optionsPanel);
Box box = new Box(BoxLayout.Y_AXIS);
box.add(top);
box.add(bottom);
jf.add(box);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}

// 根据用户选择返回选项类型
private int getOptionType() {
switch (confirmPanel.getSelection()) {
case "DEFAULT_OPTION":
return JOptionPane.DEFAULT_OPTION;
case "YES_NO_OPTION":
return JOptionPane.YES_NO_OPTION;
case "YES_NO_CANCEL_OPTION":
return JOptionPane.YES_NO_CANCEL_OPTION;
default:
return JOptionPane.OK_CANCEL_OPTION;
}
}

// 根据用户选择返回消息
private Object getMessage() {
switch (messagePanel.getSelection()) {
case "字符串消息":
return messageString;
case "图标消息":
return messageIcon;
case "组件消息":
return messageComponent;
case "普通对象消息":
return messageObject;
default:
return new Object[] { messageString, messageIcon, messageObject, messageComponent };
}
}

// 根据用户选择返回消息类型(决定图标区的图标)
private int getDialogType() {
switch (messageTypePanel.getSelection()) {
case "ERROR_MESSAGE":
return JOptionPane.ERROR_MESSAGE;
case "INFORMATION_MESSAGE":
return JOptionPane.INFORMATION_MESSAGE;
case "WARNING_MESSAGE":
return JOptionPane.WARNING_MESSAGE;
case "QUESTION_MESSAGE":
return JOptionPane.QUESTION_MESSAGE;
default:
return JOptionPane.PLAIN_MESSAGE;
}
}

private Object[] getOptions() {
switch (optionsPanel.getSelection()) {
case "字符串选项":
return new String[] { "a", "b", "c", "d" };
case "图标选项":
return new Icon[] { new ImageIcon("ico/1.gif"), new ImageIcon("ico/2.gif"), new ImageIcon("ico/3.gif"),
new ImageIcon("ico/4.gif") };
default:
return new Object[] { new Date(), new Date(), new Date() };
}
}

// 为各按钮定义事件监听器
private class ShowAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
switch (event.getActionCommand()) {
case "确认对话框":
JOptionPane.showConfirmDialog(jf, getMessage(), "确认对话框", getOptionType(), getDialogType());
break;
case "输入对话框":
if (inputPanel.getSelection().equals("单行文本框")) {
JOptionPane.showInputDialog(jf, getMessage(), "输入对话框", getDialogType());
} else {
JOptionPane.showInputDialog(jf, getMessage(), "输入对话框", getDialogType(), null,
new String[] { "轻量级Java EE企业应用实战", "疯狂Java讲义" }, "疯狂Java讲义");
}
break;
case "消息对话框":
JOptionPane.showMessageDialog(jf, getMessage(), "消息对话框", getDialogType());
break;
case "选项对话框":
JOptionPane.showOptionDialog(jf, getMessage(), "选项对话框", getOptionType(), getDialogType(), null,
getOptions(), "a");
break;
}
}
}

public static void main(String[] args) {
new JOptionPaneTest().init();
}
}

// 定义一个JPanel类扩展类,该类的对象包含多个纵向排列的
// JRadioButton控件,且Panel扩展类可以指定一个字符串作为TitledBorder
class ButtonPanel extends JPanel {
private ButtonGroup group;

public ButtonPanel(String title, String[] options) {
setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
group = new ButtonGroup();
for (int i = 0; options != null && i < options.length; i++) {
JRadioButton b = new JRadioButton(options[i]);
b.setActionCommand(options[i]);
add(b);
group.add(b);
b.setSelected(i == 0);
}
}

// 定义一个方法,用于返回用户选择的选项
public String getSelection() {
return group.getSelection().getActionCommand();
}
}

运行上面程序,会看到如图12.11所示的窗口。
这里有一张图片
图12.11已经非常清楚地显示了JOptionPane所支持的4种对话框,以及所有对话框的通用选项、每个对话框的特定选项。
读者可以通过运行上面程序来查看JOptionPane所创建的各种对话框.