【问题标题】:new thread not showing the frame新线程不显示框架
【发布时间】:2013-02-20 08:27:04
【问题描述】:

我正在尝试建立网络连接,详细信息在 JFrame 中。当用户单击一个按钮时,它应该启动新线程并向用户显示等待消息,直到主线程建立网络连接。我写了这段代码

 public void actionPerformed(ActionEvent arg0) {
     Thread ref = new Thread(new Test());//Create a new thread
     ref.start();
      new AIDRTConnManager().createConnection(ipAddress, portAddress);//main thread
      }



//This is my Thread Class
    public class Test implements Runnable{
    JDialog waitDialog;
    JPanel panel1 = new JPanel();
    JLabel waitLabel;
    JFrame frame;


    public void run(){
        frame = new JFrame();
         waitDialog = new JDialog( frame,AIRDT.toolName, true );
         waitDialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );  
         JLabel waitLabel = new JLabel( "Trying to Connect to PleaseWait...",ErrorDialog.icon,SwingConstants.CENTER ); 
            panel1.add( waitLabel ); 
            waitDialog.add( panel1 );  
            waitDialog.setSize( 100, 40 ); 
            waitDialog.setBounds( 500,300, 300, 80 ); 
        waitDialog.setVisible( true ); 
    }
}

但是当我单击按钮时,Jdialog 显示空框架,没有等待消息 (JLable),一旦我完成网络连接,此等待消息就会正确显示。

我哪里出错了?这是一个 Swing 问题(或)线程问题吗?

您能否帮我显示一条等待消息,直到后端活动完成?

【问题讨论】:

  • Funny that you call waitDialog.setSize( 100, 40 ); waitDialog.setBounds( 500,300, 300, 80 ); setBounds 是同时调用 setLocation() 和 setSize() 的快捷方式。

标签: java multithreading swing concurrency event-dispatch-thread


【解决方案1】:

您在这里混合了线程 - 所有与 UI 交互的操作(例如创建新框架)都必须发生在事件调度线程 (EDT) 或您所称的“主”线程上。后台任务应该在不同的线程上执行。

基本上你有它向后 - 你应该在新线程中执行后台工作,并在主线程中创建新框架,这与你现在的方式相反。

【讨论】:

  • +1 他确实把这一切都扭转了。等待对话框应在 actionPerformed 中启动,而连接应在新线程中完成。澄清一下,通常所说的“主线程”是在 JVM 启动时调用 main(String[] args) 方法的线程。它通常与 EDT 混合,因为许多用户在“主线程”中启动 UI,而实际上应该使用 SwingUtilities.invokeLater 在 EDT 中执行此操作。
  • @ajshort 感谢您的详细解释。它部分解决了我的问题。我在新线程中完成了我的后台工作,它也创建了网络连接。同时我设置了 waitDialog.setVisible(true);在我的主线程中。但是在设置这个之后,我的主线程根本没有恢复。 waitDialog.setVisible(true); 中发生了什么?它显示等待对话框。但在那之后没有任何效果。我添加了一个条件来检查我的后台工作是否完成。如果是这样,我试图隐藏 Waitdialog。但这种情况本身没有运行。 waitDialog.setVisible(true) 冻结主线程。Pl Help
  • 与其添加条件,不如将创建的线程中的回调添加回主线程,以便在工作完成时通知它。有一个“SwingWorker”类,专为您正在尝试做的事情而设计。它将在后台运行一个任务,然后在它完成时在 EDT 上调用 done 方法。请参阅 docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html 以获得非常好的概述。
  • @ajshort 我完成了这个应用程序并想创建一个 jar。我引用了一些像这样的图像 Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("/images/icon.gif"));但是 jar 根本没有执行。如何将图像包含到 jar 中?
【解决方案2】:

actionPerformed 下的代码在事件调度线程 (EDT) 下执行,而不是您在评论中所说的在主线程上执行。

这意味着只要连接发生,EDT 就会被阻止,因此它不必处理其他一些 UI 内容,例如显示您的 JDialog

另外,与问题无关,但请注意,您创建了一个永远不会显示的 JFrame,它是您的 JDialog 的父级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多