简体   繁体   English

SwingWorker-如何在ActionEvent中刷新JTextfield

[英]SwingWorker - How to refresh a JTextfield during an ActionEvent

I have this: basic Application - JButton - JTextField 我有这个: 基本应用程序-JButton-JTextField

I want to display a counter in the JTextField (named tf1) (0->100) when I click on the JButton "Connect". 当我单击JButton“连接”时,我想在JTextField(名称为tf1)(0-> 100)中显示一个计数器。 BUT I want the GUI to display the counting during the event on the JButton. 但是我希望GUI在JButton事件期间显示计数。

So when I click on the JButton, I call : 因此,当我单击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);
            }
        }

    }

To see if the swing worker worked, I put a breakpoint on boolean result = cw.getStatus(); 要查看秋千工作者是否工作,我在boolean result = cw.getStatus();上设置了一个断点 , I observe that the counter was active but did not display the count in the Jtextfield. ,我观察到该计数器处于活动状态,但未在Jtextfield中显示该计数。

Could you tell me what I did wrong? 你能告诉我我做错了什么吗?

EDIT: Here, the test case. 编辑:在这里,测试用例。 I put a "Thread.sleep(1000)" to simulate a time consuming calculation (I don't know if it is a good idea) in the method goSequenceTest(); 我在方法goSequenceTest()中放入了“ Thread.sleep(1000)”来模拟耗时的计算(我不知道这是否是个好主意); . I observe that the counter was active but did not display the count in the Jtextfield. 我观察到该计数器处于活动状态,但未在Jtextfield中显示该计数。

Many Thanks! 非常感谢!

OC 超频

I understand what was wrong with the code. 我了解代码有什么问题。 It is impossible to modify the GUI during a GUI event! GUI事件期间 无法修改GUI! It seems obvious now... The EDT has a stack, which is filled with actions to do. 现在看来很明显……EDT有一个堆栈,其中充满了要执行的操作。 When I click on the connect button, the EDT has a new action to do in its stack. 当我单击连接按钮时,EDT在其堆栈中有一个新操作要执行。 Until, this action is not completely processed, the EDT can not proceed to the next action on its stack. 直到该操作未完全处理,EDT才能继续执行其堆栈上的下一个操作。

What I tried to do with my Swingworker was not the good way to do it. 我尝试与Swingworker一起工作的方法不是很好的方法。 And add "Thread.sleep(1000)" in my method was stupid, since I block the EDT for 1000ms. 在我的方法中添加“ Thread.sleep(1000)”是愚蠢的,因为我将EDT阻止了1000ms。

I solved my issue by using two threads: 我通过使用两个线程解决了我的问题:

CalculationThread handles my time consuming calculation: 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 handles my SwingWorker. SwingWorkerThread处理我的SwingWorker。 (The JOptionPane is here to see if the Thread which handles the consuming calculation task works properly): (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));
                }
            }

        }

    }

The goSequenceTest() method looks like: goSequenceTest()方法如下所示:

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

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

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

Add the following getFrame() method in the class TestWindows to see the project works: 在类TestWindows中添加以下getFrame()方法以查看项目的工作情况:

private Component getFrame() {
        return this;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM