[英]Java Timer Program - rubix cube
我正在嘗試為我的朋友制作一個rubix立方體計時器。 要啟動計時器,請按住空格鍵,然后放開它。 不過,我遇到了一個問題,當我按住空格鍵時,計時器將在任何時間啟動。 我希望能夠將其重置為0,但是每當我嘗試執行此操作時,一切都會出現故障。 誰能告訴我如何修復它,或者如何以更有效的方式做到這一點? 謝謝!
package dev.suns.rubix_timer;
import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class RubixTimerMain extends JFrame {
private JPanel contentPane;
private JLabel labelTimer;
private Timer timer;
public RubixTimerMain() {
createWindow();
}
public static void main(String[] args) {
new RubixTimerMain();
}
private void createWindow() {
// setUndecorated(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(Toolkit.getDefaultToolkit().getScreenSize());
setLocationRelativeTo(null);
setExtendedState(JFrame.MAXIMIZED_BOTH);
contentPane = new JPanel();
contentPane.setBackground(new Color(201, 77, 83));
contentPane.setLayout(null);
setContentPane(contentPane);
addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
startTimer();
}
}
});
JLabel lblMinimize = new JLabel("-");
lblMinimize.setBounds(1835, -20, 16, 95);
lblMinimize.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
setState(JFrame.ICONIFIED);
}
@Override
public void mouseEntered(MouseEvent e) {
lblMinimize.setForeground(Color.BLACK);
}
@Override
public void mouseExited(MouseEvent e) {
lblMinimize.setForeground(Color.WHITE);
}
});
lblMinimize.setForeground(Color.WHITE);
lblMinimize.setFont(new Font("Segoe UI", Font.PLAIN, 40));
contentPane.add(lblMinimize);
JLabel lblX = new JLabel("X");
lblX.setBounds(1873, 0, 24, 54);
lblX.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
System.exit(0);
}
@Override
public void mouseEntered(MouseEvent e) {
lblX.setForeground(Color.BLACK);
}
@Override
public void mouseExited(MouseEvent e) {
lblX.setForeground(Color.WHITE);
}
});
lblX.setFont(new Font("Segoe UI", Font.PLAIN, 40));
lblX.setHorizontalAlignment(SwingConstants.CENTER);
lblX.setForeground(Color.WHITE);
contentPane.add(lblX);
labelTimer = new JLabel("0.0.0");
labelTimer.setHorizontalAlignment(SwingConstants.CENTER);
labelTimer.setFont(new Font("DINPro-Bold", Font.PLAIN, 200));
labelTimer.setForeground(Color.WHITE);
labelTimer.setBounds(371, 134, 1418, 653);
contentPane.add(labelTimer);
setVisible(true);
}
這是我的計時器代碼。 我試圖在幾個不同的地方將cal重置為0,但無法正常工作。
private void startTimer() {
new Thread()
{
public void run()
{
while(true)
{
Calendar cal = new GregorianCalendar();
int minutes = cal.get(Calendar.MINUTE);
int seconds = cal.get(Calendar.SECOND);
int milliseconds = cal.get(Calendar.MILLISECOND);
labelTimer.setText(minutes + "." + seconds + "." + milliseconds);
}
}
}.start();
}
}
一個問題可能是您沒有與EDT(事件調度線程)上的labelTimer
進行交互。
在Swing中,與UI對象的所有交互都必須在此線程上進行。
如果您確保對setText
的調用發生在SwingUtilities#invokeLater
的調用內時會發生什么: https : SwingUtilities#invokeLater
.Runnable)
為了能夠停止計時器線程,您需要使用某種方法在主線程和計時器線程之間進行通信。 RubixTimerMain類的同步成員變量可以做到這一點:
private Boolean isStopped = new Boolean(true);
然后,您可以添加兩種方法。 一個通過設置變量來停止計時器,另一個通過檢查變量的當前狀態來進行。
private void stopTimer(){
synchronized(isStopped){
isStopped = true;
}
}
private boolean isTimerRunning(){
boolean result = false;
synchronized(isStopped){
result = !isStopped;
}
return result;
}
您將需要像這樣更改空格鍵(在createWindow中)的偵聽器事件,以使其開始和停止計時:
addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if (isTimerRunning()){
stopTimer();
} else {
startTimer();
}
}
}
});
最后,您需要調整線程函數,以便僅在stopped狀態變量為false時才運行線程函數。 請注意,它使用isTimerRunning方法,而不是直接訪問該變量。 通過首先將GregorianCalendar的值轉換為毫秒,然后從當前時間中減去記錄的開始時間,也可以解決顯示錯誤時間的錯誤。
private void startTimer() {
new Thread()
{
public void run()
{
long timeStart = new GregorianCalendar().getTimeInMillis();
synchronized(isStopped){
isStopped = false;
}
while(isTimerRunning())
{
long timeNow = new GregorianCalendar().getTimeInMillis() - timeStart;
long milliseconds = (timeNow % 1000);
timeNow = (long) Math.floor(timeNow * 0.001f);
long seconds = (timeNow % 60);
timeNow = (long)Math.floor((float)timeNow / 60f);
long minutes = timeNow;
labelTimer.setText(minutes + "." + seconds + "." + milliseconds);
}
}
}.start();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.