首次实例化后JFrame无法正常工作?

时间:2010-02-02 00:52:45

标签: java user-interface swing jframe instantiation

作为更大的应用程序的一部分,我正在编写一个设置类,它收集并存储用户定义的设置。此类是单例,并在应用程序启动期间实例化。

为了接受用户输入,在ConfigSettings.java中从公共静态方法selectSettings()中实现了两个不同的GUI框架。两者都是JFrame的子类。以下是文件选择对话框实例化的代码:

private void selectFile() {
    SelectFileGUI fileSelector = new SelectFileGUI();
    fileSelector.setVisible(true);
    synchronized(this) {
        try {
            wait();
        }   catch(Exception e) {
            e.printStackTrace();
        }
    }
    fileSelector.dispose();
}

这在最初运行应用程序时工作正常。但是,稍后用户可以改变他们选择的设置,包括选择新的源文件。这是通过再次调用selectSettings()完成的。

我遇到的问题是,任何后续再次实例化和显示这些GUI组件的尝试都会导致显示新的JFrame,但背景为灰色,并且没有显示任何按钮或其他组件。在调试时,我也无法直接创建SelectFileGUI的新实例。

可能导致这种行为的原因是什么?

4 个答案:

答案 0 :(得分:2)

我会检查你第二次调用它是否正在使用GUI线程或从你自己的一个线程调用。

在该方法的顶部,您可以测试它(AWT线程很容易通过名称识别)并让它抛出异常,因此开发人员知道不要在错误的线程上调用它 - 或者您可以阻止它们的线程并在工作线程中完成。

答案 1 :(得分:1)

我不知道造成这种行为的原因是什么,但在您的代码中,以下几乎不可能成为管理对话框的正确方法(详见下文):

fileSelector.setVisible(true);
    synchronized(this) {
        try {
            wait();
        }   catch(Exception e) {
            e.printStackTrace();
        }
    }
    fileSelector.dispose();

您希望对话框是模态的吗?

如果你想要它们是模态的,那么你只需要调用阻塞调用,就像你调用 JColorChooser.showDialog(...)方法一样,你的返回“值”是你的颜色/文件/不管。

如果你想要它们是非模态的,那么你使用回调来获取你的颜色/文件。在JColorChooser对话框示例中,您将调用createDialog(...)方法并使用ok / cancel侦听器作为回调。

我建议你看看sun的教程,例如关于颜色选择器的教程,看看如何正确显示模态(或非模态)对话框:

http://java.sun.com/docs/books/tutorial/uiswing/components/colorchooser.html

再一次, synchronized(this){try {wait()...} 来管理像文件选择器/对话框一样简单的东西是不正确的。

答案 2 :(得分:0)

同意BillK:听起来你是第一次从EDT以外的地方打电话给你(因此你对wait()的呼叫不会阻止EDT),然后第二次从EDT开始。请参阅SwingUtilities.invokeAndWait()和/或Dialog.setModal()

答案 3 :(得分:0)

这里的共识是你违反了管理AWT绘画线程(事件调度线程)使用的规则。
有几点需要注意:

  • 如果您的代码试图在此绘制线程之外绘制GUI组件,则灰色对话框可能是EDT与您的应用程序用于绘制的线程之间的死锁的结果。
  • 如果您遇到这种情况,您将无法按照描述创建新对话框。
  • 但是,正如您提到在遇到此问题时正在调试时,可能是您已通过IDE暂停了EDT。

查看this tutorial以获取有关如何在客户端应用程序中使用线程的一些指导原则。

要完全理解这个问题,很高兴看到selectSettings()的更多与代码相关的部分,例如。