2012-06-14 16 views
6

Tôi có một ứng dụng Java sử dụng SwingWorker để cập nhật nhãn và thanh tiến trình trong GUI và hoạt động tốt. Tuy nhiên, tôi muốn thêm một tính năng vào cài đặt này.cách cập nhật GUI từ swingworker trả về hai giá trị khác nhau

Nhân viên xoay vòng của tôi thực hiện tác vụ có độ dài n và lặp lại tác vụ đó m lần. Ngay bây giờ GUI của tôi chỉ cho tôi biết có bao nhiêu thời gian nhiệm vụ đã được lặp đi lặp lại, nhưng tôi muốn nó cũng cho tôi biết thời gian của nhiệm vụ mà chúng ta đang ở. Nói n=300m=50, tôi muốn một cái gì đó như:

Task 49 is at 248() 
Task has been repeated 48 times 

Tôi nên sửa đổi gì trong SwingWorker?

/** 
* 
* @author digitaldust 
*/ 
public class Model extends SwingWorker<Integer, Integer> { 

    private HashMap<String, Number> GUIparams; 
    private int session; 
    private int ticks; 

    Model(HashMap<String, Number> KSMParams) { 
     GUIparams = KSMParams; 
     session = (Integer)GUIparams.get("experimentsInSession"); 
     ticks = (Integer)GUIparams.get("howManyTicks"); 
    } 

    /** 
    * Actual simulation 
    */ 
    @Override 
    protected Integer doInBackground() throws Exception { 

     int i=0; 
     while(!isCancelled() && i<session){ 
      i++; 
      int ii=0; 
      while(!isCancelled() && ii<ticks){ 
       // this is n, the task length and I'd like to update the GUI with this value 
       ii++; 
      } 
      System.out.println(i); 
      // this is m, how many time the task has been repeated, and now it is updated in the GUI 
      publish(i); 
      setProgress(i); 
      Thread.sleep(1000); 
     } 
     return i; 
    } 

    /** 
    * Invoked when simulation exits 
    */ 
    @Override 
    protected void done() { 
     if (isCancelled()) { 
      Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session..."); 
     } else { 
      // do stuff 

      Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended."); 
     } 
    } 

} 

Trả lời

7

Loại tham số thứ hai V trong SwingWorker<T,V> được sử dụng để thực hiện kết quả trung gian bằng cách công bố và xử lý các phương pháp của SwingWorker này. Đây có thể là lớp tùy chỉnh của bạn. Dưới đây là một ví dụ dựa trên SSCCE đăng (rút ngắn cho rõ ràng):

class Progress { 
    private int task; 
    private int element; 

    public Progress(int task, int element) { 
     super(); 
     this.task = task; 
     this.element = element; 
    } 
     ... 
} 

public class Model extends SwingWorker<Integer, Progress> { 
    ... 
    @Override 
    protected Integer doInBackground() throws Exception { 
      ... 
      publish(new Progress(i, ii)); 
     } 
} 

EDIT: ví dụ về phương pháp thực hiện quá trình

@Override 
protected void process(List<Progress> progressList) { 
    for (Progress p : progressList){ 
     System.out.println(p.getTask() + " : " + p.getElement()); 
    } 
} 

EDIT: ví dụ về giao diện người dùng cập nhật

Đây là phiên bản sửa đổi nhỏ của việc triển khai nhân viên, simila r đến một mẫu được trình bày trong hướng dẫn sử dụng SwingWorker. Những thay đổi duy nhất là giới thiệu thành viên textArea và được cập nhật setProgress() gọi trong số doInBackground(). progress thuộc tính được sử dụng để cập nhật thanh tiến trình, process() được sử dụng để cập nhật vùng văn bản.

public static class Model extends SwingWorker<Integer, Progress> { 

    private HashMap<String, Number> GUIparams; 
    private int session; 
    private int ticks; 
    private JTextArea textArea; 

    Model(HashMap<String, Number> KSMParams, JTextArea textArea) { 
     GUIparams = KSMParams; 
     session = (Integer)GUIparams.get("experimentsInSession"); 
     ticks = (Integer)GUIparams.get("howManyTicks"); 

     this.textArea = textArea; 
    } 

    @Override 
    protected void process(List<Progress> progressList) { 
     for (Progress p : progressList){ 
      textArea.append(p.getTask() + " : " + p.getElement() + "\n"); 
      System.out.println(p.getTask() + " : " + p.getElement()); 
     } 
    } 

    /** 
    * Actual simulation 
    */ 
    @Override 
    protected Integer doInBackground() throws Exception { 

     int i=0; 
     while(!isCancelled() && i<session){ 
      i++; 
      int ii=0; 
      while(!isCancelled() && ii<ticks){ 
       // this is n, the task length and I'd like to update the GUI with this value 
       ii++; 
      } 
      //System.out.println(i); 
      // this is m, how many time the task has been repeated, and now it is updated in the GUI 
      publish(new Progress(i, ii)); 
      //setProgress(i); 
      setProgress(100 * i/session); 
      Thread.sleep(1000); 
     } 
     return i; 
    } 

    /** 
    * Invoked when simulation exits 
    */ 
    @Override 
    protected void done() { 
     if (isCancelled()) { 
      Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session..."); 
     } else { 
      // do stuff 

      Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended."); 
     } 
    } 
} 

Đây là một khởi demo:

final JProgressBar progressBar = new JProgressBar(0, 100); 
final JTextArea textArea = new JTextArea(); 
final JButton button = new JButton("Start"); 

button.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     HashMap<String, Number> map = Maps.newHashMap(); 
     map.put("experimentsInSession", 10); 
     map.put("howManyTicks", 5); 

     Model task = new Model(map, textArea); 
     task.addPropertyChangeListener(
       new PropertyChangeListener() { 
        public void propertyChange(PropertyChangeEvent evt) { 
         if ("progress".equals(evt.getPropertyName())) { 
          progressBar.setValue((Integer)evt.getNewValue()); 
         } 
        } 
       }); 
     task.execute(); 
    } 
}); 
+1

+1: cùng một ý tưởng như tôi, nhưng sớm. –

+0

cảm ơn cho gợi ý, chỉ là một điều nhỏ: làm thế nào để lấy lại giá trị cho GUI? Mã của tôi không hoạt động nữa: nếu ("tiến trình" .equals (evt.getPropertyName())) { tiến trìnhBar.setValue ((Số nguyên) evt.getNewValue()); showTaskLabel.setText ("Thử nghiệm" + (Số nguyên) evt.getNewValue() + "đã ký kết.");} Cảm ơn bạn đã giúp đỡ. – user299791

+1

@SimoneGabbriellini Dường như bạn đang nghe thuộc tính 'progress'. Thuộc tính này là 'Integer' và bạn có thể sử dụng nó để cập nhật thanh tiến trình như trong bình luận của bạn. Để có được quyền truy cập vào các kết quả tiến trình trung gian, bạn nên ghi đè lên phương thức 'process()'. Xem chỉnh sửa của tôi để biết ví dụ. – tenorsax