Java 带条件的停止计时器仅在第一次工作?
我正在写一个“谁想成为百万富翁”的游戏,我已经准备好了一切,只是计时器有问题 游戏是这样运行的:如果用户答对了问题,他/她就会继续。如果没有,比赛就结束了,他们可以选择再次比赛 当游戏第一次运行时,它很好,计时器做它应该做的事情——从30秒开始倒计时,显示秒数 但是,当用户单击“再次播放”按钮时,上一个计时器将继续使用新的计时器。像这样: -timerA在用户丢失之前还有20秒(以a表示) -timerB在下一次玩游戏时开始(用b表示) 输出:20A29B19A28B18A27B17A26B。。。。。。。2a 11b 1a 10b 9b 8b 7b 6b 5b 4b 2b 1b 这是我的定时器类,叫做倒计时:Java 带条件的停止计时器仅在第一次工作?,java,netbeans,timer,timertask,Java,Netbeans,Timer,Timertask,我正在写一个“谁想成为百万富翁”的游戏,我已经准备好了一切,只是计时器有问题 游戏是这样运行的:如果用户答对了问题,他/她就会继续。如果没有,比赛就结束了,他们可以选择再次比赛 当游戏第一次运行时,它很好,计时器做它应该做的事情——从30秒开始倒计时,显示秒数 但是,当用户单击“再次播放”按钮时,上一个计时器将继续使用新的计时器。像这样: -timerA在用户丢失之前还有20秒(以a表示) -timerB在下一次玩游戏时开始(用b表示) 输出:20A29B19A28B18A27B17A26B。。
import java.util.Timer;
import java.util.TimerTask;
public class CountDown {
static Timer timer;
public static int seconds = 30;
public CountDown() {
timer = new Timer();
timer.schedule(new DisplayCountdown(), 0, 1000);
}
class DisplayCountdown extends TimerTask {
int seconds = 30;
public void run() {
if (seconds == 0) {
timer.cancel();
timer.purge();
return;
}
if (seconds > 0) {
PlayFrame.timer.setText("" + seconds); //jLabel used to display seconds
seconds--;
if (seconds < 30) {
if (PlayFrame.right == true) { //check if question was answered correctly
System.out.print("true"); //testing purposes
PlayFrame.right = false;
PlayFrame.showQuestion();
PlayFrame.startTimer();
seconds = 0;
//break;
}
else if (PlayFrame.right == false) {
//break;
}
}
else if (seconds == 0) { //if time runs out its automatic wrong answer
PlayFrame.wrong();
//break;
}
else {
PlayFrame.wrong();
PlayFrame.timer.setText(null);
timer = new Timer();
//break;
}
}
System.out.println(seconds); // for testing purposes only
}
}
}
请提供帮助,如果您需要更多信息,请咨询 您不应该与Swing应用程序一起使用。对于这些,您应该使用,因为这将尊重Swing事件线程。因此,你的问题是没有意义的,我建议你扔掉所有的计时代码,试试合适的计时器。您可以在此处找到教程:
接下来,您将希望摆脱代码正在使用的所有静态方法和字段,并将它们更改为实例字段和方法
显示JLabel中剩余时间的摆动计时器示例:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TimerExample {
private static void createAndShowGui() {
Gui mainPanel = new Gui();
JFrame frame = new JFrame("TimerExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Gui extends JPanel {
private static final long serialVersionUID = 1L;
private static final String PRESS_BUTTON = "Press Button ";
private static final String PRESS_BUTTON_AGAIN = "Press Button Again Within %02d Seconds!";
private static final String YOU_LOSE = "You Lose!";
private static final String YOU_WIN = "You Win!";
private static final int PREF_W = 250;
private static final int PREF_H = 100;
private static final int TOTAL_SECONDS = 20;
private static final int ONE_SECOND = 1000;
private int elapsedSeconds = 0;
private JLabel timerLabel = new JLabel(PRESS_BUTTON);
private JButton button = new JButton("Button");
private Timer myTimer;
public Gui() {
JPanel btnPanel = new JPanel();
btnPanel.add(button);
setLayout(new BorderLayout());
add(btnPanel, BorderLayout.CENTER);
add(timerLabel, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (myTimer != null && myTimer.isRunning()) {
myTimer.stop();
myTimer = null;
timerLabel.setText(YOU_WIN);
} else {
elapsedSeconds = 0;
myTimer = new Timer(ONE_SECOND, new TimerListener());
myTimer.start();
String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS);
timerLabel.setText(text);
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
elapsedSeconds++;
if (elapsedSeconds == TOTAL_SECONDS) {
myTimer.stop();
timerLabel.setText(YOU_LOSE);
} else {
String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS - elapsedSeconds);
timerLabel.setText(text );
}
}
}
}
我建议您将计时器声明移动到JFrame中,然后为每次需要计时器时创建“DisplayCountdown”类的新实例,并将“Timer.schedule(new DisplayCountdown(),0,1000);”行移到别处
如果清除计时器对象,它将被完全重置,因此您无需创建新的计时器对象,只需添加新的计时器任务。已解决,感谢链接 以及有关swing计时器的更多帮助(用于本主题的未来搜索)
publicstaticvoidstarttimer(){
listener=新建ActionListener(){
@凌驾
已执行的公共无效操作(操作事件){
系统输出打印(“操作”);
timerLabel.setText(“+”秒);
秒--;
系统输出打印项次(秒);
如果(秒<0){
系统输出打印(“零”);
错();
}
}
};
displayTimer=新计时器(1000,侦听器);
displayTimer.setInitialDelay(1);
displayTimer.start();
if(right==true){
系统输出打印(“真”);
displayTimer.stop();
右=假;
秒=30;
displayTimer=新计时器(10000,侦听器);
displayTimer.setDelay(10000);
displayTimer.setInitialDelay(1);
displayTimer.start();
}
else if(right==null){
系统输出打印(“空”);
displayTimer.stop();
秒=30;
displayTimer=新计时器(10000,侦听器);
displayTimer.setInitialDelay(1);
displayTimer.setDelay(10000);
displayTimer.start();
}
}
这并不理想。我所有的东西都在工作,只是前一个计时器不会停止,即使我对它调用cancel()和purge()。(是的,我是一个新手)我被动作听众搞糊涂了;因为我是用Netbeans编写的,所以它会自动为我编写。@codeaddick:这不是它是否理想的问题。这是错误的,可能不起作用,纯粹而简单。如果ActionListeners让您感到困惑,我在上面链接的同一教程中有一节介绍如何使用ActionListeners。当然,如果你被卡住了,你随时可以回到这里展示你的尝试。@CodeAddict我也是一个非常新的程序员,我必须说Swing Timer是一个不错的选择。我只用过一次,但很简单。即使我没有使用GUI,我也会在util定时器上使用它。你真的应该接受气垫船的建议。这家伙给出了一个非常好的解释@David Kroukamp我理解这个论点,但我想我可能会选择与SwingWorker一起使用Swing计时器,以防止长时间运行的任务在EDT上结束。然而,你是对的,使用util定时器也可以避免这种情况。@DavidKroukamp:在EDT上运行的任何东西都是如此。摆动计时器严格用于计时,仅此而已。如果代码调用长时间运行的进程,则该进程需要位于后台线程上。Swing计时器的优点是,它的ActionListener代码在EDT上运行,从而使您不必排队等待可运行的。另一方面,对于时间关键型代码,有时还有比util计时器更好的方法?如果我将timer.schedule
行移到run
块中,会有帮助吗?如何添加新的TimerTask?很抱歉,Timer类将我与purge()和cancel()方法混淆。在主应用程序中,我想您将其称为PlayFrame,您将创建一个专用计时器变量,并且每当启动计时器时,都会添加以下行:“Timer.schedule(new DisplayCountdown(),0,1000);”。当倒计时结束时,如果超时,它会自动清除自身,因此除了在DisplayCountdown类和PlayFrame类的错误函数运行时,您不需要在任何地方调用purge。我得到一个包含倒计时的封闭实例。DisplayCountdown是必需的(因为DisplayCountdown在倒计时类中).好的,但如果答案正确,我希望计时器完全消失,不要再使用它,并使用“取消”和“清除”功能创建一个新计时器。使用“取消”和“清除”功能与创建新计时器的操作完全相同,但应能更好地清除存储的内存。在多线程中,最好使用提供的清除功能,如wi就我所知,记忆并没有被清除。它一直在运行,直到达到0才会停止。就像一个执行任务的女人,直到达到
// Reset Everything
PlayFrame.count = 0;
PlayFrame.answer = new String();
PlayFrame.count = 0;
PlayFrame.right = false;
PlayFrame.winnings = 0;
CountDown.seconds = 30;
CountDown.timer = new Timer();
CountDown.timer.cancel();
CountDown.timer.purge();
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TimerExample {
private static void createAndShowGui() {
Gui mainPanel = new Gui();
JFrame frame = new JFrame("TimerExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Gui extends JPanel {
private static final long serialVersionUID = 1L;
private static final String PRESS_BUTTON = "Press Button ";
private static final String PRESS_BUTTON_AGAIN = "Press Button Again Within %02d Seconds!";
private static final String YOU_LOSE = "You Lose!";
private static final String YOU_WIN = "You Win!";
private static final int PREF_W = 250;
private static final int PREF_H = 100;
private static final int TOTAL_SECONDS = 20;
private static final int ONE_SECOND = 1000;
private int elapsedSeconds = 0;
private JLabel timerLabel = new JLabel(PRESS_BUTTON);
private JButton button = new JButton("Button");
private Timer myTimer;
public Gui() {
JPanel btnPanel = new JPanel();
btnPanel.add(button);
setLayout(new BorderLayout());
add(btnPanel, BorderLayout.CENTER);
add(timerLabel, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (myTimer != null && myTimer.isRunning()) {
myTimer.stop();
myTimer = null;
timerLabel.setText(YOU_WIN);
} else {
elapsedSeconds = 0;
myTimer = new Timer(ONE_SECOND, new TimerListener());
myTimer.start();
String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS);
timerLabel.setText(text);
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
elapsedSeconds++;
if (elapsedSeconds == TOTAL_SECONDS) {
myTimer.stop();
timerLabel.setText(YOU_LOSE);
} else {
String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS - elapsedSeconds);
timerLabel.setText(text );
}
}
}
}
public static void startTimer() {
listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.out.print("action");
timerLabel.setText("" + seconds);
seconds--;
System.out.println(seconds);
if (seconds < 0){
System.out.print("zero");
wrong();
}
}
};
displayTimer = new Timer(1000, listener);
displayTimer.setInitialDelay(1);
displayTimer.start();
if (right == true){
System.out.print("true");
displayTimer.stop();
right = false;
seconds = 30;
displayTimer = new Timer(10000, listener);
displayTimer.setDelay(10000);
displayTimer.setInitialDelay(1);
displayTimer.start();
}
else if (right == null){
System.out.print("null");
displayTimer.stop();
seconds = 30;
displayTimer = new Timer(10000, listener);
displayTimer.setInitialDelay(1);
displayTimer.setDelay(10000);
displayTimer.start();
}
}