2014-03-05 3 views
0

Я использую Swing Application Framework в своей программе. И у меня есть многолетняя работа. Я использую для этого org.jdesktop.application.Task. Другой программист написал две Задачи, прежде чем я взял этот проект (я не могу спросить его о программе). Когда Задачи выполняются, пользователь видит индикатор выполнения, не показывая процент завершения, но то, что показывает сообщение «Подождите», и пользователь не может нажать на главное окно, пока задача не закончится. Это прекрасно! Но я не мог найти место, где был создан ProgressBars. Может быть, это описано в некоторых файлах xml-файла или файла свойств?Как заставить программу ждать задание и показать индикатор выполнения для пользователя?

Также я написал еще одну задачу, и когда они запускаются, индикатор выполнения, который я создал, не отображается или отображается неправильно. Я читал о ProgressBar и ProgressMonitor, но это мне не помогает. Программа продолжает работать после 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 не отображается.

Мне нужно, когда задача запускает программу, ждет ее, но пользователь может видеть 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 правильно. Любая длительная задача должна запускаться в ее собственном потоке, чтобы графический интерфейс реагировал и перекрашивался.

В идеале вы будете следить за кодом 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); 

    } 
}