首先,第二個窗口,允許用戶選擇動物類型的窗口不是作爲獨立的應用程序窗口,而是作爲與主窗口有關並依賴於主窗口的對話框。例如,你永遠不會自己顯示第二個窗口,而是隻顯示它來獲取指向主窗口/類的信息。因此它應該是一個對話框類型的窗口,可以是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