我正在尝试制作一个简单的秒表/计时器作为我用 Java 编写的 Rubix 立方体计时器应用程序的一部分。计时器应在释放空格键时开始和结束,每次保存并在之后重置。但是,与手机秒表相比,计时器不准确且落后。
我尝试使用 javax.swing.timer 来增加当前值。
到目前为止这是我的代码:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
public class Panel extends JPanel {
private static final int PANEL_WIDTH = 1000;
private static final int PANEL_HEIGHT = 500;
private static final Dimension D = new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
private static final DecimalFormat df = new DecimalFormat("0.00");
private JLabel timerLabel;
private float currentValue = 0;
private String currentString;
private boolean running = false;
private Timer timer;
private static JTable table;
private static Object[][] data;
private static DefaultTableModel model;
private static JScrollPane scrollPane;
private JPanel timerContainer;
Panel() {
timerLabel = new JLabel("0.00");
timerLabel.setFont(new Font("Consolas", Font.PLAIN, 150));
timerLabel.setForeground(Color.WHITE);
timerLabel.setHorizontalAlignment(JLabel.CENTER);
timerContainer = new JPanel();
timerContainer.setBackground(Color.black);
timerContainer.setLayout(new BorderLayout());
timerContainer.add(new JLabel(), BorderLayout.WEST);
timerContainer.add(timerLabel, BorderLayout.CENTER);
timerContainer.add(new JLabel(), BorderLayout.EAST);
data = new Object[][] {
};
String[] columns = new String[] {
"Number", "Time"
};
model = new DefaultTableModel(data, columns) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
table = new JTable(model);
table.setForeground(Color.WHITE);
table.setBackground(Color.BLACK);
table.setModel(model);
table.setFont(new Font("Consolas", Font.PLAIN, 15));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.getTableHeader().setBackground(Color.darkGray);
table.getTableHeader().setForeground(Color.WHITE);
scrollPane = new JScrollPane(table);
scrollPane.setBounds(0, PANEL_HEIGHT / 2, 200, 500);
scrollPane.getViewport().setBackground(Color.darkGray);
scrollPane.setVisible(true);
this.setFocusable(true);
this.addKeyListener(new AL());
this.setPreferredSize(D);
this.setLayout(new BorderLayout());
this.setBackground(Color.BLACK);
this.add(timerContainer, BorderLayout.CENTER);
this.add(scrollPane, BorderLayout.WEST);
timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
timerLabel.setText(df.format(currentValue));
currentValue += 0.01;
}
});
}
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE & !running) {
timerLabel.setForeground(Color.GREEN);
currentValue = 0;
currentString = String.valueOf(df.format(currentValue));
timerLabel.setText(currentString);
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE & !running) {
timer.start();
running = true;
timerLabel.setForeground(Color.WHITE);
} else if (e.getKeyCode() == KeyEvent.VK_SPACE & running) {
timer.stop();
running = false;
addVal(df.format(currentValue));
}
}
}
public static void addVal(String x) {
int numOfSolve;
int rowCount = model.getRowCount();
if (rowCount > 0) {
numOfSolve = rowCount + 1;
} else {
numOfSolve = 1;
}
Object[] objectVal = { numOfSolve, x };
Object[][] newArr = new Object[Array.getLength(data) + 1][];
newArr[Array.getLength(data)] = objectVal;
model.insertRow(0, objectVal);
}
}