Java线程-制作一个时钟和自己的时钟

Java线程-制作一个时钟和自己的时钟,java,multithreading,user-interface,Java,Multithreading,User Interface,所以我开始对线程和它的工作原理非常感兴趣,它的工作原理有点令人惊讶,但我今天刚刚了解了它,并尝试制作一个可以工作的程序。所以我试着制作一个时钟,在Jlabel中给我一个当前的时钟,它就是现在,还有一个我自己输入时间的文本字段。所以我想做的是,它应该首先显示时间,当按下“设置时间”按钮时,它应该改变我输入的时间,然后作为时钟从那里开始 所以我现在的问题是,每当我现在按下设定的时间,它会改变一秒钟,然后再回到当前的时钟。我真的不知道在按Set time(启动第二个线程)时如何停止第一个线程 不过我觉

所以我开始对线程和它的工作原理非常感兴趣,它的工作原理有点令人惊讶,但我今天刚刚了解了它,并尝试制作一个可以工作的程序。所以我试着制作一个时钟,在Jlabel中给我一个当前的时钟,它就是现在,还有一个我自己输入时间的文本字段。所以我想做的是,它应该首先显示时间,当按下“设置时间”按钮时,它应该改变我输入的时间,然后作为时钟从那里开始

所以我现在的问题是,每当我现在按下设定的时间,它会改变一秒钟,然后再回到当前的时钟。我真的不知道在按Set time(启动第二个线程)时如何停止第一个线程

不过我觉得这很简单但很有趣

编辑:我还发现,当我输入自己的“时钟”时,计数会有问题。我的代码:

 public Clock() {
            initialize();
            Thread1();

        }

    .......


JButton btnSetTime = new JButton("Set time");
            btnSetTime.setBounds(474, 262, 89, 23);
            frame.getContentPane().add(btnSetTime);
            btnSetTime.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    if(e.getSource() == btnSetTime) {
                        Thread2();

                    }

                }
            });
        }

        public void Thread2() {
            Thread t2 = new Thread() {
                public void run() {
                    try {
                        for(;;) {
                            int hour = Integer.parseInt(tfhour.getText());
                            int minute = Integer.parseInt(tfminute.getText());
                            int second = Integer.parseInt(tfsecond.getText());

                            lblKlockan.setText(hour + ":" + minute + ":" + second);
                            sleep(1000);
                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
                }
            };t2.start();
        }

        public void Thread1() {
            Thread t1 = new Thread() {
                public void run() {
                    try {
                        for(;;) {
                            Calendar cal = Calendar.getInstance();
                            int hour = cal.get(Calendar.HOUR_OF_DAY);
                            int minute = cal.get(Calendar.MINUTE);
                            int second = cal.get(Calendar.SECOND);

                            lblKlockan.setText(hour + ":" + minute + ":" + second);
                            sleep(1000);
                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
                }
            };t1.start();
        }
    }
如我所见,int hour=Integer.parseInt(tfhour.getText());如果我以后换成自己的时钟,如果我是对的,可能不会算作时钟?那样的话,我该怎么修呢

我希望我在这篇文章中有我所有的问题,我希望这里的任何人也愿意帮助我:)

编辑:

要使其更易于查看,请执行以下操作: 编辑第3部分:0 当然,您可以看到代码

try {
                        for(;;) {
                            int hour = Integer.parseInt(tfhour.getText());//this one
                            int minute = Integer.parseInt(tfminute.getText());//and this one
                            int second = Integer.parseInt(tfsecond.getText());//and this too

                            lblKlockan.setText(hour + ":" + minute + ":" + second);
                            sleep(1000);
                        }

在for循环中,每次都要设置小时、分钟和秒。因此,时钟正在重置

使它们只获得一次初始化,即将它们从循环中取出


进一步修改此代码

for(;;) {
                            Calendar cal = Calendar.getInstance();
                            int hour = cal.get(Calendar.HOUR_OF_DAY);
                            int minute = cal.get(Calendar.MINUTE);
                            int second = cal.get(Calendar.SECOND);

                            lblKlockan.setText(hour + ":" + minute + ":" + second);
                            sleep(1000);
                        }
让你的计时器像时钟一样工作,而不是计时器,因为在1秒之后。小时、分钟和秒根据您从日历中获得的时间设置为值


因此,您的代码将作为显示当前时间的时钟工作。

在我看来,您根本不需要第二个线程。在这种情况下,我要做的是创建三个
Int
字段,即小时、分钟和秒偏移量,当按下按钮时,您可以更改它们,例如,
hourofset=Calendar.hour\u OF_DAY-Integer.parseInt(tfhour.getText())%24(小时数示例)。然后,只需将偏移量添加到线程1中的时间中,该偏移量自以0作为偏移量开始以来一直有效。

当线程2开始时,必须定义一个全局变量来停止线程1。举个例子,

//define a variable that controls the thread 1
static boolean clockSet = false;
现在写入线程1,使其仅在时钟集为false时运行,即不是通过单击设置时钟

  Thread t1 = new Thread(){
        public void run(){
           while(!clockSet){
            Calendar cal = Calendar.getInstance();
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int minute = cal.get(Calendar.MINUTE);
                int second = cal.get(Calendar.SECOND);                   
               lblKlockan.setText(hour + ":" + minute + ":" + second);
               try {
              sleep(1000);
            } catch (InterruptedException e) {
                    e.printStackTrace();
            }
        }
    }
   };
在线程2中,将时钟集设置为true,这样线程1将停止。我看到您只是显示输入的值,而不是在日历对象上设置这些值。因此,在线程2中创建一个日历对象,设置用户定义的值,并增加每秒钟睡眠后的时间

Thread t2 = new Thread(){
    public void run(){
        clockSet = true;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(tfhour.getText()));
        cal.set(Calendar.MINUTE, Integer.parseInt(tfminute.getText()));
        cal.set(Calendar.SECOND, Integer.parseInt(tfsecond.getText()));
        while(true){                    
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int minute = cal.get(Calendar.MINUTE);
                int second = cal.get(Calendar.SECOND);                   
               lblKlockan.setText(hour + ":" + minute + ":" + second);
               try {
            sleep(1000);
            cal.add(Calendar.SECOND, 1);
        } catch (InterruptedException e) {
            e.printStackTrace();}
      }
     }
   };

玩得开心

嗯,我只删除了for循环,结果是一样的,因为另一个线程也使用了for(;;)。但是如果没有它,时钟就无法计数。那可能有什么问题?比如我必须让线程2以某种方式接管线程1,或者在按下按钮时停止线程1并使线程2工作?是的,没错。因此线程1就像时钟一样,而线程2只有我在文本字段中输入的值,我必须使它以某种方式计数(这是我不知道的问题),并且使它从线程1接管,因此它在我的GUI中显示新的时钟。如果你明白我的意思:)@Shivam7357告诉我你想要你的代码做什么:时钟还是计时器?时钟。首先,它以时钟开始,如果我在GUI中输入值,等等,12:12:12。它应该将时钟更新为12:12:12(使用线程2),然后像时钟一样工作。是12:12:13…12:12:14。。。。。谢谢你!是否只有在ActionListiner
public void actionPerformed(ActionEvent e){if(e.getSource()==btnSetTime)中添加了ActionListiner才应该运行{clockSet=true;
在这种情况下也可以,底线是,在启动线程2之前,应该有一个变量来控制线程1的生命周期。为了确保您理解,java中的线程只能根据一个条件停止。因此run方法有这个“while”循环来检查标志并决定以太继续或不继续。请看,我在线程1实现中有逻辑来检查此标志。每当用户单击按钮时,该标志需要设置为true。仅此而已。另外,请注意线程2实现在循环中使用相同的日历对象。好的,我照你说的做了,但遇到了一些问题。因此,每当我现在按下按钮时,它给了我一个冻结的数字,就到此为止。有什么问题吗?这就是为什么你使用布尔值,所以如果它为false,它应该给我们当前时间,当单击按钮时,它应该将布尔值更改为True,它应该但不应该:(给我们我输入的值,而只是冻结,这有点奇怪?