2014-03-05 36 views
0

我在我的程序中使用了Swing應用程序框架。我有一些長期的工作。我用它org.jdesktop.application.Task。另一位程序員在我開始這個項目之前寫了兩個任務(我不能問他有關該程序)。當任務執行時,用戶看到進度條時沒有顯示完成百分比,但顯示「等待」消息,並且用戶無法在任務未結束時單擊到主窗口。沒事!但是我找不到創建ProgressBars的地方。可能是它在一些xml文件或屬性文件中描述?如何強制程序等待任務並向用戶顯示進度條?

另外我寫了另一個任務,當他們運行時,我創建的進度條不會顯示或顯示不正確。我閱讀了ProgressBar和ProgressMonitor,但它不能幫助我。 Programm在someTask.execute()後繼續運行,但我希望它顯示ProgressBar,ProgressMonitor或其他東西,並且用戶無法單擊主窗口並且窗口將正確顯示。現在,當用戶改變它時,窗口有黑色的「塊」。可能需要使用org.jdesktop.application.TaskMonitor。我嘗試在這裏使用它https://kenai.com/projects/bsaf/sources/main/content/other/bsaf_nb/src/examples/StatusBar.java?rev=235,但我的主窗口顯示不正確,我的ProgressBar不顯示。

我需要在任務運行程序,等待它的,但用戶可以看到進度條,可以取消操作並不能單擊主窗口。我該怎麼做?

這裏我的代碼:你的問題的

public class A{ 
@Action(name = "ActionName", block = Task.BlockingScope.APPLICATION) 
public RequestInfoTask requestInfo() { 
     RequestInfoTask task = new RequestInfoTask(Application.getInstance()); 
     isSuccessedGetInfo=false; 

     task.addTaskListener(new TaskListener.Adapter<List<InfoDTO>, Void>() { 
      @Override 
      public void succeeded(TaskEvent<List<InfoDTO>> listTaskEvent) { 
       isSuccessedGetResources=true; 
      } 
     }); 

     //Here I want to the program shows ProgressMonitor and user can not click to the main window. 
     //But small window with message "Progress..." is displayed for several seconds and disappear. 
     ProgressMonitor monitor = new ProgressMonitor(getMainView(), "Wait! Wait!", "I am working!", 0, 100); 
     int progress = 0; 
     monitor.setProgress(progress); 
     while(!task.isDone()){ 
      monitor.setProgress(progress+=5); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      } 
     } 
     monitor.setProgress(100); 

     //This code must run after "task" finishes. 
     if(isSuccessedGetInfo){ 
      MyTask2 task2 = new MyTask2(Application.getInstance()); 
      isSuccessedTask2=false; 
      task2.addTaskListener(new TaskListener.Adapter<Map<?,?>, Void>(){ 

       @Override 
       public void succeeded(TaskEvent<Map<String, ICredential>> arg0) { 
        isSuccessedTask2=true; 
       } 
      }); 
      //Do something with results of task2. 
     } 

     return task; 
    } 
} 

public class RequestInfoTask extends Task<List<InfoDTO>, Void> { 

    public RequestInfoTask(Application application) { 
     super(application); 
    } 

    @Override 
    protected List<InfoDTO> doInBackground() throws Exception { 
     List<InfoDTO> result = someLongerLastingMethod(); 
     return result; 
    } 

} 
+1

得到幫助最好的辦法是張貼有您所描述的問題代碼。如果您可以發佈一個獨立的工作示例,這將是獲得幫助的最快途徑。它也可能幫助你考慮問題。 – ditkin

回答

0

部分聽起來就像是來自不正確地使用EDT。任何長時間運行的任務都需要在自己的線程中啓動,以保持GUI的響應和重新繪製。

理想情況下,你會跟着MVC pattern。在這種情況下,您將進度欄放置在視圖中,控件中的標誌(表示任務是否應該仍在運行)以及模型中長時間運行的任務。

從這一點來說,如果你的模型週期性地檢查它是否應該停止(可能是在良好的停靠站),您可以重置一切。

下面是一個例子與MVC:

import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 


public class ProgressBarDemo{ 

    public static class View extends JPanel{ 
     Controller control; 
     public JProgressBar progressBar = new JProgressBar(0, 100); 
     JButton button = new JButton("Start Long Running Task"); 

     public View(Controller controlIn){ 
      super(); 
      this.control = controlIn; 
      setLayout(new BorderLayout()); 

      button.addActionListener(new ActionListener(){ 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        //Toggle between running or not 
        if(control.isRunning){ 
         control.isRunning = false; 
         button.setText("Canceling..."); 
         button.setEnabled(false); 
        } else{ 
         control.isRunning = true; 
         button.setText("Cancel Long Running Task"); 
         control.startTask(); 
        } 
       }}); 

      progressBar.setStringPainted(true); 
      add(progressBar); 
      add(button, BorderLayout.SOUTH); 
     } 
    } 

    //Communications gateway 
    public static class Controller{ 
     View view = new View(this); 
     boolean isRunning = false; 

     public void updateProgress(final int progress){ 
      SwingUtilities.invokeLater(new Runnable(){ 
       @Override 
       public void run() { 
        view.progressBar.setValue(progress); 
       }}); 
     } 

     public void reset(){ 
      SwingUtilities.invokeLater(new Runnable(){ 
       @Override 
       public void run() { 
        isRunning = false; 
        view.button.setText("Start Long Running Task"); 
        view.progressBar.setValue(0); 
        view.button.setEnabled(true); 
       }}); 
     } 

     public void startTask(){ 
      LongRunningClass task = new LongRunningClass(this); 
      new Thread(task).start(); 
     } 
    } 

    public static class LongRunningClass implements Runnable{ 

     Controller control; 
     public LongRunningClass(Controller reference){ 
      this.control = reference; 
     } 

     @Override 
     public void run() { 
      try { 
       for(int i = 0; i < 11; i++){ 
        //Monitor the is running flag to see if it should still run 
        if(control.isRunning == false){ 
         control.reset(); 
         break; 
        } 
        control.updateProgress(i * 10); 
        Thread.sleep(3000); 
       } 
       control.reset(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    public static void main(String[] args) throws InterruptedException { 
     // Create and set up the window. 
     JFrame frame = new JFrame("LabelDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     // Add content to the window. 
     frame.add(new Controller().view); 
     // Display the window. 
     frame.pack(); 
     frame.setVisible(true); 

    } 
}