JFrame未正确显示

时间:2012-09-08 17:47:45

标签: java swing user-interface jframe visitor

在我的客户端/服务器Java应用程序中,我发现了一个奇怪的行为,它阻止任何内容显示在JFrame中而不是第一个(登录一个)。

JFrame是diplayed,但它是透明的,如果我调整它,我有这个效果:

enter image description here

应用程序的工作原理如下(2个主要,1个在Server类中,1个在Client类中:

服务器端 1)main有一个无限循环,启动一个新线程来处理客户端连接它时的消息

客户端 1)main获取GuiLogin JDialog的单例,并执行一个方法来显示它

2)当用户按下Login时,guilogin中的ActionListener调用客户端方法将LoginRequest对象分派给Server,该对象使用LoginResponse对象进行回复

3)如果电子邮件和密码是正确的(email = a,password = b),它应该显示另一个JFrame,但无论我尝试什么,它总是显示错误的透明框架

3b)如果电子邮件和密码不正确,应用程序将显示JDialog(正常工作)

我认为我的错误是概念性的,代码看起来很好,我用

调用新的JFrame
   guiLogin.dispose();

   JFrame j = new JFrame();
   j.setVisible(true);

作为它的独立代码,但在客户端的访问者模式消息处理程序中的方法内,它的工作方式与截图相同

minified version of the eclipse project, stripped all the class and methods not concerning the bug

编辑:我对Java Gui& amp;事件,我现在检查导致问题的代码是在EDT内(javax.swing.SwingUtilities.isEventDispatchThread()返回true)。我应该在SwingWorker线程中移动整个消息处理逻辑吗?

1 个答案:

答案 0 :(得分:4)

您正在屏蔽Event Dispatch Thread (EDT)。以下是来自TinyClient的片段,该片段在EDT上执行:

do {
    System.out.println("waiting response");
    try {
        Response risp = (Response) in.readObject();
        risp.accept(resHandler);
    }
    catch (SocketException e) {
        // unhandled yet
    }
    Thread.sleep(500);
} while (waitForMessage);

在其中一个迭代in.readObject();上,呼叫被阻止。同样适用于Thread.Sleep。所有与UI相关的工作,例如绘画,都发生在EDT上。一旦EDT被阻止,它就不会处理任何事件。因此,您看到的结果 - UI不会重新绘制。

查看Concurrency in Swing了解更多详情。您可能希望采用多线程解决方案来处理网络。在同一个教程中查看SwingWorker。它允许在后台线程上执行任务并在EDT线程上传递结果。

编辑

由于您的申请的详细信息和规模不可用,因此很难给出具体的解决方案。请记住,Swing是单线程的。所有UI工作必须在EDT上完成。为了获得最佳性能,EDT上的所有任务都应该是简短的。网络应该在工作线程上处理。您有几个选项,例如SwingWorkerExecutorService或您自己的辅助线程。 SwingWorker有一个内置机制来推送EDT上的更新。如果是ExecutorService,您可以将SwingUtilities.invokeLater用于此目的。