JAVA有调用方法等待JFrame中的活动完成

时间:2015-08-06 15:11:49

标签: java swing

目前我正在调用一个方法(showFrames),它弹出一个包含许多可编辑文本字段的JFrame。我将这些文本字段的值存储在我需要在调用方法中使用的列表(editedFields)中。我的问题是我的调用方法不是等待用户在继续之前选择ok / cancel,所以当我尝试对其执行操作时未填充列表。我试图通过使用模态对话框来解决这个问题无济于事。这个方法在这里被调用......

...
showFrames(longToShortNameMap);
if (editedFields != null) {
     for (JTextField field : editedFields) {
          System.out.println(field.getText());
     }
}
...

并且showFrames方法实现为:

private static void showFrames(Map<String, String> longToShortNameMap) {
    final ToolDialog frame = new ToolDialog("Data Changed");
    frame.setVisible(true);
    frame.setModal(true);
    frame.setLayout(new BorderLayout());
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setSize(400, 500);
    frame.setResizable(true);
    frame.setLocationRelativeTo(null);

    JPanel panel = new JPanel(new GridLayout(0, 2));
    JPanel buttonPanel = new JPanel(new GridLayout(2, 0));
    List<String> keys = new ArrayList(longToShortNameMap.keySet());
    final List<JTextField> textFields = new ArrayList<>();
    for (String key : keys) {
        JLabel label = new JLabel(key);
        JTextField textField = new JTextField(longToShortNameMap.get(key));
        panel.add(label);
        panel.add(textField);
        textFields.add(textField);
    }
    JButton okButton = new JButton("OK"); //added for ok button
    okButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            editedFields = textFields;
            frame.setVisible(false);
            frame.dispose();

        }
    });
    JButton cancelButton = new JButton("Cancel");//added for cancel button
    cancelButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            frame.setVisible(false);
            frame.dispose();

        }
    });
    okButton.setVisible(true);//added for ok button
    cancelButton.setVisible(true);//added for cancel button
    buttonPanel.add(okButton);//added for ok button
    buttonPanel.add(cancelButton);//added for cancel button
    JScrollPane scrollPane = new JScrollPane(panel);

    scrollPane.setVisible(true);
    scrollPane.setSize(500, 500);
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.add(buttonPanel, BorderLayout.SOUTH);
}

我观察到的当前行为是,当JFrame弹出时,所有字段将立即打印出来而不是等待用户点击&#34; OK&#34;。实际上,这意味着我在文本字段中接收默认值而不是编辑的值。

注意:ToolDialog扩展了JDialog

2 个答案:

答案 0 :(得分:2)

您遇到的基本问题是您首先实例化Dialog,使其可见,然后向其中添加字段。

这实际上是不正确的。在实例化Frame / Dialog时,最好在构造函数调用中添加所有对象。然后,当一切准备就绪时,你可以看到它。

当然,您可以在显示之后向框架添加新字段,但这通常是基于某些事件完成的,例如,当用户点击&#34;添加新数字&#34;,然后您添加新的文本字段等。

因此,对您的修复很简单,将按钮,列表,面板等添加到构造函数的逻辑移动,然后使该窗口可见。

答案 1 :(得分:1)

这里有两个不同的问题:

  1. 等待对话。
  2. 正确显示对话框。
  3. 1.-等待对话。

    您应该使用JDialog 而不是JFrame 来制作窗口模态。

    窗口不是模态的,因为在将其设置为模态之前显示它。见JDialog.setModal

      

    注意:更改可见对话框的模态可能无效   它被隐藏然后再次显示。

    你需要切换两行:

    frame.setVisible(true);
    frame.setModal(true);
    

    另一种方法是与倒计时锁存器同步:

    CountDownLatch latch = new CountDownLatch(1);
    .......
    showFrames(longToShortNameMap);
    latch.await(); // suspends thread util dialog calls latch.countDown
    if (editedFields != null) {
    .......
    /// Dialog code
    latch.countDown(); // place it everywhere you are done with the dialog.
    dispose();
    

    2.-正确显示对话框。

    frame.setVisible(true)作为showFrames的最后一行。