所以我正在制作這款游戲??,讓玩家有 30 秒的時間來選擇答案。如果他們選擇一個選項,計時器將重置為 30 秒。
@Override
public void actionPerformed(ActionEvent e) {
//the idea is that when this button is clicked, the timer starts.
if(e.getSource() == button) {
//random gui stuff which i won't include
//calls the method for timer
runner();
}
這是我的 runner() 方法:
public void runner() {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable runnable = new Runnable() {
int countdownStarter = 30;
public void run() {
//this is my JLabel that prints out the timer
label.setText("" countdownStarter);
countdownStarter--;
if (countdownStarter < 0) {
label.setText("");
/*Random GUI stuff here I won't show*/
scheduler.shutdown();
}
}
我的問題是,單擊按鈕時計時器確實會運行,但是它會創建一個新的“計時器”,因此在我的 GUI 上它只是在兩個不同的時間之間閃爍。例如,如果已經存在的計時器為 5 秒(左)并且我單擊按鈕,則 JLabel 文本在 5/30、4/29、3/28、2/27 等之間閃爍,但實際上我只是想要它停止現有的計時器。
不知道我能做什么,我真的很感激任何幫助,因為我對搖擺和 gui 的東西很陌生。
謝謝!
uj5u.com熱心網友回復:
從分離你的擔憂開始。
您有一個機制需要跟蹤按鈕何時被觸發以及它應該倒計時的時間量,并且您有一些更新 UI 的機制。
第一部分非常簡單,您可以簡單地利用java.timeAPI,例如...
public class CountdownTimer {
private Instant startedAt;
private Duration duration;
public CountdownTimer(Duration duration) {
this.duration = duration.plusSeconds(1);
}
public boolean isRunning() {
return startedAt != null;
}
public void start() {
if (startedAt != null) {
return;
}
startedAt = Instant.now();
}
public void stop() {
startedAt = null;
}
public Duration getTimeRemaining() {
return duration.minus(getRunTime());
}
public Duration getRunTime() {
if (startedAt == null) {
return null;
}
return Duration.between(startedAt, Instant.now());
}
}
因此,基于“錨定”時間,您可以計算“運行時間”,然后您可以從中計算“剩余時間”,很簡單。現在,要重置它,您只需呼叫stop一次start。
接下來,我們需要一些方法來更新 UI。Swing 是單執行緒的并且不是執行緒安全的,這意味著您不能在事件調度執行緒的背景關系中運行長時間運行或阻塞操作,并且您不應該從外部更新 UI 或 UI 依賴的任何狀態事件調度執行緒的一側。
最好的選擇是使用SwingTimer,例如......
public class CountdownPane extends JPanel {
private CountdownTimer countdownTimer;
private Timer timer;
public CountdownPane() {
countdownTimer = new CountdownTimer(Duration.ofSeconds(5));
JButton btn = new JButton("Destory the world");
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Duration duration = countdownTimer.getTimeRemaining();
long seconds = duration.toSecondsPart();
if (seconds <= 0) {
countdownTimer.stop();
timer.stop();
btn.setText("Boom");
} else {
btn.setText(format(duration));
}
}
});
timer.setInitialDelay(0);
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(36, 36, 36, 36));
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (countdownTimer.isRunning()) {
countdownTimer.stop();
timer.stop();
btn.setText("Destory the world");
} else {
countdownTimer.start();
timer.start();
}
}
});
add(btn);
}
protected String format(Duration duration) {
long seconds = duration.toSecondsPart();
return String.format("d seconds", seconds);
}
}
可運行的示例...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new CountdownPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CountdownPane extends JPanel {
private CountdownTimer countdownTimer;
private Timer timer;
public CountdownPane() {
countdownTimer = new CountdownTimer(Duration.ofSeconds(5));
JButton btn = new JButton("Destory the world");
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Duration duration = countdownTimer.getTimeRemaining();
long seconds = duration.toSecondsPart();
if (seconds <= 0) {
countdownTimer.stop();
timer.stop();
btn.setText("Boom");
} else {
btn.setText(format(duration));
}
}
});
timer.setInitialDelay(0);
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(36, 36, 36, 36));
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (countdownTimer.isRunning()) {
countdownTimer.stop();
timer.stop();
btn.setText("Destory the world");
} else {
countdownTimer.start();
timer.start();
}
}
});
add(btn);
}
protected String format(Duration duration) {
long seconds = duration.toSecondsPart();
return String.format("d seconds", seconds);
}
}
public class CountdownTimer {
private Instant startedAt;
private Duration duration;
public CountdownTimer(Duration duration) {
this.duration = duration.plusSeconds(1);
}
public boolean isRunning() {
return startedAt != null;
}
public void start() {
if (startedAt != null) {
return;
}
startedAt = Instant.now();
}
public void stop() {
startedAt = null;
}
public Duration getTimeRemaining() {
return duration.minus(getRunTime());
}
public Duration getRunTime() {
if (startedAt == null) {
return null;
}
return Duration.between(startedAt, Instant.now());
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/480827.html
