2014-12-18 3 views
1

우리 팀원은 라디오 버튼에 대한 비정상적인 동작을 알았습니다. 내부 리스너에는 SwingUtilites.invokeLater 호출이 있습니다. 액션 청취자의 구조에서는, 다른 thread를 기동하도록 (듯이) 설계되어 있기 (위해) 때문에,이 호출을 피할 수가 없게되어, AWT thread 에의 전환이 다시 생깁니다.라디오 버튼으로 상태가 즉시 바뀌지 않습니다.

해결 방법이 있습니까? 표시되는 구성 요소의 상태를 변경하는 것을 의미합니다.

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

답변

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의이 방법을 실행 호출하여 이벤트 디스패처 스레드에 의해 호출되는 별도의 작업자 스레드에서 실행됩니다. SwingUtilities.invokeLater 메서드는 이벤트 발송 스레드에서 비동기 적으로 실행될 run 메서드를 부과하기 때문에 내부에서 Thread.sleep을 호출하면 GUI에 영향을주는 이벤트 발송 스레드가 고정됩니다.

4

장기간 백그라운드 작업을 반복적으로 시작하지 않으려는 것처럼 보입니다. JRadioButton 대신 부모 JToggleButton을 사용하고 이름과 작업을 으로 설정하십시오. 백그라운드 작업이 시작되면을 취소하십시오. SwingWorker과 같은 Future을 사용하면 편리합니다. JButton을 사용하는 관련 예제는 here입니다.

관련 문제