Java JFrame未正确显示
在我的客户机/服务器Java应用程序中,我发现了一个奇怪的行为,它阻止任何内容在JFrame中显示,而不是第一个(登录) JFrame是diplayed,但它是透明的,如果我调整它的大小,就会产生以下效果: 应用程序的工作原理如下(2个主类,1个服务器类,1个客户端类: 服务器端 1) main有一个无限循环,当客户端连接到它时,启动一个新线程来处理消息 客户端 1) main获取guiloginjdialog的单例,并执行一个方法来显示它 2) 当用户按Login时,guilogin中的ActionListener会调用客户端方法将LoginRequest对象分派给服务器,服务器将使用LoginResponse对象进行响应 3) 如果电子邮件和密码是正确的(email=a,password=b),它应该显示另一个JFrame,但是不管我怎么做,它总是显示被窃听的透明框架 3b)如果电子邮件和密码不正确,应用程序将显示JDialog(正常工作) 我认为我的错误是概念性的,代码看起来很好,我用Java JFrame未正确显示,java,swing,user-interface,jframe,visitor,Java,Swing,User Interface,Jframe,Visitor,在我的客户机/服务器Java应用程序中,我发现了一个奇怪的行为,它阻止任何内容在JFrame中显示,而不是第一个(登录) JFrame是diplayed,但它是透明的,如果我调整它的大小,就会产生以下效果: 应用程序的工作原理如下(2个主类,1个服务器类,1个客户端类: 服务器端 1) main有一个无限循环,当客户端连接到它时,启动一个新线程来处理消息 客户端 1) main获取guiloginjdialog的单例,并执行一个方法来显示它 2) 当用户按Login时,guilogin中的Ac
guiLogin.dispose();
JFrame j = new JFrame();
j.setVisible(true);
作为独立代码,它可以工作,但在客户端上我的访问者模式消息处理程序的方法中,它的工作方式与屏幕截图中的类似
编辑:我对Java Gui和事件非常缺乏经验,我现在检查导致问题的代码是否在EDT中(javax.swing.SwingUtilities.isEventDispatchThread()返回true)。我应该在SwingWorker线程中移动整个消息处理逻辑吗?您正在阻止
事件调度线程(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);
在.readObject()中的一次迭代中代码>呼叫被阻止。线程也是如此。Sleep
。所有与UI相关的工作,如绘制,都在EDT上进行。一旦EDT被阻止,它就不会处理任何事件。因此,您看到的结果是,UI没有重新绘制
请查看以了解更多详细信息。您可能希望采用多线程解决方案来处理网络。查看同一教程中的SwingWorker
。它允许在后台线程上执行任务,并在EDT线程上传递结果
编辑:
由于您的应用程序的详细信息和规模不可用,因此很难给出具体的解决方案。请记住,Swing是单线程的。所有UI工作必须在EDT上完成。为了获得最佳性能,EDT上的所有任务都应简短。应在工作线程上处理网络。您有几个选项,例如SwingWorker
、ExecutorService
或您自己的辅助线程SwingWorker
有一个内置机制,可以在EDT上推送更新。如果是ExecutorService
,您可以使用SwingUtilities.invokeLater
您正在阻止事件调度线程(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);
在.readObject()中的一次迭代中代码>呼叫被阻止。线程也是如此。Sleep
。所有与UI相关的工作,如绘制,都在EDT上进行。一旦EDT被阻止,它就不会处理任何事件。因此,您看到的结果是,UI没有重新绘制
请查看以了解更多详细信息。您可能希望采用多线程解决方案来处理网络。查看同一教程中的SwingWorker
。它允许在后台线程上执行任务,并在EDT线程上传递结果
编辑:
由于您的应用程序的详细信息和规模不可用,因此很难给出具体的解决方案。请记住,Swing是单线程的。所有UI工作必须在EDT上完成。为了获得最佳性能,EDT上的所有任务都应简短。应在工作线程上处理网络。您有几个选项,例如SwingWorker
、ExecutorService
或您自己的辅助线程SwingWorker
有一个内置机制,可以在EDT上推送更新。如果是ExecutorService
,您可以使用SwingUtilities.invokeLater
链接还是java项目?您必须同时启动服务器和客户端。您可能正在阻止EDT,或者根本不使用EDT。我必须等到早上才能看到附加的代码,因为我无法在我的iPAD上查看它:(链接或java项目?您必须同时启动服务器和客户端似乎您正在阻止EDT或根本不使用EDT。我必须等到早上才能看到附加的代码,因为我无法在我的iPAD上查看它:(当Gagandeep Bali暗示时,我已经在看那些EDT教程了。编辑:我更新了我的question@mark查看我的上一次更新。您也可以选择一个专用的ExecutorService
。我接受了答案,我想从现在起我可以找到答案。我已经与SwingWorker修复了它,但我仍在调整它,因为doInBackground()不能像wishEclipse在我的受保护void doInBackground()中说的那样是一个void函数“返回类型与SwingWorker不兼容”方法,并且自动更正提示我将其更改为受保护的Void doInBackgroundmethod@max+1用一个小例子解释EDT是如何被阻止的以及需要做什么,而不仅仅是说“使用SwingWorker
或ExecutorService
”当Gagandeep Bali暗示时,我已经在看EDT教程了question@mark查看我的上一次更新。您也可以选择一个专用的ExecutorService
。我接受了答案,我想从现在起我可以找到答案。我已经与SwingWorker修复了它,但我仍在调整它,因为doInBackground()不能像wishEclipse在受保护的void doInBackground()方法中所说的“返回类型与SwingWorker不兼容”,并且自动更正提示我将其更改为受保护的V