2012-09-08 90 views
2

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

JFrame中被diplayed,但它是透明的,如果我调整它的大小,我有这样的效果:

enter image description here

该应用程序是这样的(2主,1服务器级和1 Client类:

服务器端 1)主具有一个无限循环,开始一个新的线程,当客户端连接到它来处理消息

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

2)当用户按下Login时,guilogin中的ActionListener调用客户端方法来分派LoginRequest对象到服务器,用LoginResponse对象

3)如果电子邮件地址和密码是否正确(电子邮件= A,密码= b)中,它应该显示另一个JFrame的,但无论我尝试,它始终显示窃听 - 透明帧

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

我觉得我的错误是什么地方的概念,代码看起来正确的很好,我调用与

guiLogin.dispose(); 

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

,因为它的工作原理独立代码的新的JFrame,但客户在我的访问者模式的消息处理的方法中,它就像在截图

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

编辑:我对Java GUI中&事件非常缺乏经验,我现在检查发现造成问题的代码是EDT(javax.swing.SwingUtilities.isEventDispatchThread内()返回真)。我应该在SwingWorker线程中移动整个消息处理逻辑吗?

+0

它不起作用。 –

+0

该链接还是java项目?你必须同时启动服务器和客户端 – alessiop86

+3

似乎你要么阻止你的美国东部时间,要么你根本不使用它。我必须等到早上才能看到附加的代码,因为我无法在iPAD上查看它:( –

回答

4

您正在屏蔽Event Dispatch Thread (EDT)。下面是从TinyClient一个片段,它是在美国东部时间执行:

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); 

在迭代​​呼叫被封锁的一个。 Thread.Sleep也是如此。所有与用户界面相关的工作(例如绘画)都发生在EDT上。一旦EDT被阻止,它不会处理任何事件。因此,你看到的结果 - 用户界面不重新粉刷。

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

编辑

随着应用程序的细节和规模都无法访问,很难给出一个具体的解决方案。请记住,Swing是单线程的。所有UI工作必须在EDT上完成。为了获得最佳性能,EDT上的所有任务都应该简短。网络应该在工作者线程上处理。您有几个选项,如SwingWorkerExecutorService或您自己的辅助线程。 SwingWorker有一个内置的机制来推送EDT上的更新。在ExecutorService的情况下,您可以使用SwingUtilities.invokeLater用于此目的。

+0

当Gagandeep Bali暗示时,我已经在看这些美国东部时间教程了。编辑:我更新了我的问题 – alessiop86

+0

@mark请参阅我最近的更新。你也可以选择一个专用的'ExecutorService'。 – tenorsax

+0

我接受了答案,我认为从现在开始我可以弄清楚,我已经用SwingWorker修复了它,但是我仍然在调整它,因为doInBackground()不能成为void函数就像我希望 – alessiop86