Java实现时间动态显示方法汇总
本文所述实例可以实现Java在界面上动态的显示时间。具体实现方法汇总如下:
1.方法一用TimerTask:
利用java.util.Timer和java.util.TimerTask来做动态更新,毕竟每次更新可以看作是计时1秒发生一次。
代码如下:
importjava.awt.Dimension; importjava.text.SimpleDateFormat; importjava.util.Calendar; importjava.util.Date; importjava.util.Timer; importjava.util.TimerTask; importjavax.swing.JFrame; importjavax.swing.JLabel; importjavax.swing.JPanel; /** *ThisclassisasimpleJFrameimplementationtoexplainhowto *displaytimedynamicallyontheJSwing-basedinterface. *@authorEdison * */ publicclassTimeFrameextendsJFrame { /* *Variables */ privateJPaneltimePanel; privateJLabeltimeLabel; privateJLabeldisplayArea; privateStringDEFAULT_TIME_FORMAT="HH:mm:ss"; privateStringtime; privateintONE_SECOND=1000; publicTimeFrame() { timePanel=newJPanel(); timeLabel=newJLabel("CurrentTime:"); displayArea=newJLabel(); configTimeArea(); timePanel.add(timeLabel); timePanel.add(displayArea); this.add(timePanel); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(newDimension(200,70)); this.setLocationRelativeTo(null); } /** *Thismethodcreatesatimertasktoupdatethetimepersecond */ privatevoidconfigTimeArea(){ Timertmr=newTimer(); tmr.scheduleAtFixedRate(newJLabelTimerTask(),newDate(),ONE_SECOND); } /** *Timertasktoupdatethetimedisplayarea * */ protectedclassJLabelTimerTaskextendsTimerTask{ SimpleDateFormatdateFormatter=newSimpleDateFormat(DEFAULT_TIME_FORMAT); @Override publicvoidrun(){ time=dateFormatter.format(Calendar.getInstance().getTime()); displayArea.setText(time); } } publicstaticvoidmain(Stringarg[]) { TimeFrametimeFrame=newTimeFrame(); timeFrame.setVisible(true); } }
继承TimerTask来创建一个自定义的task,获取当前时间,更新displayArea.
然后创建一个timer的实例,每1秒执行一次timertask。由于用schedule可能会有时间误差产生,所以直接调用精度更高的scheduleAtFixedRate的。
2.方法二:利用线程:
这个就比较简单了。具体代码如下:
importjava.awt.Dimension; importjava.text.SimpleDateFormat; importjava.util.Calendar; importjavax.swing.JFrame; importjavax.swing.JLabel; importjavax.swing.JPanel; /** *ThisclassisasimpleJFrameimplementationtoexplainhowto *displaytimedynamicallyontheJSwing-basedinterface. *@authorEdison * */ publicclassDTimeFrame2extendsJFrameimplementsRunnable{ privateJFrameframe; privateJPaneltimePanel; privateJLabeltimeLabel; privateJLabeldisplayArea; privateStringDEFAULT_TIME_FORMAT="HH:mm:ss"; privateintONE_SECOND=1000; publicDTimeFrame2() { timePanel=newJPanel(); timeLabel=newJLabel("CurrentTime:"); displayArea=newJLabel(); timePanel.add(timeLabel); timePanel.add(displayArea); this.add(timePanel); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(newDimension(200,70)); this.setLocationRelativeTo(null); } publicvoidrun() { while(true) { SimpleDateFormatdateFormatter=newSimpleDateFormat(DEFAULT_TIME_FORMAT); displayArea.setText(dateFormatter.format( Calendar.getInstance().getTime())); try { Thread.sleep(ONE_SECOND); } catch(Exceptione) { displayArea.setText("Error!!!"); } } } publicstaticvoidmain(Stringarg[]) { DTimeFrame2df2=newDTimeFrame2(); df2.setVisible(true); Threadthread1=newThread(df2); thread1.start(); } }
比较:
个人倾向于方法一,因为Timer是可以被多个TimerTask共用,而产生一个线程,会增加多线程的维护复杂度。
注意如下代码:
jFrame.setDefaultCloseOperation();//给关闭按钮增加特定行为 jFrame.setLocationRelativeTo(null);//让Frame一出来就在屏幕中间,而不是左上方。
将上面方法一稍微一修改,就可以显示多国时间。代码如下:
importjava.awt.BorderLayout; importjava.awt.event.ActionEvent; importjava.awt.event.ActionListener; importjava.text.SimpleDateFormat; importjava.util.Calendar; importjava.util.Date; importjava.util.Locale; importjava.util.TimeZone; importjava.util.Timer; importjava.util.TimerTask; importjavax.swing.DefaultComboBoxModel; importjavax.swing.JComboBox; importjavax.swing.JFrame; importjavax.swing.JLabel; importjavax.swing.JPanel; /** *Asimpleworldclock *@authorEdison * */ publicclassWorldTimeFrameextendsJFrame { /** * */ privatestaticfinallongserialVersionUID=4782486524987801209L; privateStringtime; privateJPaneltimePanel; privateTimeZonetimeZone; privateJComboBoxzoneBox; privateJLabeldisplayArea; privateintONE_SECOND=1000; privateStringDEFAULT_FORMAT="EEEdMMM,HH:mm:ss"; publicWorldTimeFrame() { zoneBox=newJComboBox(); timePanel=newJPanel(); displayArea=newJLabel(); timeZone=TimeZone.getDefault(); zoneBox.setModel(newDefaultComboBoxModel(TimeZone.getAvailableIDs())); zoneBox.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ updateTimeZone(TimeZone.getTimeZone((String)zoneBox.getSelectedItem())); } }); configTimeArea(); timePanel.add(displayArea); this.setLayout(newBorderLayout()); this.add(zoneBox,BorderLayout.NORTH); this.add(timePanel,BorderLayout.CENTER); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); pack(); } /** *Thismethodcreatesatimertasktoupdatethetimepersecond */ privatevoidconfigTimeArea(){ Timertmr=newTimer(); tmr.scheduleAtFixedRate(newJLabelTimerTask(),newDate(),ONE_SECOND); } /** *Timertasktoupdatethetimedisplayarea * */ publicclassJLabelTimerTaskextendsTimerTask{ SimpleDateFormatdateFormatter=newSimpleDateFormat(DEFAULT_FORMAT,Locale.ENGLISH); @Override publicvoidrun(){ dateFormatter.setTimeZone(timeZone); time=dateFormatter.format(Calendar.getInstance().getTime()); displayArea.setText(time); } } /** *UpdatethetimeZone *@paramnewZone */ publicvoidupdateTimeZone(TimeZonenewZone) { this.timeZone=newZone; } publicstaticvoidmain(Stringarg[]) { newWorldTimeFrame(); } }
本来需要在updateTimeZone(TimeZonenewZone)中,更新displayArea的。但是考虑到TimerTask执行的时间太短,才1秒钟,以肉眼观察,基本上是和立刻更新没区别。如果TimerTask执行时间长的话,这里就要立刻重新用心的时间更新一下displayArea。
补充:
①.pack()用来自动计算屏幕大小;
②.TimeZone.getAvailableIDs()用来获取所有的TimeZone。