默认情况下,应用程序启动单个线程,并在此线程上执行所有计算。当您更改组件的颜色时,只有当程序有空闲时间时,才会重新绘制组件,但由于计算仍在继续,程序从来没有空闲时间。
您需要做的是将此循环中的代码放到另一个线程,并从第二个线程更新GUI。
这是一个小的工作示例,应该让您开始。
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ColorfulButtons extends JFrame {
private JLabel[] labels = new JLabel[5];
// start the application, this starts the original thread
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ColorfulButtons frame = new ColorfulButtons();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ColorfulButtons() {
// create your gui
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
JPanel contentPane = new JPanel();
setContentPane(contentPane);
contentPane.setLayout(new GridLayout(1, 0, 0, 0));
for (int i = 0; i < 5; i++) {
JLabel lbl = new JLabel("TEXT");
add(lbl);
labels[i] = lbl;
}
// start the color changing thread
new Thread(new Runnable() {
public void run() {
doTheThing();
}
// give it a name for debugging
}, "DoTheThingThread").start();
}
private void doTheThing() {
int index = 0;
while (true) {
// put label in final variable so I can use it inside anonymous classes
final JLabel lbl = labels[index];
// make label yellow on Event Dispatch Thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
lbl.setForeground(Color.YELLOW);
}
});
// pause to give the gui time to redraw and process events
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// make label red on Event Dispatch Thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
lbl.setForeground(Color.RED);
}
});
// increment or reset index
if (index < 5 - 1)
index++;
else
index = 0;
}
}
}