Java JFrame未正确显示

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

在我的客户机/服务器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(正常工作)

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

   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