无法正确禁用JButton

时间:2019-12-06 07:09:09

标签: java swing

//Click Event for convertBtn
        convertBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                //Disable convertBtn temporarily
                convertBtn.setEnabled(false);

                //If amountBox is empty or has an invalid value
                if(!amountBox.getText().matches("^[0-9]{0,10}(\\.[0-9]{1,5})?$") || amountBox.getText().equalsIgnoreCase("")) {
                    amountBox.requestFocusInWindow();
                    JOptionPane.showMessageDialog (null, "Please Enter a valid amount.\nEx: 1234567890.12345", "Invalid Amount", JOptionPane.ERROR_MESSAGE);
                    convertBtn.setEnabled(true);
                    return;
                }

                //Fetch the exchange rate and place it inside the resLabel.
                //The code connect to a server to fetch the data with the help of a thread.
                //Also Thread.join() is used in the code to wait for the result.
                ExchangeRate er = new ExchangeRate(currencies[fromCombo.getSelectedIndex()], currencies[toCombo.getSelectedIndex()], amountBox.getText());
                resLabel.setText(er.getExhangeRate());

                //Re-enable convertBtn
                convertBtn.setEnabled(true);

            }

        });

触发事件后,程序应在执行某些进程时禁用按钮,并且在进程结束后,程序应重新启用按钮。

不幸的是,实际上发生的是在执行过程中不会禁用该按钮。当我删除了应该重新启用按钮的最后一行时,我注意到打算在开始时禁用按钮的第一行实际上是在过程结束之后执行的!

这意味着都convertBtn.setEnabled(false);和convertBtn.setEnabled(true);似乎在其他进程结束后执行!!

1 个答案:

答案 0 :(得分:1)

Swing使用单个线程进行所有事件分派。这还包括绘画事件。

基本上在您的代码中,ActionEvent被传递到您的actionPerformed方法,您做了一些工作(禁用/启用按钮),然后该方法返回。只有在这一点上,Swing才可以处理任何新事件(包括重绘事件)。

这意味着在actionPerformed存在之前,UI上的任何内容都不会更新。

有关更多详细信息,请参见The Event Dispatch Thread

那么,解决方案是什么?

嗯,最常见的解决方案是使用SwingWorker

这将使您可以在“事件调度线程”之外执行工作,但是它还提供了与UI交互的便捷功能,例如更新进度条。

您还可以听工作者查看完成的时间并重置按钮的状态