2014-09-29 62 views
1

我有一個有趣的項目,我需要更改迭代中文本區域的內容。更新迭代中的textArea

它的一個角色,一個「射彈」,移動一個字符串。該字符串將被更新併發送到迭代中的textArea,並在角色到達牆壁時停止迭代。

但我textArea只更新(視覺),當我離開迭代。當它在裏面時,textArea凍結,就好像它在等待迭代一樣,即使在它內部有Thread.sleep()。

我做了一個MVCE例證問題的下面,注意文本只顯示迭代後,我希望它在每一步的apper。

public class GUIProblem extends JFrame{ 
    public GUIProblem() { 
     setSize(640, 480); 

     JPanel panel = new JPanel(); 
     getContentPane().add(panel, BorderLayout.CENTER); 

     final JTextArea textArea = new JTextArea(); 
     textArea.setRows(10); 
     textArea.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent arg0) { 
       int i = 0; 
       while(i < 10){ 
        textArea.setText("this text only appears after the iteration, i want it to appear in each step of the iteration!"); 
        System.out.println("iterating..." + i++); 
        try { 
         Thread.sleep(200); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }); 
     textArea.setColumns(30); 
     panel.add(textArea); 
    } 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       GUIProblem gui = new GUIProblem(); 
       gui.setVisible(true); 
      } 
     }); 
     JOptionPane.showMessageDialog(null, "Click the textArea!"); 
    } 
} 

回答

4

你已經一個經典的Swing線程問題,即停止在其軌道Swing事件線程與你的迭代和Thread.sleep()電話。解決方案與類似問題相同:使用Swing Timer或後臺線程(如SwingWorker)。在你的情況下,使用計時器。

例如,由於您發佈的MCVE

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 

public class GUIProblem extends JFrame { 
    public GUIProblem() { 
     // setSize(640, 480); 

     JPanel panel = new JPanel(); 
     getContentPane().add(panel, BorderLayout.CENTER); 

     final JTextArea textArea = new JTextArea(20, 50); 
     textArea.addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent mEvt) { 
      int i = 0; 
      int timerDelay = 200; 
      new Timer(timerDelay, new ActionListener() { 
       int count = 0; 
       private final int MAX_COUNT = 10; 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (count >= MAX_COUNT) { 
        ((Timer) e.getSource()).stop(); // stop the timer 
        return; 
        } 
        textArea.append("Count is: " + count + "\n"); 
        count++; 
       } 
      }).start(); 
     } 
     }); 

     panel.add(new JScrollPane(textArea)); 
    } 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      GUIProblem gui = new GUIProblem(); 
      gui.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
      gui.pack(); 
      gui.setLocationRelativeTo(null); 
      gui.setVisible(true); 
     } 
     }); 
     JOptionPane.showMessageDialog(null, "Click the textArea!"); 
    } 
}