2015-05-28 43 views
0

如果在执行RMI连接期间如何使我的进度条响应,我已经没有任何想法了,所以我决定询问您的帮助。使用Swing进度条的多线程

下面的代码:

Thread performLogin = new Thread(new Runnable() 
{ 

    @Override 
    public void run() 
    { 
     LoginResult = TryLogin(); 
    } 
}); 

performLogin.start(); 
WaiterFrame.setVisible(true); 
SetProgressDialog(); 

try 
{ 
    performLogin.join(); 
} 
catch(InterruptedException exc) 
{ 
    System.err.println(exc.getLocalizedMessage()); 
} 

if (LoginResult) 
{ ... } 


WaiterFrame.setVisible(false); 
this.dispose(); 

进度条没有反应 - 在执行performLogin线程没有动画,因为它应该。我试图在另一个线程上运行进度条框架,但结果相同(以及使用Eventqueue.invokelater())。

回答

1

可能的原因是performLogin.join();阻塞了事件派发线程,导致UI无响应。

Swing(和大多数GUI框架)要记住的两件事情;

  1. 它是单线程的,如果你的块EDT出于任何原因,将不再能够处理新的事件或执行重绘
  2. 它不是线程安全的,所以你永远不应该修改的状态意来自EDT外部的UI。

你可以使用一个SwingWorker,这将让你在后台线程中运行长时间运行的过程,但提供了一些机制,通过它可以将更新发送回EDT安全的。

Worker Threads and SwingWorker更多细节和Issues with SwingWorker and JProgressBar为例

1

如果您使用的是Java 8,你可以尝试这样的事:

CompletableFuture<LoginResult> loginResult = CompletableFuture.supplyAsync(this::tryLogin); 
WaiterFrame.setVisible(true); 
setProgressDialog(); 
loginResult.thenAccept(lr -> { 
    //do your thing 
    WaiterFrame.setVisible(false); 
}) 

有这取决于你需要做什么其他选项“thenAccept”。 “然后接受”只消耗未来的内容。

如果Java 8不是一个选项,使用Guava的ListenableFuture和Executors也可以实现同样的效果。

+0

感谢您的回复,这个工具看起来非常有用的,但在我的情况没有结果。在执行TryLogin()方法期间仍然没有动画(按照预期进行进度条动画之后)。 – baka1408

0

非常感谢你MadProgrammer!进度条按照SwingWorker用法的预期工作。我张贴的代码,如果有人鼓励在未来同样的问题:

PerformLogin = new SwingWorker<Boolean, Object>() 
{ 
    @Override 
    protected Boolean doInBackground() throws Exception 
    { 
     LoginResult = TryLogin(); 
     if (LoginResult) 
     { 
      MainF = new MainFrame(); 
      MainF.Connection = DataEntry.TestConnection; 
      MainF.prepareFormToShow(); 
     } 
     return LoginResult; 
    } 

    @Override 
    protected void done() 
    { 
     if (LoginResult == true) 
     { 
      EventQueue.invokeLater(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         MainF.setVisible(true); 
         WaiterFrame.setVisible(false); 
        } 
       }); 
     } 
     else 
     { 
      setVisible(true); 
      this.cancel(true); 
      JOptionPane.showMessageDialog(null, "Wrong adress!", 
      "Błąd",JOptionPane.WARNING_MESSAGE); 
     } 
    } 

WaiterFrame.setVisible(true); 
PerformLogin.execute(); 
在主线程