【问题标题】:Radio button doesn't change the state immediately单选按钮不会立即更改状态
【发布时间】:2014-12-18 21:55:58
【问题描述】:

在我们的项目中,我的队友注意到单选按钮的异常行为,当内部动作侦听器有 SwingUtilites.invokeLater 调用时。动作侦听器的架构不允许避免此调用,因为它旨在启动另一个线程,然后切换回 AWT 线程。

有没有办法解决这个问题?我的意思是改变显示组件的状态。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;

public class RadioButtonTest {

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
            | UnsupportedLookAndFeelException e1) {
        e1.printStackTrace();
    }
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.add(panel);
    ButtonGroup group = new ButtonGroup();
    JRadioButton b1 = new JRadioButton("Button 1");
    final JRadioButton b2 = new JRadioButton("Button 2");
    b2.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            Runnable action = new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(2500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        e.printStackTrace();
                    }
                }
            };
            SwingUtilities.invokeLater(action);
        }
    });
    group.add(b1);
    group.add(b2);
    panel.add(b1);
    panel.add(b2);

    frame.setVisible(true);
} 
}

【问题讨论】:

    标签: java swing actionlistener thread-sleep jradiobutton


    【解决方案1】:

    您似乎希望避免重复启动长时间运行的后台任务。代替JRadioButton,使用父JToggleButton,并在后台任务启动时将其名称和操作设置为CancelFutureSwingWorker 使这很方便。使用JButton 的相关示例见here

    【讨论】:

      【解决方案2】:

      使用 SwingWorker,试试这个代码:

       public void actionPerformed(ActionEvent arg0) {
             SwingWorker<Object,Object> sw = new SwingWorker<Object,Object>()
             {
                  @Override
                  protected Object doInBackground() throws Exception
                  {
                      try {
                           Thread.sleep(2500);
                       } catch (InterruptedException e) {
                           Thread.currentThread().interrupt();
                           e.printStackTrace();
                       }
                       return null;
                  }
              };
              sw.execute();
      }
      

      SwingWorker 在单独的工作线程上执行,该工作线程由事件调度线程通过调用 execute 方法调用。 SwingUtilities.invokeLater 方法只是将 run 方法强制异步执行到事件调度线程上,因此在其中调用 Thread.sleep 将冻结影响 GUI 的事件调度线程。

      【讨论】:

        猜你喜欢
        • 2021-12-25
        • 1970-01-01
        • 2021-01-28
        • 1970-01-01
        • 2021-11-07
        • 2018-08-05
        • 2021-05-20
        • 1970-01-01
        相关资源
        最近更新 更多