2012-10-21 31 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 :) –

相关问题