- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的程序是一个内存游戏。每当点击一个图 block 时,计时器就会启动。我正在尝试创建一个用于暂停和恢复 Swing 计时器的菜单。暂停效果很好;但是,我遇到的问题是,每当我在暂停后恢复计时器时,它都会跳过四秒,而不是继续计时器。计时器的具体方法发布在整个程序代码的下面。这是我目前拥有的:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.*;
import java.util.Collections;
import java.util.Calendar;
import java.time.*;
public class MemoryGame implements ActionListener {
private Timer cdTimer; //Count down timer of 1.5 secs for unmatched pairs
private Timer swTimer; //Main timer for the game
private int count = 0;
private long start = Calendar.getInstance().getTimeInMillis();
private long now;
private long elapsed;
boolean match = false; //Determine if the cdTimer is running or not
private JToggleButton[] buttons;
private JToggleButton first; //Variable for the first button to match
private JLabel time; //Label to hold the
private JMenuItem pause;
private JMenuItem resume;
ArrayList<ImageIcon> iconList = new ArrayList();
ArrayList<JToggleButton> retireButton = new ArrayList();
ImageIcon icon = new ImageIcon("MemoryGame.png");
public MemoryGame() {
JFrame jfrm = new JFrame("Memory Game");
jfrm.setSize(1000, 1000);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setIconImage(icon.getImage());
time = new JLabel("Elapsed time is 00:00:00");
GridLayout layout = new GridLayout(3,4);
JPanel gamePanel = new JPanel();
gamePanel.setLayout(layout);
createIcons(); //set icons for the tiles
buttons = new JToggleButton[12];
for(int i = 0; i < buttons.length; i++) {
JToggleButton btn = new JToggleButton(icon);
buttons[i] = btn;
buttons[i].addActionListener(this);
gamePanel.add(buttons[i]);
}
Collections.shuffle(Arrays.asList(buttons));
Collections.shuffle(iconList);
jfrm.add(gamePanel, BorderLayout.CENTER);
time.setHorizontalAlignment(JLabel.CENTER);
time.setVerticalAlignment(JLabel.CENTER);
jfrm.add(time, BorderLayout.NORTH);
//Create menus
JMenuBar jm = new JMenuBar();
JMenu action = new JMenu("Action");
action.setMnemonic(KeyEvent.VK_A);
JMenu gameTimer = new JMenu("Game Timer");
gameTimer.setMnemonic(KeyEvent.VK_T);
pause = new JMenuItem("Pause", KeyEvent.VK_P);
pause.setAccelerator(KeyStroke.getKeyStroke("control P"));
pause.setEnabled(false);
pause.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
elapsed += now;
swTimer.stop();
}
});
resume = new JMenuItem("Resume", KeyEvent.VK_R);
resume.setAccelerator(KeyStroke.getKeyStroke("control R"));
resume.setEnabled(false);
resume.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
timerContinue();
}
});
gameTimer.add(pause);
gameTimer.add(resume);
action.add(gameTimer);
JMenuItem reveal = new JMenuItem("Reveal", KeyEvent.VK_R);
reveal.addActionListener(this);
action.add(reveal);
action.addSeparator();
JMenuItem exit = new JMenuItem("Exit", KeyEvent.VK_X);
exit.addActionListener(this);
action.add(exit);
JMenu help = new JMenu("Help");
help.setMnemonic(KeyEvent.VK_H);
JMenuItem viewHelp = new JMenuItem("View Help...",
KeyEvent.VK_H);
viewHelp.addActionListener(this);
help.add(viewHelp);
help.addSeparator();
JMenuItem about = new JMenuItem("About", KeyEvent.VK_A);
about.addActionListener(this);
help.add(about);
jm.add(action);
jm.add(help);
jfrm.setJMenuBar(jm);
jfrm.setLocationRelativeTo(null);
jfrm.setVisible(true);
}
public void actionPerformed(ActionEvent e){
//this if makes sure the timer does not restart everytime a button is clicked
if(retireButton.size() == 0){
timerStart();
}
if(swTimer.isRunning()){
pause.setEnabled(true);
resume.setEnabled(true);
}
//this if makes sure no button will be input during the 1.5 secs delay
if(match == false){
JToggleButton btn = (JToggleButton)e.getSource(); //take in button
setIcon(btn);
resetIcon(btn);
//this if makes btn equals the first button if it is null
if(first == null){
first = btn;
return;
}
matching(first, btn);
first = null;
}
}
public void updateTime(){
long temp = Calendar.getInstance().getTimeInMillis();
time.setText("Elapsed time is " + formatTime((long) (temp - start)));
now = temp - start;
}
public void continueTime(){
long temp = Calendar.getInstance().getTimeInMillis();
time.setText("Elapsed time is " + formatTime((long) (temp - start)));
}
private void timerContinue(){
ActionListener timerAL = new ActionListener(){
public void actionPerformed(ActionEvent e){
continueTime();
}
};
//stop the timer if it is still running
if (swTimer != null && swTimer.isRunning()) {
swTimer.stop();
}
swTimer = new Timer(1000, timerAL);
swTimer.setInitialDelay(0);
swTimer.start();
}
public static String formatTime(long ms){
long millis = ms % 1000;
long x = ms / 1000;
long seconds = x % 60;
x /= 60;
long minutes = x % 60;
x /= 60;
long hours = x % 24;
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
//Method to reset the button to game image when it is clicked for a second time
private void resetIcon(JToggleButton btn){
if(!btn.isSelected()){
btn.setIcon(icon);
}
}
private void timerStart(){
ActionListener timerAL = new ActionListener(){
public void actionPerformed(ActionEvent e){
updateTime();
}
};
//stop the timer if it is still running
if (swTimer != null && swTimer.isRunning()) {
swTimer.stop();
}
swTimer = new Timer(1000, timerAL);
swTimer.setInitialDelay(0);
swTimer.start();
}
private void timerStop(){
//if all 12 buttons are matched, then stop the timer
if(retireButton.size() == 12){
long stop = Calendar.getInstance().getTimeInMillis();
time.setText("You finished in " + formatTime((long)(stop-start)));
swTimer.stop();
}
}
//set the icons for the tiles
private void setIcon(JToggleButton btn) {
if(btn == buttons[0] || btn == buttons[1])
btn.setIcon(iconList.get(0));
else if(btn == buttons[2] || btn == buttons[3])
btn.setIcon(iconList.get(1));
else if(btn == buttons[4] || btn == buttons[5])
btn.setIcon(iconList.get(2));
else if(btn == buttons[6] || btn == buttons[7])
btn.setIcon(iconList.get(3));
else if(btn == buttons[8] || btn == buttons[9])
btn.setIcon(iconList.get(4));
else if(btn == buttons[10] || btn == buttons[11])
btn.setIcon(iconList.get(5));
}
//match the two input buttons
private void matching(JToggleButton btn, JToggleButton btn2){
if(btn.isSelected()){
if(btn2.isSelected()){
buttonDisable(btn, btn2); //disable all buttons besides btn, and btn2
if(!btn.getIcon().toString().equals(btn2.getIcon().toString())){
startTime(1, btn, btn2); //start the 1.5 secs countdown
}
else {
retirePair(btn, btn2);
timerStop();
buttonEnable(btn, btn2);
}
}
}
}
private void startTime(int countPassed, JToggleButton btn, JToggleButton btn2){
ActionListener action = new ActionListener(){
public void actionPerformed(ActionEvent e){
if(count == 0){
cdTimer.stop();
match = false; //resets match
unflipPair(btn, btn2); //reset tile to game image again
buttonEnable(btn, btn2);
}
else
count--;
}
};
cdTimer = new Timer(500, action);
cdTimer.start();
match = true;
count = countPassed;
}
//enable buttons other than btn and btn2
private void buttonEnable(JToggleButton btn, JToggleButton btn2){
for(int i = 0; i < buttons.length; i++){
if(buttons[i] != btn && buttons[i] != btn2)
buttons[i].setEnabled(true);
}
}
//disable buttons other than btn and btn2
private void buttonDisable(JToggleButton btn, JToggleButton btn2){
for(int i = 0; i < buttons.length; i++){
if(buttons[i] != btn && buttons[i] != btn2)
buttons[i].setEnabled(false);
}
}
private void unflipPair(JToggleButton btn, JToggleButton btn2){
btn.setIcon(icon);
btn2.setIcon(icon);
btn.setEnabled(true);
btn2.setEnabled(true);
btn.setSelected(false);
btn2.setSelected(false);
}
private void retirePair(JToggleButton btn, JToggleButton btn2){
btn.setSelected(true);
btn2.setSelected(true);
btn.removeActionListener(this);
btn2.removeActionListener(this);
retireButton.add(btn);
retireButton.add(btn2);
}
private void createIcons(){
ImageIcon icon1 = new ImageIcon("1.png");
ImageIcon icon2 = new ImageIcon("2.png");
ImageIcon icon3 = new ImageIcon("3.png");
ImageIcon icon4 = new ImageIcon("4.png");
ImageIcon icon5 = new ImageIcon("5.png");
ImageIcon icon6 = new ImageIcon("6.png");
iconList.add(icon1);
iconList.add(icon2);
iconList.add(icon3);
iconList.add(icon4);
iconList.add(icon5);
iconList.add(icon6);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if(args.length == 0) //java MemoryGame debug increases the string length to 1
new MemoryGame();
else
new MemoryGame(2);
}
});
}
}
这些是 addActionListener:
pause.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
elapsed += now;
swTimer.stop();
}
});
resume.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
timerContinue();
}
});
这是timerContinue方法:
public void continueTime(){
long temp = Calendar.getInstance().getTimeInMillis();
time.setText("Elapsed time is " + formatTime((long) (temp - start)));
}
private void timerContinue(){
ActionListener timerAL = new ActionListener(){
public void actionPerformed(ActionEvent e){
continueTime();
}
};
//stop the timer if it is still running
if (swTimer != null && swTimer.isRunning()) {
swTimer.stop();
}
swTimer = new Timer(1000, timerAL);
swTimer.setInitialDelay(0);
swTimer.start();
}
这是 timeStart() 方法:
public void updateTime(){
long temp = Calendar.getInstance().getTimeInMillis();
time.setText("Elapsed time is " + formatTime((long) (temp - start)));
now = temp - start;
}
private void timerStart(){
ActionListener timerAL = new ActionListener(){
public void actionPerformed(ActionEvent e){
updateTime();
}
};
//stop the timer if it is still running
if (swTimer != null && swTimer.isRunning()) {
swTimer.stop();
}
swTimer = new Timer(1000, timerAL);
swTimer.setInitialDelay(0);
swTimer.start();
}
最佳答案
因此,您捕获了开始
private long start = Calendar.getInstance().getTimeInMillis();
当类第一次实例化时......不确定这是一个好主意,但让我们继续......
当您暂停计时器时...
pause.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
elapsed += now;
swTimer.stop();
}
});
您捕获经过的
时间
当您恢复时钟时...
public void continueTime(){
long temp = Calendar.getInstance().getTimeInMillis();
time.setText("Elapsed time is " + formatTime((long) (temp - start)));
}
private void timerContinue(){
ActionListener timerAL = new ActionListener(){
public void actionPerformed(ActionEvent e){
continueTime();
}
};
//stop the timer if it is still running
if (swTimer != null && swTimer.isRunning()) {
swTimer.stop();
}
swTimer = new Timer(1000, timerAL);
swTimer.setInitialDelay(0);
swTimer.start();
}
您正在使用当前时间并减去 start
,但 start
从未重置,因此它仍在从首次初始化的时间开始计算。
从概念上讲,“可暂停”时钟具有两个重要状态。
所以。当你暂停时钟时,你需要做一些事情......
null
之类的值,这样就很明显了)恢复后,您需要...
开始
时间。开始
时间与现在(时钟滴答作响时)之间的时间totalRunningTime
,这将创建时钟的总体运行时间。简单😁
首先,这个问题本身并不罕见,如果您花一些时间研究这个问题,可以找到许多解决方案。
话虽如此,既然现在已经是 2018 年了,Java 11 也即将面世,您确实应该使用 Java 较新的日期/时间 API,它提供了许多真正有用的 API,包括 Duration
以及独立于底层日历系统处理时间的能力......所以我们不会遇到夏令时的奇怪问题 😝
以下是我使用的一些库代码的示例,它实现了上面的功能。
它的“奇怪”之处在于,它独立于计时系统。也就是说,它不会“滴答作响”。相反,您可以使用 Swing Timer
(在您的情况下)来调用 getDuration
并根据需要更新 UI。
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, LocalDateTime.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
如果您想了解这个概念的实际应用,您可以查看 Adding resume function to stopwatch
关于java - Swing 计时器的暂停和恢复无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52978554/
有什么方法可以恢复删除的元素吗? 这是我删除元素的代码 myFunction() { var width = window.innerWidth; var February = doc
我有一个 TokuDB 表,由于某种原因缺少 ***_status.tokudb 文件。 我还不确定文件是否由于 TokuDB 崩溃而丢失。 问题是: 有没有办法从主要文件和关键文件(我可以从 tok
我正在 Windows 7 (x86) 上运行带有 Workbench 6.3.8 的 32 位 MySQL Server 5.7.22 本地实例(必须选择 32 位版本 - 所以,较旧的版本)。 我
1、备份 <% SQL="backup database 数据库名 to disk='"&Serve
1、ASP中怎么实现SQL数据库备份、恢复! 答:asp在线备份sql server数据库: 1、备份 <% SQL="ba
我在 R 中使用 stats::filter 函数来理解 R 中的 ARIMA 模拟(如在函数 stats::arima.sim 中)和估计。我知道 stats::filter 将线性过滤器应用于向量
我已经浏览了示例应用程序的文档和代码,并发现 files/objectbox/objectbox/data.mdb 是存储所有数据的默认文件。 假设我的理解是正确的,我有几个问题找不到文档: 我想在我
为了恢复非续订订阅类型的 InAppPurchase,我已经实现了服务器来处理此问题。 但在购买过程中,iTunes 有时不会要求用户验证他们的卡详细信息, 在这种情况下,它会在后台发送应用程序并显示
我的问题是寻找cocos2d游戏期间暂停/恢复状态(包括所有需要保存的数据信息)的设计解决方案。 包括但不限于以下情况: 1).用户选择退出,然后弹出一个对话框供用户选择“直接退出”、“暂停”; 2)
在 Mercurial 中,我有一个旧的变更集,除了对单个文件的更改外,它都很好。我将如何恢复对该单个文件的更改? 即使只是能够在上一个变更集中查看文件的状态也会很好,然后我可以剪切和粘贴。 我的 M
我的一项职能遇到了困难。我想做的是计时器在页面加载后立即启动,并且只有一个带有启动/恢复的按钮。我无法在代码中找出需要更改功能的位置。有人可以帮助我吗?谢谢! HTML: , Javascr
我正在阅读Scrap your type classes 。这为类型类提供了替代方案。然而,我被Paul Chiusano的评论所困扰。其中讨论了恢复 do 表示法 语法。 坦白说,我无法理解 ret
当 OrientDB 因某人重新启动机器而非正常关闭时,OrientDB 最终会处于数据恢复失败的状态。对于如何从这种不正常的关闭中正常恢复有什么建议吗?我们正在寻找系统在断电期间能够自行恢复的方法。
我正在构建一个 Electron 应用程序,如果发生崩溃,它必须重新加载渲染进程窗口。 目前我可以从主进程重新启动应用程序 app.relaunch(); app.quit(); 但我无法检测到窗口崩
我有 3 个 Activity ,比如说 MainActivity、 Activity 2 和 Activity 3。 在 MainActivity 中,我有一个按钮(开始/停止),当我单击此按钮时,
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
Twilio 是否支持暂停和恢复内容播放。换句话说,我有相当长的文件将播放给调用者,并且我正在尝试找到一种方法来实现暂停和恢复功能。在播放某些内容的过程中,我希望用户能够按数字暂停,然后再次按数字从音
我已经提交了 A、B、C、D 和 E。我意识到在提交 B 中发生了一些非常糟糕的事情,所以我想回到 A,这次正确地进行之前搞砸了 B 的更改,然后重新应用 C 、 D 和 E 自动。 您可能想知道为什
我的一个文件被“标记为文本”,图标也发生了变化。实际上这是一个 PHP 文件。我尝试过使用 Help -> Find Action -> Mark As 尝试将其恢复为 PHP 突出显示,但它不起作用
我有一些 SSE 程序,可以将循环中的内存归零,当指针未对齐时,它会引发 SIGSEGV进入我的处理程序。我可以在此类处理程序中获取更多信息吗例行公事,现在我不知道它是在哪里完成的,我也可以吗以某种可
我是一名优秀的程序员,十分优秀!