이 문제가 발생하는 이유는 여러 가지가있을 수 있으며 동일하게 고정 될 수있는 여러 가지 이유가 있습니다.
설명에 따르면 이벤트 발송 스레드 외부에서 UI를 업데이트하려고하는 것 같습니다.
스윙은 단일 스레드 환경이며 스레드로부터 안전하지도 않습니다. 기본적으로 이것은 UI에 대한 모든 상호 작용/변경이 EDT의 맥락에서 수행 될 것이라는 기대가 있습니다. 이 규칙을 지키지 않으면 모든 종류의 이상하고 멋진 행동으로 이어질 수 있습니다.
가장 간단한 해결책은
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FlashyButton {
public static void main(String[] args) {
new FlashyButton();
}
public FlashyButton() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton button;
private Color[] colors = new Color[]{Color.RED, Color.YELLOW};
public TestPane() {
button = new JButton("Flash Gorden");
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setFocusPainted(false);
button.setOpaque(true);
button.setBackground(Color.YELLOW);
setLayout(new GridBagLayout());
add(button);
Timer timer = new Timer(500, new ActionListener() {
private int counter = 0;
@Override
public void actionPerformed(ActionEvent e) {
counter++;
if (counter % 2 == 0) {
button.setBackground(colors[0]);
} else {
button.setBackground(colors[1]);
}
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
}
Concurrency in Swing에서보세요 당신은 예를 들어 EDT 내에서 실행이 보장되는 정규 시간 제한 이벤트를 예약 할 수있는하는 javax.swing.Timer
을 사용하는 것입니다 자세한 내용은 How to Use Swing Timers을 참조하십시오.
더 복잡한 솔루션을 사용하면 Thread
을 사용할 수 있습니다,하지만 당신은 UI를 업데이트하는 데 사용할 것이다하는 Runnable
인터페이스를 실행하는 것 EDT 위에 이벤트를 배치 할 SwingUtilities.invokeLater
를 사용하여 UI를 업데이트 할 필요 . 조심스럽게 업데이트 프로세스를 제어하지 않는 한 실제 이벤트가 트리거되기 전에 호출 한 Thread
이 옮겨져 일부 더티 업데이트가 발생할 수 있으므로 동기화 문제가 발생할 수 있습니다 ...
스택 오버플로에 오신 것을 환영합니다! 귀하의 문제를 보여주는 실제 실행 가능한 예제 (https://stackoverflow.com/help/mcve)는 덜 추측적인 작업과 더 나은 응답을 포함합니다. – MadProgrammer
나는 실제 코드가 쓸모가 없기 전에 누군가가 비슷한 문제에 부딪 쳤음에 틀림 없다고 생각했습니다. 그것은 자바 문제가 더 있습니다. JButton -> Red 일시 중지 JButton -> 검정색 – user3667398
놀랄 것입니다. – MadProgrammer