2012-10-21 30 views
3

我正在製作遊戲客戶端/服務器,並且我正在使用新線程更新客戶端GUI(使用Swing)的一些信息。我試圖使用SwingUtilities,但它不起作用。另外,我聽說SwingUtilities每次使用它時都會創建一個新線程,所以我正在尋找一種新方法(我有10個左右的JTextFields需要更新)。有沒有辦法不使用SwingUtilities呢?這是我現在所擁有的。從Java中的另一個線程更新JTextField

SwingUtilities.invokeLater( 
     new Runnable() {  
      public void run()  
      {  
       Client.status.setText("status = "+status); 
      }  
     }); 
+0

究竟不管用? 'invokeLater'在[Event Dispatch Thread]上執行runnable(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html)。作爲替代方案,您可以查看[SwingWorker](http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html),該工具專爲長時間運行的任務而設計,可爲用戶界面提供更新在EDT上。 – tenorsax

+0

當我的意思不工作時,我的意思是Textfield沒有更新。不過我會看看SwingWorker。 – Narabhut

回答

4

我不知道你在哪裏聽說過「SwingUtilities類創建一個新的線程」而來,但我認爲你要麼誤解或錯誤地被告知。 SwingUtilities.invokeLaterRunnable放到Event Dispatcher隊列的末尾。隊列然後在它自己的線程上下文(及時)內處理這個事件,調用Run,沒有爲這個進程創建「新」線程。

至於你的問題。

您可能需要調用領域父容器validate()(也可能repaint()),以鼓勵其更新;)

沒有,沒有任何其他的方式來同步跨越線程的用戶界面,這就是原因對於SwingUtilities

+0

+1不錯的答案。 * SwingUtilities.invokeLater將Runnable放置到Event Dispatcher隊列的末尾*,但我始終不知道你是如何從另一個線程更新UI comps,現在我知道肯定;) –

4

有趣的是,就在最近我遇到過類似的問題,所以爲了克服這個我用SwingUtilities.invokeAndWait(Runnable runnable),這就是取得了SSCCE我創建工作不如預期,但如果我改變所有調用invokeAndWait()invokeLater(),可以清楚地看到兩者之間的區別。

從Java文件引述說:

Causes doRun.run() to be executed synchronously on the AWT event dispatching thread. 
This call blocks until all pending AWT events have been processed and 
(then) doRun.run() returns. This method should be used when an application thread 
needs to update the GUI. 

這是我作爲一個SSCCE代表一個冒泡排序動畫做了一個小程序:

import javax.swing.*; 

public class BubbleSortFrame extends JFrame 
{ 
    private BubbleSortView contentPane; 

    private void displayGUI() 
    { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     contentPane = new BubbleSortView(); 
     setContentPane(contentPane); 
     pack(); 
     setLocationByPlatform(true); 
     setVisible(true); 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       new BubbleSortFrame().displayGUI(); 
      } 
     }); 
    } 
} 

import java.awt.*; 
import java.awt.event.*; 
import java.lang.reflect.InvocationTargetException; 
import javax.swing.*; 

public class BubbleSortView extends JPanel 
{ 
    private JLabel sizeLabel; 
    private JTextField sizeField; 
    private JTextField[] vField; 
    private JLabel[] vLabel; 
    private JButton startButton, createButton; 
    private int size; 
    private JPanel createPanel, animationPanel; 

    private BubbleSort bubbleSort; 

    public BubbleSortView() 
    { 
     size = 5; 
     displayAndCreateGUI(); 
    } 

    private void displayAndCreateGUI() 
    { 
     setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
     setOpaque(true); 
     setBackground(Color.WHITE); 
     JPanel basePanel = new JPanel(); 
     basePanel.setLayout(new GridLayout(2, 1, 5, 5)); 
     basePanel.setOpaque(true); 
     basePanel.setBackground(Color.WHITE); 

     JPanel topPanel = new JPanel(); 
     topPanel.setOpaque(true); 
     topPanel.setBackground(Color.WHITE); 
     topPanel.setBorder(
      BorderFactory.createTitledBorder("Input : ")); 
     topPanel.setLayout(new GridLayout(2, 1, 5, 5)); 
     /* 
     * This will act as the area 
     * for taking the input for 
     * number of elements in an Array. 
     */ 
     JPanel sizePanel = new JPanel(); 
     sizePanel.setOpaque(true); 
     sizePanel.setBackground(Color.WHITE); 
     sizeLabel = new JLabel("Enter Number of Elements : "); 
     sizeField = new JTextField(10); 
     createButton = new JButton("CREATE"); 

     /* 
     * This will act as the area 
     * where we will specify the values 
     * for each index in an Array. 
     */ 
     createPanel = new JPanel(); 
     createPanel.setOpaque(true); 
     createPanel.setBackground(Color.WHITE); 
     createPanel.setBorder(
      BorderFactory.createTitledBorder("Please Enter values for an Array : ")); 
     createPanel.setVisible(false);  

     animationPanel = new JPanel(); 
     animationPanel.setOpaque(true); 
     animationPanel.setBackground(Color.WHITE); 
     animationPanel.setBorder(
      BorderFactory.createTitledBorder("Animation : ")); 
     animationPanel.setVisible(false); 

     createButton.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent ae) 
      { 
       if (sizeField.getDocument().getLength() > 0) 
       { 
        size = Integer.parseInt(sizeField.getText()); 
        vField = new JTextField[size]; 
        createPanel.setVisible(true); 
        for (int i = 0; i < size; i++) 
        { 
         vField[i] = new JTextField(5); 
         /* 
         * Adding the Listener to the 
         * last JTextField on the Right 
         * Side. 
         */ 
         if (i == (size - 1)) 
         { 
          vField[i].addActionListener(new ActionListener() 
          { 
           @Override 
           public void actionPerformed(ActionEvent ae) 
           { 
            animationPanel.setLayout(
              new GridLayout(1, size, 2, 2)); 
            animationPanel.setVisible(true); 
            vLabel = new JLabel[size]; 
            for (int i = 0; i < size; i++) 
            { 
             vLabel[i] = new JLabel(
              vField[i].getText(), JLabel.CENTER); 
             vLabel[i].setOpaque(true); 
             vLabel[i].setBackground(Color.YELLOW); 
             vLabel[i].setForeground(Color.RED); 
             animationPanel.add(vLabel[i]); 
            } 
            animationPanel.revalidate(); 
            animationPanel.repaint(); 
            bubbleSort = new BubbleSort(vLabel, size); 
            Thread t = new Thread(bubbleSort); 
            t.start(); 
           } 
          }); 
         } 
         createPanel.add(vField[i]); 
        } 
        createPanel.revalidate(); 
        createPanel.repaint(); 
        createButton.setEnabled(false); 
       } 
       else 
        size = 5; 
      } 
     }); 
     sizePanel.add(sizeLabel); 
     sizePanel.add(sizeField); 
     sizePanel.add(createButton); 

     /* 
     * Initializing JTextField Array 
     * so that it can be first presented 
     * to the USER to take input for 
     * 5 values. 
     */ 
     //for (int i = 0; i < size; i++) 
     // vField[i] = new JTextField(5); 
     topPanel.add(sizePanel); 
     topPanel.add(createPanel); 
     basePanel.add(topPanel); 
     basePanel.add(animationPanel); 
     add(basePanel); 
    } 

    private class BubbleSort implements Runnable 
    { 
     private int[] arr; 
     private JLabel[] vLabel; 
     private int size; 
     private int pass; 

     public BubbleSort(JLabel[] label, int size) 
     { 
      vLabel = label; 
      this.size = size; 
      pass = 1; 
      for (int i = 0; i < size; i++) 
       System.out.print("" + vLabel[i].getText() + "\t"); 
      System.out.println(""); 
     } 

     @Override 
     public void run() 
     { 
      try 
      { 
       bubbleSorting(); 
      } 
      catch (InvocationTargetException ite) 
      { 
       ite.printStackTrace(); 
      } 
      catch(InterruptedException ie) 
      { 
       ie.printStackTrace(); 
      } 
     } 

     private void bubbleSorting() 
      throws InterruptedException, InvocationTargetException 
     { 
      while (pass < size) 
      { 
       for (int i = 0; i < (size - pass); i++) 
       { 
        final int j = i; 
        SwingUtilities.invokeAndWait(new Runnable() 
        { 
         @Override 
         public void run() 
         { 
          vLabel[j].setBackground(Color.RED); 
          vLabel[j].setForeground(Color.WHITE); 
          vLabel[j + 1].setBackground(Color.RED); 
          vLabel[j + 1].setForeground(Color.WHITE); 
         } 
        }); 
        try 
        { 
         Thread.sleep(1500); 
        } 
        catch(InterruptedException ie) 
        { 
         ie.printStackTrace(); 
        } 
        int left = Integer.parseInt(vLabel[i].getText()); 
        int right = Integer.parseInt(vLabel[i + 1].getText()); 
        if (left > right) 
        { 
         String temp = vLabel[i].getText(); 
         vLabel[i].setText(vLabel[i + 1].getText()); 
         vLabel[i + 1].setText(temp); 
        } 
        SwingUtilities.invokeAndWait(new Runnable() 
        { 
         @Override 
         public void run() 
         { 
          vLabel[j].setBackground(Color.YELLOW); 
          vLabel[j].setForeground(Color.RED); 
          vLabel[j + 1].setBackground(Color.YELLOW); 
          vLabel[j + 1].setForeground(Color.RED); 
         } 
        }); 
       } 
       System.out.println("Pass : " + pass + "\tSize : " + size); 
       SwingUtilities.invokeAndWait(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         vLabel[size - pass].setBackground(Color.GREEN); 
         vLabel[size - pass].setForeground(Color.BLUE); 
        } 
       }); 
       pass++; 
      } 
      SwingUtilities.invokeAndWait(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        vLabel[0].setBackground(Color.GREEN); 
        vLabel[0].setForeground(Color.BLUE); 
       } 
      }); 
     } 
    } 
} 
+1

+1 nice SSCCE :) –

相關問題