在我的Client/Server Java应用程序中,我发现了一个奇怪的行为,它阻止任何内容在JFrame中显示,而不是第一个内容(登录内容)。
JFrame是显示的,但它是透明的,如果我调整它的大小,我会得到这样的效果:

应用程序的工作方式如下(2个main,1个在Server类中,1个在Client类中:
服务器端1) main有一个无限循环,当客户端连接到main时,启动一个新线程来处理消息
客户端1) main获取GuiLogin JDialog的单例,并执行一个方法进行显示
2)当用户按下Login时,guilogin中的ActionListener将调用客户端方法将LoginRequest对象分派到服务器,服务器将以LoginResponse对象进行响应
3)如果电子邮件和密码是正确的(email=a,password=b),它应该显示另一个JFrame,但无论我如何尝试,它总是显示错误透明的框架
3b)如果电子邮件和密码不正确,应用程序将显示JDialog (工作正常)
我想我的错误是在概念上的某个地方,代码看起来不错,我用以下命令调用新的JFrame
guiLogin.dispose();
JFrame j = new JFrame();
j.setVisible(true);作为独立的代码,它可以工作,但在客户机上的Visitor-pattern消息处理程序的方法中,它的工作方式与屏幕截图中的类似
minified version of the eclipse project, stripped all the class and methods not concerning the bug
编辑:我对Java Gui和事件缺乏经验,我现在检查了导致问题的代码是否在EDT中( javax.swing.SwingUtilities.isEventDispatchThread()返回true )。我应该将整个消息处理逻辑移到SwingWorker线程中吗?
发布于 2012-09-09 04:18:47
你屏蔽了Event Dispatch Thread (EDT)。下面是在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);在其中一次迭代中,in.readObject();调用被阻塞。Thread.Sleep也是如此。所有与UI相关的工作,比如绘画,都在EDT上进行。一旦EDT被阻塞,它就不会处理任何事件。因此,您看到的结果是: UI不会被重新绘制。
有关更多详细信息,请查看Concurrency in Swing。您可能希望采用多线程解决方案来处理网络。在同一教程中查看SwingWorker。它允许在后台线程上执行任务,并在EDT线程上传递结果。
编辑:
由于您的应用程序的细节和规模都不可用,因此很难给出具体的解决方案。请记住,Swing是单线程的。所有的UI工作必须在EDT上完成。为了获得最佳性能,EDT上的所有任务都应该简短。网络应该在工作线程上处理。您有几个选项,例如SwingWorker、ExecutorService或您自己的辅助线程。SwingWorker有一个内置的机制,可以在EDT上推送更新。在ExecutorService的情况下,您可以使用SwingUtilities.invokeLater来实现此目的。
https://stackoverflow.com/questions/12333078
复制相似问题