2016-12-05 48 views
0

我有這樣的:basic Application - JButton - JTextField的SwingWorker - 如何一個ActionEvent期間刷新一個JTextField

我想顯示在JTextField中(稱爲TF1)的計數器(0-> 100),當我點擊JButton的「連接」 。但我希望GUI在期間在JButton上顯示計數

所以,當我點擊JButton的,我稱之爲:

public class Swing_Lab_2 { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     TestWindows tw = new TestWindows(); 
    } 
} 
class TestWindows extends JFrame { 

    private final JPanel pnl; 
    private final JTextField tf1; 
    private final JButton btn; 

    TestWindows() { 
     super(); 
     pnl = new JPanel(new GridLayout(2, 2)); 
     tf1 = new JTextField(); 
     btn = new JButton("Connect"); 

     pnl.add(btn); 
     pnl.add(new JPanel()); 
     pnl.add(tf1); 

     this.setContentPane(pnl); 
     btn.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       goSequenceTest(); 
      } 

     }); 

     this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     this.pack(); 
     this.setVisible(true); 
    } 

    private void goSequenceTest() { 
     CountWorker_TF cw = new CountWorker_TF(); 
     cw.execute(); 
     for (int i = 0; i < 10; i++) { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
     boolean result = cw.getStatus(); 
     System.out.print(String.format("in the interruption %b", result)); 
    } 

    private class CountWorker_TF extends SwingWorker<Integer, String> { 

     boolean finished = false; 

     CountWorker_TF() { 

     } 

     @Override 
     protected Integer doInBackground() throws Exception { 
      for (int i = 0; i < 101; i++) { 
       publish(String.format("%d", i)); 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
      finished = true; 
      System.out.print(String.format("in the swingWorker %b", finished)); 
      return 1; 
     } 

     public boolean getStatus() { 
      return finished; 
     } 

     @Override 
     protected void process(List<String> strings) { 
      /* Affichage des publications reçues dans le textarea. */ 
      for (String s : strings) { 
       tf1.setText(s); 
      } 
     } 

    } 

要查看是否擺動工人的工作,我把一個斷點布爾結果= cw.getStatus();,我觀察到計數器是活動的,但沒有顯示Jtextfield中的計數。

你能告訴我我做錯了什麼嗎?

編輯:在這裏,測試用例。我把一個「Thread.sleep(1000)」模擬一個耗時的計算(我不知道這是個好主意)在方法goSequenceTest();。我觀察到,該計數器是活躍的,但沒有顯示Jtextfield中的計數。

非常感謝!

OC

+0

我從來沒有與擺動工作人員合作,但流程方法似乎並不是一個好主意。一旦輸入方法,它會立即將您的文本字段的文本設置爲最後一個值(至少這是我的理解你的代碼)。 – XtremeBaumer

+0

感謝您的評論XtremeBaumer。 我真的不明白它是如何工作的。我得到的理解是,每次調用進程(列表字符串)時,該列表在該方法結束時被清除,並且對publish(String str)的新調用將添加其第一個字符串。但我不知道EDT如何管理這兩種方法。 – user7251462

+0

發佈一個證明問題的正確[mcve]。所以你需要一個帶有文本框和按鈕的框架。當你點擊按鈕時,你啓動SwingWorker。 – camickr

回答

0

我明白代碼出了什麼問題。它是不可能在GUI事件期間修改GUI 期間!現在看起來很明顯......美國東部時間有一個堆棧,它充滿了行動。當我點擊連接按鈕時,EDT會在其堆棧中執行一個新操作。直到此操作未完成處理,EDT無法繼續執行堆棧上的下一個操作。

我試圖用我的Swingworker做的事情並不是做這件事的好方法。並添加「Thread.sleep(1000)」在我的方法是愚蠢的,因爲我阻止了EDT 1000毫秒。

我解決我的問題,通過使用兩個線程:

CalculationThread處理我的耗時的計算:

private class CalculationThread extends Thread { 

     public CalculationThread() { 
      super(); 
     } 

     @Override 
     public void run() { 
      for (int i = 0; i < 100; i++) { 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       System.out.println(String.format("I am processing a calculation consuming time %d", i)); 
      } 
     } 
    } 

SwingWorkerThread處理我的SwingWorker。 (該JOptionPane的是在這裏,看看它處理耗時的計算任務的線程工作正常):

private class SwingWorkerThread extends Thread { 

     boolean reloadFpga = false; 

     public SwingWorkerThread() { 
      super(); 
     } 

     public void run() { 
      Object[] options = {"Yes", "No"}; 
      String txt = "Would you like start counting ?"; 
      int reload = JOptionPane.showOptionDialog(TestWindows.this.getFrame(), txt, "Counting ?", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, null); 
      reloadFpga = (reload == 0); 

      if (reloadFpga) { 
       CountWorker_TF cw = new CountWorker_TF(); 
       cw.execute(); 
       boolean result = false; 
       while (!result) { 
        result = cw.getStatus(); 
        System.out.print(String.format("In the SwingWorker %b \n", result)); 
       } 
      } 

     } 

    } 

的goSequenceTest()方法如下所示:

private void goSequenceTest() { 
     SwingWorkerThread tt = new SwingWorkerThread(); 
     tt.start(); 

     CalculationThread tt2 = new CalculationThread(); 
     tt2.start(); 

     System.out.print(String.format("End EDT")); 
    } 

添加下面的getFrame()方法該類TestWindows看到該項目的作品:

private Component getFrame() { 
     return this; 
    }