http://zetcode.com/tutorials/javaswingtutorial/swingdialogs/
对话框窗口或对话框是大多数现代 GUI 应用必不可少的部分。 对话被定义为两个或更多人之间的对话。 在计算机应用中,对话框是一个窗口,用于与应用“对话”。 对话框用于输入数据,修改数据,更改应用设置等。对话框是用户与计算机程序之间进行通信的重要手段。
在 Java Swing 中,我们可以创建两种对话框:标准对话框和自定义对话框。自定义对话框由程序员创建。 它们基于JDialog类。标准对话框是 Swing 工具箱中可用的预定义对话框,例如JColorChooser或JFileChooser。 这些是用于常见编程任务的对话框,例如显示文本,接收输入,加载和保存文件。 它们节省了程序员的时间,并增强了一些标准行为。
对话框有两种基本类型:模态对话框和非模态对话框。模态对话框阻止输入到其他顶级窗口。非模态对话框允许输入其他窗口。 打开文件对话框是模态对话框的一个很好的例子。 选择要打开的文件时,不应进行其他操作。 典型的非模态对话框是查找文本对话框。 能够在文本控件中移动光标并定义从何处开始查找特定文本很方便。
MessageDialog
消息对话框是向用户提供信息的简单对话框。 消息对话框是使用JOptionPane.showMessageDialog()方法创建的。
MessageDialogsEx.java
package com.zetcode;import javax.swing.GroupLayout;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import java.awt.EventQueue;import static javax.swing.GroupLayout.DEFAULT_SIZE;public class MessageDialogsEx extends JFrame {private JPanel pnl;public MessageDialogsEx() {initUI();}private void initUI() {pnl = (JPanel) getContentPane();var warBtn = new JButton("Warning");var errBtn = new JButton("Error");var queBtn = new JButton("Question");var infBtn = new JButton("Information");warBtn.addActionListener(event -> JOptionPane.showMessageDialog(pnl,"A deprecated call!", "Warning", JOptionPane.WARNING_MESSAGE));errBtn.addActionListener(event -> JOptionPane.showMessageDialog(pnl,"Could not open file!", "Error", JOptionPane.ERROR_MESSAGE));queBtn.addActionListener(event -> JOptionPane.showMessageDialog(pnl,"Are you sure to quit?", "Question", JOptionPane.QUESTION_MESSAGE));infBtn.addActionListener(event -> JOptionPane.showMessageDialog(pnl,"Download completed.", "Information",JOptionPane.INFORMATION_MESSAGE));createLayout(warBtn, errBtn, queBtn, infBtn);setTitle("Message dialogs");setSize(300, 200);setLocationRelativeTo(null);setDefaultCloseOperation(EXIT_ON_CLOSE);}private void createLayout(JComponent... arg) {var pane = getContentPane();var gl = new GroupLayout(pane);pane.setLayout(gl);gl.setAutoCreateGaps(true);gl.setHorizontalGroup(gl.createSequentialGroup().addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE).addGroup(gl.createParallelGroup().addComponent(arg[0]).addComponent(arg[2])).addGroup(gl.createParallelGroup().addComponent(arg[1]).addComponent(arg[3])).addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE));gl.setVerticalGroup(gl.createSequentialGroup().addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE).addGroup(gl.createParallelGroup().addComponent(arg[0]).addComponent(arg[1])).addGroup(gl.createParallelGroup().addComponent(arg[2]).addComponent(arg[3])).addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE));gl.linkSize(arg[0], arg[1], arg[2], arg[3]);pack();}public static void main(String[] args) {EventQueue.invokeLater(() -> {var md = new MessageDialogsEx();md.setVisible(true);});}}
该示例显示了错误,警告,问题和信息消息对话框。
var warBtn = new JButton("Warning");var errBtn = new JButton("Error");var queBtn = new JButton("Question");var infBtn = new JButton("Information");
这四个按钮显示四个不同的消息对话框。
errBtn.addActionListener(event -> JOptionPane.showMessageDialog(pnl,"Could not open file!", "Error", JOptionPane.ERROR_MESSAGE));
要创建消息对话框,我们调用JOptionPane类的静态showMessageDialog()方法。 我们提供对话框的父项,消息文本,标题和消息类型。 消息类型是以下常量之一:
ERROR_MESSAGEWARNING_MESSAGEQUESTION_MESSAGEINFORMATION_MESSAGE
显示的图标取决于此常数。

图:问题消息对话框
自定义对话框
在下面的示例中,我们创建一个简单的自定义对话框。 它是有关在许多 GUI 应用中找到的对话框的示例,通常位于“帮助”菜单中。
CustomDialogEx.java
package com.zetcode;import javax.swing.Box;import javax.swing.GroupLayout;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import java.awt.EventQueue;import java.awt.Font;import java.awt.Frame;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import static javax.swing.GroupLayout.Alignment.CENTER;class AboutDialog extends JDialog {public AboutDialog(Frame parent) {super(parent);initUI();}private void initUI() {var icon = new ImageIcon("src/resources/notes.png");var imgLabel = new JLabel(icon);var textLabel = new JLabel("Notes, 1.23");textLabel.setFont(new Font("Serif", Font.BOLD, 13));var okBtn = new JButton("OK");okBtn.addActionListener(event -> dispose());createLayout(textLabel, imgLabel, okBtn);setModalityType(ModalityType.APPLICATION_MODAL);setTitle("About Notes");setDefaultCloseOperation(DISPOSE_ON_CLOSE);setLocationRelativeTo(getParent());}private void createLayout(JComponent... arg) {var pane = getContentPane();var gl = new GroupLayout(pane);pane.setLayout(gl);gl.setAutoCreateContainerGaps(true);gl.setAutoCreateGaps(true);gl.setHorizontalGroup(gl.createParallelGroup(CENTER).addComponent(arg[0]).addComponent(arg[1]).addComponent(arg[2]).addGap(200));gl.setVerticalGroup(gl.createSequentialGroup().addGap(30).addComponent(arg[0]).addGap(20).addComponent(arg[1]).addGap(20).addComponent(arg[2]).addGap(30));pack();}}public class CustomDialogEx extends JFrameimplements ActionListener {public CustomDialogEx() {initUI();}private void initUI() {createMenuBar();setTitle("Simple Dialog");setSize(350, 250);setLocationRelativeTo(null);setDefaultCloseOperation(EXIT_ON_CLOSE);}private void createMenuBar() {var menubar = new JMenuBar();var fileMenu = new JMenu("File");fileMenu.setMnemonic(KeyEvent.VK_F);var helpMenu = new JMenu("Help");helpMenu.setMnemonic(KeyEvent.VK_H);var aboutMemuItem = new JMenuItem("About");aboutMemuItem.setMnemonic(KeyEvent.VK_A);helpMenu.add(aboutMemuItem);aboutMemuItem.addActionListener(this);menubar.add(fileMenu);menubar.add(Box.createGlue());menubar.add(helpMenu);setJMenuBar(menubar);}@Overridepublic void actionPerformed(ActionEvent e) {showAboutDialog();}private void showAboutDialog() {var aboutDialog = new AboutDialog(this);aboutDialog.setVisible(true);}public static void main(String[] args) {EventQueue.invokeLater(() -> {var ex = new CustomDialogEx();ex.setVisible(true);});}}
从“帮助”菜单中,我们可以弹出一个小对话框。 该对话框显示文本,图标和按钮。
class AboutDialog extends JDialog {
自定义对话框基于JDialog类。
setModalityType(ModalityType.APPLICATION_MODAL);
setModalityType()方法设置对话框的模态类型。 ModalityType.APPLICATION_MODAL阻止来自同一应用的所有顶级窗口的输入。 在我们的例子中,在对话框的生存期内,应用框架的输入被阻止。
setLocationRelativeTo(getParent());
setLocationRelativeTo()方法将对话框窗口居中在框架窗口的区域上方。
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setDefaultCloseOperation()设置用户单击窗口的“关闭”按钮时发生的情况。 该对话框将被隐藏和处置。
private void showAboutDialog() {var aboutDialog = new AboutDialog(this);aboutDialog.setVisible(true);}
对话框窗口使用setVisible()方法显示在屏幕上。

图:自定义对话框
JFileChooser
JFileChooser是用于从文件系统中选择文件的标准对话框。
FileChooserEx.java
package com.zetcode;import javax.swing.AbstractAction;import javax.swing.GroupLayout;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JToolBar;import javax.swing.filechooser.FileNameExtensionFilter;import java.awt.EventQueue;import java.awt.event.ActionEvent;import java.io.File;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import static javax.swing.GroupLayout.DEFAULT_SIZE;public class FileChooserEx extends JFrame {private JPanel panel;private JTextArea area;public FileChooserEx() {initUI();}private void initUI() {panel = (JPanel) getContentPane();area = new JTextArea();var spane = new JScrollPane();spane.getViewport().add(area);var toolbar = createToolBar();createLayout(toolbar, spane);setTitle("JFileChooser");setSize(400, 300);setLocationRelativeTo(null);setDefaultCloseOperation(EXIT_ON_CLOSE);}private JToolBar createToolBar() {var openIcon = new ImageIcon("src/resources/document-open.png");var toolbar = new JToolBar();var openBtn = new JButton(openIcon);openBtn.addActionListener(new OpenFileAction());toolbar.add(openBtn);return toolbar;}private void createLayout(JComponent... arg) {var pane = getContentPane();var gl = new GroupLayout(pane);pane.setLayout(gl);gl.setHorizontalGroup(gl.createParallelGroup().addComponent(arg[0], DEFAULT_SIZE, DEFAULT_SIZE,Short.MAX_VALUE).addGroup(gl.createSequentialGroup().addComponent(arg[1])));gl.setVerticalGroup(gl.createSequentialGroup().addComponent(arg[0]).addGap(4).addComponent(arg[1]));pack();}public String readFile(File file) {String content = "";try {content = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));} catch (IOException ex) {JOptionPane.showMessageDialog(this,"Could not read file", "Error", JOptionPane.ERROR_MESSAGE);}return content;}private class OpenFileAction extends AbstractAction {@Overridepublic void actionPerformed(ActionEvent e) {var fileChooser = new JFileChooser();var filter = new FileNameExtensionFilter("Java files", "java");fileChooser.addChoosableFileFilter(filter);int ret = fileChooser.showDialog(panel, "Open file");if (ret == JFileChooser.APPROVE_OPTION) {var file = fileChooser.getSelectedFile();var text = readFile(file);area.setText(text);}}}public static void main(String[] args) {EventQueue.invokeLater(() -> {var ex = new FileChooserEx();ex.setVisible(true);});}}
该代码示例将演示如何使用JFileChooser将文件内容加载到文本区域组件中。
var fileChooser = new JFileChooser();
这是文件选择器对话框的构造器。
var filter = new FileNameExtensionFilter("Java files", "java");fileChooser.addChoosableFileFilter(filter);
在这里,我们定义文件过滤器。 在本例中,我们将具有扩展名为.java的 Java 文件。 我们还有默认的“所有文件”选项。
int ret = fileChooser.showDialog(panel, "Open file");
showDialog()方法在屏幕上显示对话框。 单击“是”或“确定”按钮时,将返回JFileChooser.APPROVE_OPTION。
if (ret == JFileChooser.APPROVE_OPTION) {var file = fileChooser.getSelectedFile();var text = readFile(file);area.setText(text);}
在这里,我们获得所选文件的名称。 我们读取文件的内容并将文本设置到文本区域中。

图:JFileChooser对话框
JColorChooser
JColorChooser是用于选择颜色的标准对话框。
ColorChooserEx.java
package com.zetcode;import javax.swing.GroupLayout;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JColorChooser;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JToolBar;import java.awt.Color;import java.awt.EventQueue;import static javax.swing.GroupLayout.DEFAULT_SIZE;public class ColorChooserEx extends JFrame {private JPanel colourPanel;public ColorChooserEx() {initUI();}private void initUI() {colourPanel = new JPanel();colourPanel.setBackground(Color.WHITE);var toolbar = createToolBar();createLayout(toolbar, colourPanel);setTitle("JColorChooser");setSize(400, 300);setLocationRelativeTo(null);setDefaultCloseOperation(EXIT_ON_CLOSE);}private JToolBar createToolBar() {var openIcon = new ImageIcon("src/resources/colourdlg.png");var toolbar = new JToolBar();var openBtn = new JButton(openIcon);openBtn.addActionListener(e -> {var color = JColorChooser.showDialog(colourPanel,"Choose colour", Color.white);colourPanel.setBackground(color);});toolbar.add(openBtn);return toolbar;}private void createLayout(JComponent... arg) {var pane = getContentPane();var gl = new GroupLayout(pane);pane.setLayout(gl);gl.setHorizontalGroup(gl.createParallelGroup().addComponent(arg[0], DEFAULT_SIZE, DEFAULT_SIZE,Short.MAX_VALUE).addGroup(gl.createSequentialGroup().addGap(30).addComponent(arg[1]).addGap(30)));gl.setVerticalGroup(gl.createSequentialGroup().addComponent(arg[0]).addGap(30).addComponent(arg[1]).addGap(30));pack();}public static void main(String[] args) {EventQueue.invokeLater(() -> {var ex = new ColorChooserEx();ex.setVisible(true);});}}
在示例中,我们有一个白色面板。 我们将通过从JColorChooser中选择一种颜色来更改面板的背景颜色。
var color = JColorChooser.showDialog(colourPanel,"Choose colour", Color.white);colourPanel.setBackground(color);
此代码显示颜色选择器对话框。 showDialog()方法返回所选的颜色值。 我们将colourPanel's背景更改为新选择的颜色。
在 Java Swing 教程的这一部分中,我们介绍了对话框。
