我要做的是:
我正在尝试在java中创建一个基本的计时器。
我遵循的方法是:
我正在使用Thread.sleep(1000)使主线程休眠1秒钟,并且一旦Thread唤醒代码增量1中的秒字段,并且数分钟和小时都有正常的数学。
代码本身:
public class a extends javax.swing.JFrame {
javax.swing.JTextField text,minute,starter,hours;
a() {
super("Timer!");
try{
javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
} finally {
this.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER,20,20));
text = new javax.swing.JTextField();
hours = new javax.swing.JTextField();
hours.setPreferredSize(new java.awt.Dimension(25,25));
this.add(hours);
minute = new javax.swing.JTextField();
minute.setPreferredSize(new java.awt.Dimension(25,25));
javax.swing.JButton starter = new javax.swing.JButton("Start!");
this.add(minute);
text.setPreferredSize(new java.awt.Dimension(25,25));
this.add(text);
starter.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mouseReleased(java.awt.event.MouseEvent e) {
timer();
}
});
this.add(starter);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
text.setEditable(false);
text.setText("0");
minute.setEditable(false);
hours.setEditable(false);
minute.setText("0");
hours.setText("0");
}
}
private void timer() {
while(true) {
try {
Thread.sleep(1000);
int i = Integer.parseInt(text.getText());
i++;
text.setText(String.valueOf(i%60));
if(i==60) {
i = Integer.parseInt(minute.getText());
i++;
minute.setText(String.valueOf(i));
if(i==60) {
minute.setText("0");
int number = Integer.parseInt(hours.getText());
hours.setText(String.valueOf(++number));
}
}
} catch(Exception e) {
text.setText("crap!");
}
}
}
public static void main(String args[]){
a o = new a();
}
}
我的问题
我的问题或问题是,当我没有使用JButton启动器并且只是在构造函数中调用timer()方法时,计时器就像一个魅力,但是当我使用JButton并且放了计时器时( )调用它的事件监听器按照要求启动计时器,应用程序只是冻结而没有任何反应。
就像我上面提到的,如果我只是在构造函数中调用timer并从应用程序中删除JButton一切正常。但是当使用JButton时(为了手动启动计时器),应用程序就会冻结。
修改
对不起!我忘了提到当应用程序冻结它时点击JButton会冻结。
修改
这个问题不是另一个问题的重复,因为问题是关于如何在java中创建一个计时器,我从来没有要求过!我知道,我在问题中提到的是我在代码中犯了什么错误,其中一个答案解释得很好。我从未问过“如何在java中创建计时器”这个问题。
答案 0 :(得分:4)
你没有在主线程中调用sleep()。你是在事件调度线程中完成的。该线程是处理所有UI事件并在需要时重新绘制UI组件的线程。由于你迫使它永远睡不着,它不能再做这个工作了。
使用javax.swing.Timer
。
请注意,当计时器位于构造函数中时,它会意外运行:您正在从主线程调用构造函数,因此不会阻止EDT。但这也违反了摆动线程规则:必须始终从EDT创建和访问摆动组件。阅读the tutorial about concurrency in swing。
答案 1 :(得分:1)
在可能的情况下,任何软件的正确方法是永远不要冻结gui。使用asynctask或新线程或timertask来测量传递的时间,然后定期更新gui。然后,您将使用按钮启动asynctask或新线程。为此,它充满了样本的互联网。
这是一个例子,尝试一下,让我知道:
import java.util.Timer;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// Your code here
}
}, 1000, 1000);