如何让代码等待GUI完成?

时间:2014-04-09 10:19:39

标签: java eclipse multithreading swing user-interface

我知道有一个类似的问题与Matlab有关,但它对Java没有帮助。我正在为一个程序编写GUI,其中一个GUI框架的结果对于另一个GUI框架是必要的 - 我已将我的问题简化为以下内容:

我有一个带有 JFrame 的GUI JTextField ,当按下按钮时,会将该字段的内容作为字符串返回。

在静态main方法的下方,这个字符串用于其他方法 - 尽管在本演示中它只是放入一个print语句。

我遇到的问题是代码没有等待GUI的完成(也就是有人按下按钮并触发事件),然后继续下一个语句 - 因此在这个演示问题中它导致了#34 ;空"要打印,在我的大问题中,它会导致null传递给其他JFrame(并抛出异常)。

我在线学到的是,这是由于多线程" Swing的本质 - 每次我创建一个Swing组件时,它都会在自己的线程中运行,以使其余的代码能够继续 - 但在这种情况下,我不希望其余代码继续,我想(我可能错了)是所有其他线程等待当前的Swing线程完成并给出一个可以在程序中进一步使用的结果。

在点击GUI JButton之前,我可以使用哪些代码暂停代码?

我知道对此的一个解决方案是" nest"代码的 ActionListener 部分内的依赖代码,但在较大的项目中,这给了我大量的嵌套代码,这似乎不是一件好事。

主方法的演示问题代码在这里:

public class Testing {

public static void main(String[] args) {

    Testing runningClass = new Testing();
    String message = null;

    JGetString getString = new JGetString();
    message = runningClass.initiateListener(getString);

    System.out.println(message); // How can I make this wait until getString
                                    // has closed?

}

private String initiateListener(JGetString window) {
    buttonListener listener = new buttonListener(window);
    window.addActionListener(listener);
    return listener.returning;

}

public class buttonListener implements ActionListener {

    JGetString getString;
    String returning;

    public buttonListener(JGetString getString) {
        this.getString = getString;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String returning = getString.returnString();
        this.returning = returning;
        getString.setVisible(false);

    }

}

}

扩展 JFrame 的GUI代码在这里:

public class JGetString extends JFrame {
private JTextField textField;
private JButton btnGet = new JButton("Get");

public JGetString() {
    textField = new JTextField();
    getContentPane().add(textField, BorderLayout.CENTER);
    getContentPane().add(btnGet, BorderLayout.SOUTH);
    setVisible(true);
    pack();
}


public void addActionListener(ActionListener act) {
    btnGet.addActionListener(act);

}

public String returnString() {
    return textField.getText();
}


}

很抱歉这么长的问题和大块代码 - 谢谢!

1 个答案:

答案 0 :(得分:1)

正如Arvind在评论中已经指出的那样:当你想要等待GUI时常用的方法"是对话框。特别是模态对话框。可以使用JOptionPane的实用方法创建预定义的标准对话框。有关详细信息,请访问http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html

对话通常不是真正的窗口"。例如,它在任务栏中没有表示。如果你想创建一个真正的JFrame,并等待它被关闭,事情可能会变得有点繁琐:帧的创建实际上应该在事件派发线程上完成。

因此,为了找到合适的解决方案,您应该有一个真正清楚地了解哪个线程负责什么,以及哪个线程应该等待哪个其他线程在哪一点。

通过"职责",我指的是每个班级扮演的角色。例如:让ActionListener在这里发挥积极作用可能是一种可行(也可能更容易)的解决方案。 ActionListener可以调用主类中的方法,并将字符串传递给此方法。这将允许主线程和事件调度线程之间的轻松同步(可能,但最好不是synchronizedwait()notifyAll()

然而,另一个解决方案,其中ActionListener仍然是"被动",而实际的字符串仍然是从JGetString实例获得的,在这里勾画:它引入了一个{{ 1}}只封装Waiter的类,因此允许等待按下按钮。但是注意,根据您的长期目标以及您的计划背后的一般结构和意图,可能会有更合适的解决方案。

CountDownLatch