首先,第二个窗口,允许用户选择动物类型的窗口不是作为独立的应用程序窗口,而是作为与主窗口有关并依赖于主窗口的对话框。例如,你永远不会自己显示第二个窗口,而是只显示它来获取指向主窗口/类的信息。因此它应该是一个对话框类型的窗口,可以是JOptionPane,也可以是模态JDialog,而不是JFrame。这还有其他几个优点,包括确保它保持在主窗口的前方,并且在处理完后不会关闭整个应用程序。
关于setVisible(true/false),这应该工作得很好。
关于从第二个窗口/对话框中提取动物类型信息:如果您将第二个窗口称为模态JDialog或JOptionPane(这实际上是一种专门的模态JDialog),您将确切知道用户何时完成其工作在第二个窗口中,因为主窗口的代码将在第二个窗口中称为setVisible(true)的位置之后启动,或称为JOptionPane.showXXXX()。在这一点上,你可以通过给第二个窗口/类一个公共方法来请求第二个窗口的动物类型,比如getAnimalType(),它返回这个信息。
例如,这里有一个双窗口的程序,证明是一个使用GridBagLayout的,并在JOptionPane中接受两个JTextField的文本一个JPanel:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TwoWindowEg {
private static void createAndShowUI() {
JFrame frame = new JFrame("Two Window Eg");
frame.getContentPane().add(new MainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MainPanel extends JPanel {
private JTextField textField = new JTextField(20);
private DialogPanel dialogPanel = null;
public MainPanel() {
textField.setEditable(false);
textField.setFocusable(false);
textField.setBackground(Color.white);
JButton openDialogBtn = new JButton("Open Dialog");
openDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (dialogPanel == null) {
dialogPanel = new DialogPanel();
}
int result = JOptionPane.showConfirmDialog(MainPanel.this, dialogPanel,
"Enter First and Last Name", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
String text = dialogPanel.getText();
textField.setText(text);
}
}
});
add(textField);
add(openDialogBtn);
setPreferredSize(new Dimension(400, 300));
setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
}
}
class DialogPanel extends JPanel {
private static final Insets INSETS = new Insets(0, 10, 0, 10);
private JTextField firstNameField = new JTextField(10);
private JTextField lastNameField = new JTextField(10);
public DialogPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
INSETS, 0, 0);
add(new JLabel("First Name"), gbc);
gbc = new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.LINE_END, GridBagConstraints.BOTH,
INSETS, 0, 0);
add(new JLabel("Last Name"), gbc);
gbc = new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL,
INSETS, 0, 0);
add(firstNameField, gbc);
gbc = new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0,
GridBagConstraints.LINE_END, GridBagConstraints.HORIZONTAL,
INSETS, 0, 0);
add(lastNameField, gbc);
}
public String getText() {
return firstNameField.getText() + " " + lastNameField.getText();
}
}
如果我理解你很好,是我应该创建一个类,扩展JDialog而不是JFrame,或者在动作监听器中,我应该创建一个JDialog并从那里使用它?另一个问题是我创建动物的第一个窗口有点复杂。它包含组合框,复选框,面板等。这就是为什么我使用了JFrame。这对于JDialog来说可能吗? – mkab 2011-04-09 18:56:48
@mkab:显示在JFrame中的任何类型的复杂GUI都可以显示在一个JDialog中。对于这个问题,您可以在JOptionPanes中显示复杂的GUI,因为JOptionPane的show方法的第二个参数(接受对象的那个参数)可以是任何Swing组件。例如,请参阅上面我在编辑中添加的代码以回答我的答案。 – 2011-04-09 18:58:40
哇,我现在明白了。我总是使用默认的JOptionPane.showXXX对话框来确认用户是否想要退出应用程序,或者如果用户想保存他的工作。我从来没有想过它可以定制为包含更复杂的GUI,因为对于组件参数,我只是把null。感谢您的帮助和见解。干杯。 – mkab 2011-04-09 19:08:12