特定 Java Swing 算法中 ActionListener 的延迟?
Delay in ActionListener in specific Java Swing algorithm?
我以前在这里问过这个问题,但由于太不具体而且没有 "minimal reproducible example" 的特点而被删除了。 :)
基本上,只要用户点击 "Start":
,我希望我的算法按如下方式运行
- 在 4x4 按钮网格上,一个随机按钮先变为红色,然后变为黑色,中间有 500 毫秒的延迟。
- 重复6次
这是我尝试实施 "Timer" 延迟的代码,但严重失败:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestMemoryGame extends JFrame {
private JButton[] button = new JButton[16];
private JButton start;
private JPanel grid;
private int counter = 6;
private Timer timer;
private int delay = 500;
private Color babyBlue = new Color(137, 156, 240);
private Color lightRed = new Color(255,69,0);
public TestMemoryGame() {
super();
init();
}
public void init() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
setSize(500, 500);
setBackground(Color.WHITE);
grid = new JPanel(new GridLayout(4, 4));
for (int x = 0; x < 16; x++) {
button[x] = new JButton();
button[x].setBackground(babyBlue);
grid.add(button[x]);
}
grid.setPreferredSize(new Dimension(400, 400));
add(grid);
start = new JButton("START");
start.setBackground(Color.ORANGE);
start.setPreferredSize(new Dimension(150, 30));
GridBagConstraints c = new GridBagConstraints();
c.gridy = 1;
c.insets.top = 10;
add(start, c);
start.addActionListener(startTimer);
timer = new Timer(delay, action);
pack();
setVisible(true);
}
ActionListener startTimer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
}
};
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] array = new int[counter];
for (int x = 0; x < counter; x++) {
array[x] = (int)(Math.random() * 16);
button[array[x]].setBackground(lightRed);
timer.start();
//Delay of 500
timer.stop();
button[array[x]].setBackground(Color.black);
}
}
};
public static void main(String[] args) {
new TestMemoryGame();
}
}
我尝试过很多不同的方法,但我似乎不明白如何正确使用 "Timer"。
如果有人花时间尝试在下面的代码中实现它,我将不胜感激,因为到目前为止,简单地向我解释它并没有带我到任何地方。 :(
非常感谢!
这里有一个明显的问题:
@Override
public void actionPerformed(ActionEvent e) {
int[] array = new int[counter];
for (int x = 0; x < counter; x++) {
array[x] = (int)(Math.random() * 16);
button[array[x]].setBackground(lightRed);
timer.start();
//Delay of 500
timer.stop(); // **** here ****
button[array[x]].setBackground(Color.black);
}
}
您在调用 timer.start()
之后立即调用 timer.stop()
并且没有给计时器机会。也许您想在 Timer 完成其业务后从它自己的 ActionListener 中停止它。
此外,这不编译:
timer = new Timer(delay, action);
在发布的代码中没有任何名为 action
的变量,但在此方法调用中除外,这应该会导致“找不到符号”错误。
所以解决方案可能是:
timer.addActionListener(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (someCondition) {
// do Timer's business repeating until condition is false
} else {
// condition now false
((Timer) e.getSource()).stop(); // stop the Timer
}
}
});
请注意,在 if 块中,您可以递增一个计数器变量,其中一个在启动计时器之前设置为 0,然后在 someCondition
中检查该变量的状态。如果需要,您可以通过这种方式重复一个动作 5 次。
我误读了你在上一个问题中的一个要求:Specific Delay in Java Swing within an ActionListener?,所以我会在这里再次重申我的建议space:
在你的class中:
- 创建一个 ArrayList 作为实例变量,这样您就可以在 ActionListeners 中访问 ArrayList
在添加到按钮的 ActionListener 中,您需要:
- 将要切换颜色的 6 个随机按钮添加到 ArrayList。所以你将创建一个循环来随机选择 6 个按钮。
- 设置 ArrayList 中第一个按钮的颜色
- 启动计时器
然后在定时器的 ActionListener 中:
- 重置 ArrayList 中第一个按钮的颜色
- 从 ArrayList 中删除第一个按钮
- 如果 ArrayList 为空,则停止 Timer
- 否则获取第一个按钮并将颜色更改为红色
因此,当您单击“开始”按钮时,第一个按钮显示为红色。它将保持红色,直到定时器在 500 毫秒后触发,此时它将重置为默认值并更改另一个按钮。定时器将在 500 毫秒后再次触发,并且该过程不断重复。
请注意定时器的 ActionListener 中没有循环代码。定时器将每 500 毫秒持续生成一个事件,直到您停止定时器。
如果您需要更多帮助,请提出后续问题,不要创建新话题。
我以前在这里问过这个问题,但由于太不具体而且没有 "minimal reproducible example" 的特点而被删除了。 :)
基本上,只要用户点击 "Start":
,我希望我的算法按如下方式运行- 在 4x4 按钮网格上,一个随机按钮先变为红色,然后变为黑色,中间有 500 毫秒的延迟。
- 重复6次
这是我尝试实施 "Timer" 延迟的代码,但严重失败:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestMemoryGame extends JFrame {
private JButton[] button = new JButton[16];
private JButton start;
private JPanel grid;
private int counter = 6;
private Timer timer;
private int delay = 500;
private Color babyBlue = new Color(137, 156, 240);
private Color lightRed = new Color(255,69,0);
public TestMemoryGame() {
super();
init();
}
public void init() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
setSize(500, 500);
setBackground(Color.WHITE);
grid = new JPanel(new GridLayout(4, 4));
for (int x = 0; x < 16; x++) {
button[x] = new JButton();
button[x].setBackground(babyBlue);
grid.add(button[x]);
}
grid.setPreferredSize(new Dimension(400, 400));
add(grid);
start = new JButton("START");
start.setBackground(Color.ORANGE);
start.setPreferredSize(new Dimension(150, 30));
GridBagConstraints c = new GridBagConstraints();
c.gridy = 1;
c.insets.top = 10;
add(start, c);
start.addActionListener(startTimer);
timer = new Timer(delay, action);
pack();
setVisible(true);
}
ActionListener startTimer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
}
};
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] array = new int[counter];
for (int x = 0; x < counter; x++) {
array[x] = (int)(Math.random() * 16);
button[array[x]].setBackground(lightRed);
timer.start();
//Delay of 500
timer.stop();
button[array[x]].setBackground(Color.black);
}
}
};
public static void main(String[] args) {
new TestMemoryGame();
}
}
我尝试过很多不同的方法,但我似乎不明白如何正确使用 "Timer"。 如果有人花时间尝试在下面的代码中实现它,我将不胜感激,因为到目前为止,简单地向我解释它并没有带我到任何地方。 :(
非常感谢!
这里有一个明显的问题:
@Override
public void actionPerformed(ActionEvent e) {
int[] array = new int[counter];
for (int x = 0; x < counter; x++) {
array[x] = (int)(Math.random() * 16);
button[array[x]].setBackground(lightRed);
timer.start();
//Delay of 500
timer.stop(); // **** here ****
button[array[x]].setBackground(Color.black);
}
}
您在调用 timer.start()
之后立即调用 timer.stop()
并且没有给计时器机会。也许您想在 Timer 完成其业务后从它自己的 ActionListener 中停止它。
此外,这不编译:
timer = new Timer(delay, action);
在发布的代码中没有任何名为 action
的变量,但在此方法调用中除外,这应该会导致“找不到符号”错误。
所以解决方案可能是:
timer.addActionListener(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (someCondition) {
// do Timer's business repeating until condition is false
} else {
// condition now false
((Timer) e.getSource()).stop(); // stop the Timer
}
}
});
请注意,在 if 块中,您可以递增一个计数器变量,其中一个在启动计时器之前设置为 0,然后在 someCondition
中检查该变量的状态。如果需要,您可以通过这种方式重复一个动作 5 次。
我误读了你在上一个问题中的一个要求:Specific Delay in Java Swing within an ActionListener?,所以我会在这里再次重申我的建议space:
在你的class中:
- 创建一个 ArrayList 作为实例变量,这样您就可以在 ActionListeners 中访问 ArrayList
在添加到按钮的 ActionListener 中,您需要:
- 将要切换颜色的 6 个随机按钮添加到 ArrayList。所以你将创建一个循环来随机选择 6 个按钮。
- 设置 ArrayList 中第一个按钮的颜色
- 启动计时器
然后在定时器的 ActionListener 中:
- 重置 ArrayList 中第一个按钮的颜色
- 从 ArrayList 中删除第一个按钮
- 如果 ArrayList 为空,则停止 Timer
- 否则获取第一个按钮并将颜色更改为红色
因此,当您单击“开始”按钮时,第一个按钮显示为红色。它将保持红色,直到定时器在 500 毫秒后触发,此时它将重置为默认值并更改另一个按钮。定时器将在 500 毫秒后再次触发,并且该过程不断重复。
请注意定时器的 ActionListener 中没有循环代码。定时器将每 500 毫秒持续生成一个事件,直到您停止定时器。
如果您需要更多帮助,请提出后续问题,不要创建新话题。