请帮我处理以下代码?(JAVA)

时间:2015-04-26 06:49:55

标签: java

我要做的是:

我正在尝试在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中创建计时器”这个问题。

2 个答案:

答案 0 :(得分:4)

你没有在线程中调用sleep()。你是在事件调度线程中完成的。该线程是处理所有UI事件并在需要时重新绘制UI组件的线程。由于你迫使它永远睡不着,它不能再做这个工作了。

使用javax.swing.Timer

请注意,当计时器位于构造函数中时,它会意外运行:您正在从主线程调用构造函数,因此不会阻止EDT。但这也违反了摆动线程规则:必须始终从EDT创建和访问摆动组件。阅读the tutorial about concurrency in swing

答案 1 :(得分:1)

你接近是完全错误的。 如果你在按钮例程中冻结gui,就像你做的那样,控件永远不会返回,并且它不允许你做任何事情。 按钮例程试图更新gui而不是来自"主循环" ("主循环"也管理gui方面),因此它需要线程中的空闲时间来执行它,但是你再次调用sleep以便gui永远没有时间自我更新。

在可能的情况下,任何软件的正确方法是永远不要冻结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);