第14章 窗口和对话框

14章 窗口和对话框

  Swing的窗口(window)、窗体(frame)和对话框(dialog)是分别扩展AWTwindowFrame类和Dialog类的重量组件。当这三个组件都是窗口时,这三个组件之间的差别是不明显的,因此,有时在给定情况下要确定使用哪个组件是很困难的。为了澄清这些差别,表14-1列出了与这三个组件有关的一些属性。

        表14-1 窗口、窗体和对话框属性①,②
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  属性     窗口   窗体     对话框
  ─────────────────────────────────
  模态      否    否     否/CSG
  可调整大小   否    否/SG    是/SG
  标题栏     否    是      是
  边框      否    是      是
  标题      否    是/CSG    是/CSG
  菜单栏     否    是/SG    否
  焦点管理器   是    是      是
  警告字符串   是/G   是/G     是/G
  图标图像   否    是/SG    否
  链接到一个窗体  是   否      是
  ─────────────────────────────────
  /否指缺省的属性状态
  ②C=在构造时可设置,S=可使用的设置方法,G=可使用的获取方法(即get...()is...())
  不是所有的平台都支持窗口的图标化。

  窗口是这三个组件中最基本的组件,事实上,java.awt.WindowFrameDialog的超类。窗口没有边框、标题栏或菜单栏,而且不能调整其大小。如果需要在其他组件之上的无边框矩形区域中显示某些内容,则窗口是最合适的。

14.1 JWindow

14-1 使用JWindow来实现一个splash窗口

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// This has been modified from the code in the book
// to display the animated swing.gif in a window in the corner
// of your desktop. A double click closes the window.

public class Test extends JFrame {
Toolkit toolkit = Toolkit.getDefaultToolkit();
JWindow window = new JWindow();
JLabel label = new JLabel(new ImageIcon("swing.gif"));

static public void main(String[] args) {
JFrame frame = new Test();
}
public Test() {
//label.setBorder(BorderFactory.createRaisedBevelBorder());
window.getContentPane().add(label, "Center");
//centerWindow();
// change location to suite taste ...
window.setLocation(75,10);
window.pack();
window.show();

window.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(e.getClickCount() == 2) {
window.dispose();
System.exit(0);
}
}
});
}
private void centerWindow() {
Dimension scrnSize = toolkit.getScreenSize();
Dimension labelSize = label.getPreferredSize();
int labelWidth = labelSize.width,
labelHeight = labelSize.height;

window.setLocation(scrnSize.width/2 - (labelWidth/2),
scrnSize.height/2 - (labelHeight/2));
window.pack();
}
}

14-2 一个作为应用程序窗口使用的JWindow实例

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
JWindow window = new JWindow();
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem quitItem;

public Test() {
final Container contentPane = getContentPane();
JButton button = new JButton("show window ...");

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

fileMenu.add("New");
fileMenu.add("Open ...");
fileMenu.add("Save");
fileMenu.add("Save As ...");
fileMenu.addSeparator();
fileMenu.add(quitItem = new JMenuItem("Quit"));

menuBar.add(fileMenu);

window.getRootPane().setJMenuBar(menuBar);
window.getRootPane().setBorder(
BorderFactory.createRaisedBevelBorder());

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Point pt = contentPane.getLocation();

SwingUtilities.convertPointToScreen(
pt, contentPane);

window.setBounds(pt.x + 10, pt.y + 10, 200, 200);
window.show();

quitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
window.dispose();
}
});
}
});
}
}

 

14.1.1 JWindow属性

 

14.1.2 JWindow类总结

 

14.1.3 AWT兼容

 

14.2 JDialog

 

14-3 运行中的JDialog

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private ConstraintsPanel cp = new ConstraintsPanel();
private JPanel buttonsPanel = new JPanel();

private JButton showButton = new JButton("show dialog ..."),
okButton = new JButton("OK"),
applyButton = new JButton("Apply"),
cancelButton = new JButton("Cancel");

private JButton[] buttons = new JButton[] {
okButton, applyButton, cancelButton,
};

private JDialog dialog = new JDialog(null, // owner
"Constraints Dialog", // title
true); // modal

public Test() {
Container contentPane = getContentPane();
Container dialogContentPane = dialog.getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(showButton);

dialogContentPane.add(cp, BorderLayout.CENTER);
dialogContentPane.add(buttonsPanel, BorderLayout.SOUTH);
dialog.pack();

// setLocationRelativeTo must be called after pack(),
// because dialog placement is based on dialog size.
// Because the applet is not yet showing, calling
// setLocationRelativeTo() here causes the dialog to be
// shown centered on the screen.
//
// If setLocationRelativeTo() is not invoked, the dialog
// will be located at (0,0) in screen coordinates.
//dialog.setLocationRelativeTo(this);

for(int i=0; i < buttons.length; ++i) {
buttonsPanel.add(buttons[i]);
}
addButtonListeners();
}
private void addButtonListeners() {
showButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// calling setLocationRelativeTo() here causes
// the dialog ito be centered over the applet.
dialog.setLocationRelativeTo(Test.this);
dialog.show();
}
});
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus("OK button Activated");
dialog.dispose();
}
});
applyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus("Apply button Activated");
}
});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus("Cancel button Activated");
dialog.dispose();
}
});
}
}

14.2.1 JDialog属性

 

14.2.2 JDialog类总结

 

14.2.3 AWT兼容

 

14.3 JOptionPane

 

14-4 JOptionPane创建对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton topButton = new JButton(
"show dialog created from option pane");
private JButton bottomButton = new JButton(
"show dialog created with static method");

private String title = "dialog title";
private String message = "message";

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(topButton);
contentPane.add(bottomButton);

topButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane optionPane = new JOptionPane(
message, // message
JOptionPane.INFORMATION_MESSAGE); // messageType

JDialog dialog = optionPane.createDialog(
topButton, // parentComponent
title); // title

dialog.show();
}
});
bottomButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(
bottomButton, // parentComponent
message, // message
title, // title
JOptionPane.INFORMATION_MESSAGE); // messageType
}
});
}
}

14.3.1 内部窗体

 

14-5 JOptionPane创建内部窗体

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show internal frame");

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showInternalMessageDialog(
button, // parentComponent
"Break Time ...", // message
"Reminder!", // title
JOptionPane.INFORMATION_MESSAGE); // messageType
}
});
}
}

14.3.2 JOptionPane静态方法创建对话框

 

14.3.3 消息对话框

 

14-6 显示具有不同消息类型的消息对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "dialog title";
private String message = "information";
private int messageType = JOptionPane.INFORMATION_MESSAGE;
private String messages[] = {
"information", "error", "warning", "question", "plain"
};

public Test() {
Container contentPane = getContentPane();
JPanel controlPanel = new ControlPanel(this);

contentPane.setLayout(new FlowLayout());
contentPane.add(controlPanel);
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(
button, // parentComponent
message, // message
title, // title
messageType);
}
});
}
public void setMessageType(int messageType) {
this.messageType = messageType;

switch(messageType) {
case JOptionPane.INFORMATION_MESSAGE:
message = messages[0];
break;
case JOptionPane.ERROR_MESSAGE:
message = messages[1];
break;
case JOptionPane.WARNING_MESSAGE:
message = messages[2];
break;
case JOptionPane.QUESTION_MESSAGE:
message = messages[3];
break;
case JOptionPane.PLAIN_MESSAGE:
message = messages[4];
break;
}
}
}
class ControlPanel extends JPanel {
private JComboBox messageTypes = new JComboBox();
private int[] typeValues = {
JOptionPane.INFORMATION_MESSAGE,
JOptionPane.ERROR_MESSAGE,
JOptionPane.WARNING_MESSAGE,
JOptionPane.QUESTION_MESSAGE,
JOptionPane.PLAIN_MESSAGE,
};
private String[] typeNames = {
"JOptionPane.INFORMATION_MESSAGE",
"JOptionPane.ERROR_MESSAGE",
"JOptionPane.WARNING_MESSAGE",
"JOptionPane.QUESTION_MESSAGE",
"JOptionPane.PLAIN_MESSAGE",
};

public ControlPanel(final Test applet) {
add(messageTypes);

for(int i=0; i < typeNames.length; ++i) {
messageTypes.addItem(typeNames[i]);
}
messageTypes.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
String s = (String)messageTypes.getSelectedItem();
int type;

for(int i=0; i < typeNames.length; ++i) {
if(s.equals(typeNames[i]))
applet.setMessageType(typeValues[i]);
}
}
});
}
}

14-7 替换消息对话框的缺省图标

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "Reminder!";
private String message = "Dinner time";

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(
button, // parentComponent
message, // message
title, // title
JOptionPane.INFORMATION_MESSAGE,// messageType
new ImageIcon("dining.gif")); // icon
}
});
}
}

 

14.3.4 确认对话框

 

14-8 使用确认对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "Unsaved Changes";
private String message[] = {
"Unsaved Changes in File: dialog.fm",
" ",
"Save before closing?",
" ",
};

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(
button, // parentComponent
message, // message
title, // title
JOptionPane.YES_NO_CANCEL_OPTION, // optionType
JOptionPane.WARNING_MESSAGE, // messageType
new ImageIcon("punch.gif")); // icon

switch(result) {
case JOptionPane.CLOSED_OPTION:
showStatus("Dialog Closed");
break;
case JOptionPane.YES_OPTION:
showStatus("Yes");
break;
case JOptionPane.NO_OPTION:
showStatus("No");
break;
case JOptionPane.CANCEL_OPTION:
showStatus("Cancel");
break;
}
}
});
}
}

14.3.5 输入对话框

 

14-9 有文本域的输入对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");
private String message = "Please Enter Your Name";

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = JOptionPane.showInputDialog(message);

if(s == null)
showStatus("cancel button activated");
else
showStatus("Name: " + s);
}
});
}
}

14-10 有组合框的输入对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "Animal Selection Dialog";
private String message = "Select your favorite animal:";
private String[] selectionValues = {
"dog", "cat", "mouse", "goat", "koala", "rabbit",
};

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = (String)JOptionPane.showInputDialog(
Test.this, // parentComponent
message, // message
title, // title
JOptionPane.QUESTION_MESSAGE, // messageType
null, // icon
selectionValues, // selectionValues
selectionValues[3]); // initialValue

if(s == null)
showStatus("cancel button activated");
else
showStatus(s);
}
});
}
}

14-11 带列表的输入对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "Animal Selection Dialog";
private String message = "Select your favorite animal:";
private Object[] selectionValues = {
"dog", "cat", "mouse", "goat", "koala", "rabbit",
"mouse", "horse", "kangaroo", "iguana", "tiger", "lion",
"eagle", "vulture", "wolf", "coyote", "owl", "snake",
"shrew", "zebra", "wildebeast"
};

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = (String)JOptionPane.showInputDialog(
Test.this, // parentComponent
message, // message
title, // title
JOptionPane.QUESTION_MESSAGE, // messageType
null, // icon
selectionValues, // selectionValues
selectionValues[3]); // initialValue

if(s == null)
showStatus("cancel button activated");
else
showStatus(s);
}
});
}
}

 

14.3.6 选项对话框

 

14-12 使用一个选项对话框

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");
private JButton applyButton = new JButton("Apply");
private RotatePanel rotatePanel = new RotatePanel();
private String title = "Rotate";
private Object[] buttonRowObjects = new Object[] {
"Ok",
applyButton,
"Cancel",
};

public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

applyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus(rotatePanel.getSelectedAngle() +
" degrees");
}
});
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int value = JOptionPane.showOptionDialog(
button, // parentComponent
rotatePanel, // message
title, // title
JOptionPane.DEFAULT_OPTION, // optionType
JOptionPane.PLAIN_MESSAGE, // messageType
null, // icon
buttonRowObjects, // options
applyButton); // initialValue

switch(value) {
case JOptionPane.CLOSED_OPTION:
showStatus(
"Dialog closed with close box");
break;
case JOptionPane.OK_OPTION:
showStatus("Ok button activated: " +
rotatePanel.getSelectedAngle() +
" degrees");
break;
case JOptionPane.CANCEL_OPTION:
showStatus("Cancel button activated");
break;
}
}
});
}
}
class RotatePanel extends JPanel {
private ButtonGroup group = new ButtonGroup();

private JRadioButton[] buttons = {
new JRadioButton("0"),
new JRadioButton("90"),
new JRadioButton("180"),
new JRadioButton("270"),
};
public RotatePanel() {
setBorder(BorderFactory.createTitledBorder("Angle:"));

for(int i=0; i < buttons.length; ++i) {
if(i ==0)
buttons[i].setSelected(true);

add(buttons[i]);
group.add(buttons[i]);
}
}
public String getSelectedAngle() {
String rv = null; // rv = return value

for(int i=0; i < buttons.length; ++i) {
if(buttons[i].isSelected())
rv = buttons[i].getText();
}
return rv;
}
}

14.3.7 JOptionPane属性

 

14.3.8 JOptionPane事件

 

14-13 监听从选项窗格激发的 PropertyChangeEvents

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;

public class Test extends JApplet {
private JButton button = new JButton("show dialog ...");

private String title = "Update References";
private JPanel messagePanel = new JPanel();
private JCheckBox[] checkBoxes = {
new JCheckBox("All Cross-References"),
new JCheckBox("Text Insets Marked for Manual Update"),
new JCheckBox("Text Insets Marked for Automatic Update"),
new JCheckBox("OLE Links Marked for Manual Update"),
new JCheckBox("OLE Links Marked for Automatic Update"),
};

public Test() {
Container contentPane = getContentPane();

messagePanel.setBorder(
BorderFactory.createTitledBorder("Update:"));

messagePanel.setLayout(new BoxLayout(messagePanel,
BoxLayout.Y_AXIS));

for(int i=0; i < checkBoxes.length; ++i)
messagePanel.add(checkBoxes[i]);

final JOptionPane pane = new JOptionPane(
messagePanel, // message
JOptionPane.QUESTION_MESSAGE, // messageType
JOptionPane.OK_CANCEL_OPTION); // optionType

contentPane.setLayout(new FlowLayout());
contentPane.add(button);

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JDialog dialog = pane.createDialog(
Test.this, // parentComponent
title); // title

dialog.show(); // blocks

Integer value = (Integer)pane.getValue();

if(value.intValue() == JOptionPane.OK_OPTION)
updateReferences();
else
showStatus("dialog canceled");
}
});
pane.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String name = e.getPropertyName();

if(name.equals(JOptionPane.VALUE_PROPERTY))
System.out.println(name + ":" + e.getNewValue());
}
});
}
private void updateReferences() {
showStatus("updating references");
}
}

14.3.9 JOptionPane类总结

 

14-14 构造各种配置的选项窗格

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
Object[] objects = new Object[] {
new JLabel("JOptionPane(Object message)",
new ImageIcon("beach_umbrella.gif"),
JLabel.LEFT),
new JCheckBox("check me out"),
new VerboseObject(),
};
Object[] objects2 = new Object[] {
"JOptionPane(Object message, int messageType)",
"messageType = JOptionPane.INFORMATION_MESSAGE",
};
Object[] objects3 = new Object[] {
"JOptionPane(Object message, " +
"int messageType, int optionsType)",
"messageType = JOptionPane.QUESTION_MESSAGE",
"optionType = JOptionPane.YES_NO_CANCEL_OPTION",
};
Object[] objects4 = new Object[] {
"JOptionPane(Object message, " +
"int messageType, int optionsType, Icon icon)",
"messageType = JOptionPane.WARNING_MESSAGE",
"optionType = JOptionPane.OK_CANCEL_OPTION",
"icon = new ImageIcon(/"ballot_box.gif/")",
};
Object[] objects5 = new Object[] {
"JOptionPane(Object message, " +
"int messageType, int optionsType, Icon icon)",
"messageType = JOptionPane.ERROR_MESSAGE",
"optionType = JOptionPane.OK_CANCEL_OPTION",
"icon = null",
"options = /"button 1/", /"button 2/", " +
"new JButton(/"button 3/")",
};

JOptionPane defaultPane = new JOptionPane();

JOptionPane messagePane = new JOptionPane(
"JOptionPane(Object message)");

JOptionPane objectPane = new JOptionPane(objects);

JOptionPane messageTypePane = new JOptionPane(
objects2, JOptionPane.INFORMATION_MESSAGE);

JOptionPane messageAndOptionTypePane = new JOptionPane(
objects3, JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_CANCEL_OPTION);

JOptionPane messageOptionAndIconPane = new JOptionPane(
objects4, JOptionPane.WARNING_MESSAGE,
JOptionPane.OK_CANCEL_OPTION,
new ImageIcon("ballot_box.gif"));

Object[] options = {
"button 1", "button 2", new JButton("button 3"),
};
JOptionPane messageOptionIconAndOptionsPane =
new JOptionPane(
objects5, JOptionPane.ERROR_MESSAGE,
JOptionPane.OK_CANCEL_OPTION,
null,
options,
options[2]);

contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.Y_AXIS));
contentPane.add(defaultPane);
contentPane.add(new JSeparator());
contentPane.add(messagePane);
contentPane.add(new JSeparator());
contentPane.add(objectPane);
contentPane.add(new JSeparator());
contentPane.add(messageTypePane);
contentPane.add(new JSeparator());
contentPane.add(messageAndOptionTypePane);
contentPane.add(new JSeparator());
contentPane.add(messageOptionAndIconPane);
contentPane.add(new JSeparator());
contentPane.add(messageOptionIconAndOptionsPane);
}
}
class VerboseObject extends Object {
public String toString() {
return "This is what you'll see in the option pane";
}
}

14.3.10 AWT兼容

 

14.4 本章回顾

 

  略

 

 

上一篇:LeetCode—628. 三个数的最大乘积(Maximum Product of Three Numbers)——分析及代码(Java)


下一篇:Codeforces Round #695 (Div. 2) C. Three Bags