gpt4 book ai didi

Java - Swing 计时器开始显示的时间比预期晚一些

转载 作者:行者123 更新时间:2023-12-01 17:59:03 25 4
gpt4 key购买 nike

我正在制作一个游戏。我想要一个类似时钟的东西,显示从游戏开始到现在已经过去了多长时间。它工作得几乎很好,但它的启动可能比实际游戏开始晚一两秒。我不知道这是什么原因,所以我将不胜感激任何帮助。谢谢!

我创建了类似的情况(可运行)。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;
import javax.swing.Timer;


public class GUI extends javax.swing.JFrame {

private Timer SimpleTimer;

public GUI() {
initComponents();
}

private void initComponents() {

jLabel1 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(154, 154, 154)
.addComponent(jLabel1))
.addGroup(layout.createSequentialGroup()
.addGap(131, 131, 131)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(196, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(92, Short.MAX_VALUE)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(48, 48, 48)
.addComponent(jLabel1)
.addGap(137, 137, 137))
);

pack();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
startGame();
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
}

private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;

private void startGame() {
long startTime = System.currentTimeMillis();
if(SimpleTimer != null) {
SimpleTimer.stop();
}
SimpleTimer = new Timer(1000, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
long millis = System.currentTimeMillis() - startTime;
jLabel1.setText("Time passed: " + String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
}
});
SimpleTimer.start();
}
}

最佳答案

你的时间计算看起来不太对劲。不应该是这样的吗:

String text = String.format(TIME_FORMAT, 
TimeUnit.MILLISECONDS.toHours(millis) % 24,
TimeUnit.MILLISECONDS.toMinutes(millis) % 60,
TimeUnit.MILLISECONDS.toSeconds(millis) % 60);
timerLabel.setText("Time passed: " + text);

编辑:不,您的转换没​​问题。如果您显示 1 秒单位,我建议您的计时器使用比 1 秒更细的粒度。这里我使用的粒度是100毫秒。

请注意,您的代码无法为我运行(尝试复制并运行您发布的代码以查看它的作用)。

请查看 MCVE 是什么?应如下所示,然后复制并运行此代码以查看是否有效的计时器:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.concurrent.TimeUnit;

import javax.swing.*;

@SuppressWarnings("serial")
public class SimpleTimer extends JPanel {
private static final String TIME_FORMAT = "%02d:%02d:%02d";
public static final int TIMER_DELAY = 100;
private static final int PREF_W = 300;
private static final int PREF_H = 100;
private long startTime;
private Timer myTimer;
private JLabel timerLabel = new JLabel("00:00:00");
private JCheckBox fastChkBox = new JCheckBox("Run Artificially Fast", false);

public SimpleTimer() {
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(new JButton(new RestartAction("Restart", KeyEvent.VK_R)));
centerPanel.add(fastChkBox);

JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Time passed: "));
topPanel.add(timerLabel);

setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}

private class RestartAction extends AbstractAction {
public RestartAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}

@Override
public void actionPerformed(ActionEvent e) {
if (myTimer != null && myTimer.isRunning()) {
myTimer.stop();
}

startTime = System.currentTimeMillis();
myTimer = new Timer(TIMER_DELAY, new TimerListener());
myTimer.start();
}
}

// make it bigger
@Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}


private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
long millis = System.currentTimeMillis() - startTime;

if (fastChkBox.isSelected()) {
millis *= 512; // make time go faster
}
String text = String.format(TIME_FORMAT,
TimeUnit.MILLISECONDS.toHours(millis) % 24,
TimeUnit.MILLISECONDS.toMinutes(millis) % 60,
TimeUnit.MILLISECONDS.toSeconds(millis) % 60);
timerLabel.setText(text);
}
}

private static void createAndShowGui() {
SimpleTimer mainPanel = new SimpleTimer();

JFrame frame = new JFrame("SimpleTimer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
<小时/>

编辑:没有 NetBeans 构建器垃圾的代码:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;

import javax.swing.JPanel;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class GUI extends javax.swing.JFrame {

private Timer SimpleTimer;

public GUI() {
initComponents();
}

private void initComponents() {

jLabel1 = new javax.swing.JLabel(" Time passed: 00:00:00 ");
jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("Restart");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

JPanel btnPanel = new JPanel();
btnPanel.add(jButton1);
JPanel labelPanel = new JPanel();
labelPanel.add(jLabel1);

setLayout(new BorderLayout());
add(labelPanel, BorderLayout.PAGE_START);
add(btnPanel, BorderLayout.CENTER);

pack();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
startGame();
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
}

private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;

private void startGame() {
long startTime = System.currentTimeMillis();
if (SimpleTimer != null) {
SimpleTimer.stop();
}
SimpleTimer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long millis = System.currentTimeMillis() - startTime;
jLabel1.setText("Time passed: " + String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES
.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
}
});
SimpleTimer.start();
}
}

关于Java - Swing 计时器开始显示的时间比预期晚一些,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42376025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com