java - 从 Java 中的另一个线程更新 JTextField

标签 java multithreading swing user-interface client

我正在制作一个游戏客户端/服务器,我有一个新线程更新客户端 GUI(使用 Swing)上的一些信息。我正在尝试使用 SwingUtilities,但它不起作用。另外,我听说 SwingUtilities 会在您每次使用它时创建一个新线程,所以我也在寻找一种新方法(我有 10 个左右的 JTextFields 需要更新)。有没有不使用 SwingUtilities 的方法?这是我现在拥有的。

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

最佳答案

有趣的是,就在最近我遇到了类似的问题,所以为了克服这个问题我使用了SwingUtilities.invokeAndWait(Runnable runnable) ,这就是 SSCCE 的原因我正在创建以按预期工作,但如果我将所有调用更改为 invokeAndWait() invokeLater() ,两者的区别一目了然。

引自 Java Doc 说:

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);
                }
            });
        }
    }
}

关于java - 从 Java 中的另一个线程更新 JTextField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13003280/

相关文章:

java - Apache:Tomcat "any version".exe 或 .zip

multithreading - Windows 7 Phone中的线程问题

ios - coreData executeFetchRequest 方法的竞争条件导致 nil 数据的问题

java - 使用多线程程序并行编译项目比使用单线程程序有任何性能优势吗?

java - 在 JTable 单元格中输入值并单击“确定”不注册值

java - 如何使用TableColumnModelListener根据java中的重新定位来更改列颜色

java - 迭代列表并排列数据

java - JScrollPaneLayout怎么设置和JTable一样?

java - 在java swing中同步滚动N个jtables

java - Admob 间质性单例模式 java.lang.NullPointerException :