我试图让容器显示我的数组中的每种颜色。它编译,但它只会显示我所假设的,青色。我以为我的for循环会使用ActionEvent / Listener循环遍历数组中的所有颜色。你看到我做错了吗?感谢。
import java.awt.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Four extends JFrame implements ActionListener {
private final int SIZE = 180;
Color colors[] = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE,
Color.CYAN};
int i;
private Container con = getContentPane();
private JButton button = new JButton("Press Me");
public Four()
{
super("Frame");
setSize(SIZE, SIZE);
con.setLayout(new FlowLayout());
con.add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
for(i=0; i < colors.length; i++) {
con.setBackground(colors[i]);
}
}
public static void main(String[] args) {
Four frame = new Four();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
答案 0 :(得分:3)
Swing是一个单线程环境,这意味着阻止或阻止此线程执行的任何操作都将阻止它处理事件队列中的新事件,包括重绘请求。
Swing也是(大部分),而不是线程安全的,这意味着尝试从事件调度线程外部更新任何UI组件的状态是不安全的。
您的代码中存在问题......
public void actionPerformed(ActionEvent event) {
for(i=0; i < colors.length; i++) {
con.setBackground(colors[i]);
}
}
这意味着只会显示最后一种颜色。
在这种情况下,我建议使用Swing Timer
,它允许您以固定的时间间隔安排回调,这将在事件调度线程的上下文中执行
请查看Concurrency in Swing和How to use Swing Timers了解详情
更新了示例
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
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 Four extends JFrame {
public static void main(String[] args) {
new Four();
}
public Four() {
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.setLayout(new BorderLayout());
frame.add(new FourPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class FourPane extends JPanel {
Color colors[] = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE,
Color.CYAN};
int i;
private JButton button = new JButton("Press Me");
private Timer timer;
public FourPane() {
add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!timer.isRunning()) {
timer.start();
}
}
});
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (i < colors.length) {
setBackground(colors[i]);
} else {
((Timer) e.getSource()).stop();
}
i++;
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(180, 180);
}
}
}
答案 1 :(得分:2)
你将i重新初始化为0,然后每次在actionPerformed中循环到colors.length,这样你就得到了最后一项。请改用它:
public class Four extends JFrame implements ActionListener {
private final int SIZE = 180;
Color colors[] = {Color.RED, Color.ORANGE, Color.YELLOW,
Color.GREEN, Color.BLUE, Color.CYAN};
int i = 0;
private Container con = getContentPane();
private JButton button = new JButton("Press Me");
public Four() {
super("Frame");
setSize(SIZE, SIZE);
con.setLayout(new FlowLayout());
con.add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
con.setBackground(colors[i++ % colors.length]);
}
public static void main(String[] args) {
Four frame = new Four();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}