2012-01-18 175 views
8

我有一個消息標籤和一個提交按鈕。提交按鈕將被多次按下,每次按下的操作可能需要一分鐘時間。Swing - 更新標籤

按下按鈕時,我想將消息設置爲空,並且在任務完成後,我要將消息設置爲「完成」。

private void submitActionPerformed(java.awt.event.ActionEvent evt) { 
    message = ""; 
    updateMessageLabel(); 

    doTheTask(); 

    /* this update is apply to the label after completion */ 
    message = "Complete"; 
} 

是否有可能在運行submitActionPerformed()方法之前(或方法)來更新該消息的標籤,但在點擊該按鈕後?

+2

我可能會推斷太多在這裏,但似乎像一個進度條將很好地在這裏工作(http://docs.oracle。 COM/JavaSE的/教程/ uiswing /組件/ progress.html)? – 2012-01-18 20:20:59

+0

@ZackMacomber即下一步 – 2012-01-18 20:30:10

回答

10

是的,你可以做到這一點使用SwingWorker線程,不喜歡更新標籤,在currentThread的​​方法中的所有預submitActionPerformed()活動和使用職工Thread調用doTheTask()作爲後臺作業。

我建議你去通過這個文檔,參考有關SwingWorker Thread

+2

最好鏈接到最新版本的JavaDocs。我編輯了您的答案以指向J2SE 7.有關獲取最新文檔鏈接的提示,請參見[優點2](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7090875) 。 – 2012-01-19 03:20:47

13

雖然Swing concurrency tutorial已經包含了如何應對搖擺併發一些很好的樣本,找到下面這

  • 包含一個示例用於證明UI仍然存在的複選框
  • 有一個進度條,它從SwingWorker更新爲
  • 都有一個標籤,它獲取一旦SwingWorker更新完成

    import javax.swing.JCheckBox; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JProgressBar; 
    import javax.swing.SwingWorker; 
    import java.awt.BorderLayout; 
    import java.awt.EventQueue; 
    import java.lang.reflect.InvocationTargetException; 
    import java.util.List; 
    import java.util.concurrent.ExecutionException; 
    
    public class SwingWorkerExample { 
        private static JProgressBar PROGRESS_BAR; 
        private static JLabel OUTPUT_LABEL; 
        private static JFrame createGUI(){ 
        JFrame testFrame = new JFrame("TestFrame"); 
    
        PROGRESS_BAR = new JProgressBar(); 
        PROGRESS_BAR.setMinimum(0); 
        PROGRESS_BAR.setMaximum(100); 
    
        OUTPUT_LABEL = new JLabel("Processing"); 
    
        testFrame.getContentPane().add(PROGRESS_BAR, BorderLayout.CENTER); 
        testFrame.getContentPane().add(OUTPUT_LABEL, BorderLayout.SOUTH); 
    
        //add a checkbox as well to proof the UI is still responsive 
        testFrame.getContentPane().add(new JCheckBox("Click me to proof UI is responsive"), BorderLayout.NORTH); 
    
    
    
        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        return testFrame; 
        } 
    
        public static void main(String[] args) throws InvocationTargetException, InterruptedException { 
        EventQueue.invokeAndWait(new Runnable() { 
         @Override 
         public void run() { 
         JFrame frame = createGUI(); 
    
         frame.pack(); 
         frame.setVisible(true); 
         } 
        }); 
        //start the SwingWorker outside the EDT 
        MySwingWorker worker = new MySwingWorker(PROGRESS_BAR, OUTPUT_LABEL); 
        worker.execute(); 
        } 
        private static class MySwingWorker extends SwingWorker<String, Double>{ 
        private final JProgressBar fProgressBar; 
        private final JLabel fLabel; 
        private MySwingWorker(JProgressBar aProgressBar, JLabel aLabel) { 
         fProgressBar = aProgressBar; 
         fLabel = aLabel; 
        } 
    
        @Override 
        protected String doInBackground() throws Exception { 
         int maxNumber = 10; 
         for(int i = 0; i < maxNumber; i++){ 
         Thread.sleep(2000);//simulate long running process 
         double factor = ((double)(i+1)/maxNumber); 
         System.out.println("Intermediate results ready"); 
         publish(factor);//publish the progress 
         } 
         return "Finished"; 
        } 
    
        @Override 
        protected void process(List<Double> aDoubles) { 
         //update the percentage of the progress bar that is done 
         int amount = fProgressBar.getMaximum() - fProgressBar.getMinimum(); 
         fProgressBar.setValue((int) (fProgressBar.getMinimum() + (amount * aDoubles.get(aDoubles.size() - 1)))); 
        } 
    
        @Override 
        protected void done() { 
         try { 
         fLabel.setText(get()); 
         } catch (InterruptedException e) { 
         e.printStackTrace(); 
         } catch (ExecutionException e) { 
         e.printStackTrace(); 
         } 
        } 
        } 
    } 
    
+0

感謝您的代碼。很有幫助。 – 2012-01-19 13:38:26

+3

流程實現不像用戶預期的那樣工作正常:它們可能是列表中的幾個(累計)值,但它將progressBar值設置爲僅第一個值。相反,要麼循環遍歷全部,要麼只使用最後一個只有 – kleopatra 2012-01-20 12:12:11

+0

@kleopatra的好點。我將調整代碼 – Robin 2012-01-20 13:20:21