// ClockApplication.java (c) Kari Laitinen // http://www.naturalprogramming.com/ /* 2014-11-20 File created as a modification of ClockApplet.java 2014-11-20 Last modification. This program prints a clock onto the screen once in every 200 milliseconds. The clock thus seems to run when this program is executing. This program demonstrates: - how to use a thread that maintains animation - how to get the current time and date by "reading" the computer's clock */ import java.awt.* ; import java.awt.event.* ; // WindowListener, WindowEvent import javax.swing.* ; import java.util.* ; // Calendar and GregorianCalendar classes are here. class ClockPanel extends JPanel implements Runnable { static final int HOUR_HAND_LENGTH = 152 ; static final int MINUTE_HAND_LENGTH = 188 ; static final int SECOND_HAND_LENGTH = 200 ; Thread thread_that_runs_the_clock ; boolean thread_must_be_executed ; int panel_width, panel_height ; int clock_center_point_x, clock_center_point_y ; public ClockPanel( int given_width, int given_height ) { panel_width = given_width ; panel_height = given_height ; clock_center_point_x = panel_width / 2 ; clock_center_point_y = panel_height / 2 + 10 ; setBackground( new Color( 210, 255, 210 ) ) ; // Very light green } public void start_animation_thread() { if ( thread_that_runs_the_clock == null ) { thread_must_be_executed = true ; thread_that_runs_the_clock = new Thread( this ) ; thread_that_runs_the_clock.start() ; } } public void stop_animation_thread() { if ( thread_that_runs_the_clock != null ) { thread_that_runs_the_clock.interrupt() ; thread_must_be_executed = false ; thread_that_runs_the_clock = null ; } } public void run() { System.out.print( "\n Method run() started ... " ) ; while ( thread_must_be_executed == true ) { repaint() ; try { Thread.sleep( 200 ) ; // Suspend for 0.2 second. } catch ( InterruptedException caught_exception ) { // No actions to handle the exception. } } System.out.print( "\n Method run() finished ... " ) ; } public void paintComponent( Graphics graphics ) { super.paintComponent( graphics ) ; String[] days_of_week = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } ; String[] names_of_months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" } ; Calendar time_now = new GregorianCalendar() ; int current_year = time_now.get( Calendar.YEAR ) ; int current_day = time_now.get( Calendar.DAY_OF_MONTH ) ; int month_index = time_now.get( Calendar.MONTH ) ; int number_of_day_of_week = time_now.get( Calendar.DAY_OF_WEEK ) ; String current_month = names_of_months[ month_index ] ; String current_day_of_week = days_of_week[ number_of_day_of_week - 1 ] ; int current_hours = time_now.get( Calendar.HOUR_OF_DAY ) ; int current_minutes = time_now.get( Calendar.MINUTE ) ; int current_seconds = time_now.get( Calendar.SECOND ) ; int current_milliseconds = time_now.get( Calendar.MILLISECOND ) ; graphics.drawString( "" + current_day_of_week + ", " + current_month + " " + current_day + ", " + current_year , 20, 20 ) ; graphics.drawString( String.format( "%d:%02d:%02d", current_hours, current_minutes, current_seconds ), 20, 40 ) ; graphics.drawRect( 0, 0, panel_width - 1, panel_height - 1 ) ; // Let's print a 10-point dot in the center of the clock. graphics.fillOval( clock_center_point_x - 5, clock_center_point_y - 5, 10, 10 ) ; // The following loop prints dots on the clock dial. int dot_index = 0 ; while ( dot_index < 60 ) { double dot_angle = dot_index * Math.PI / 30 - Math.PI / 2 ; int dot_position_x = (int) (Math.cos( dot_angle ) * SECOND_HAND_LENGTH + clock_center_point_x ) ; int dot_position_y = (int) (Math.sin( dot_angle ) * SECOND_HAND_LENGTH + clock_center_point_y ) ; int dot_diameter = 4 ; if ( ( dot_index % 5 ) == 0 ) { // Every 5th dot on the clock circle is a larger dot. dot_diameter = 8 ; } graphics.fillOval( dot_position_x - dot_diameter / 2, dot_position_y - dot_diameter / 2, dot_diameter, dot_diameter ) ; dot_index = dot_index + 1 ; } // For every hand of the clock, we'll first calculte the // angle of the hand in question. Then we can calculate the // the coordinates of the end point of the hand, and finally // we'll draw the hand. double hour_hand_angle = ( current_hours * 30 + current_minutes / 2 ) * Math.PI / 180 - Math.PI /2 ; int hour_hand_end_x = (int) ( Math.cos( hour_hand_angle ) * HOUR_HAND_LENGTH + clock_center_point_x ) ; int hour_hand_end_y = (int) ( Math.sin( hour_hand_angle ) * HOUR_HAND_LENGTH + clock_center_point_y ) ; graphics.drawLine( clock_center_point_x, clock_center_point_y, hour_hand_end_x, hour_hand_end_y ) ; double minute_hand_angle = ( (double) current_minutes + (double) current_seconds / 60.0 ) * Math.PI / 30 - Math.PI /2 ; int minute_hand_end_x = (int) ( Math.cos( minute_hand_angle ) * MINUTE_HAND_LENGTH + clock_center_point_x ) ; int minute_hand_end_y = (int) ( Math.sin( minute_hand_angle ) * MINUTE_HAND_LENGTH + clock_center_point_y ) ; graphics.drawLine( clock_center_point_x, clock_center_point_y, minute_hand_end_x, minute_hand_end_y ) ; graphics.setColor( Color.red ) ; double second_hand_angle = ((double) current_seconds + (double) current_milliseconds / 1000.0 ) * Math.PI / 30 - Math.PI /2 ; int second_hand_end_x = (int) ( Math.cos( second_hand_angle ) * SECOND_HAND_LENGTH + clock_center_point_x ) ; int second_hand_end_y = (int) ( Math.sin( second_hand_angle) * SECOND_HAND_LENGTH + clock_center_point_y ) ; graphics.drawLine( clock_center_point_x, clock_center_point_y, second_hand_end_x, second_hand_end_y ) ; } } class ClockFrame extends JFrame implements WindowListener { static final int FRAME_WIDTH = 600 ; static final int FRAME_HEIGHT = 580 ; ClockPanel clock_panel ; public ClockFrame() { setTitle( "ClockApplication.java" ) ; setSize( FRAME_WIDTH, FRAME_HEIGHT ) ; clock_panel = new ClockPanel( FRAME_WIDTH, FRAME_HEIGHT ) ; Container content_pane = getContentPane() ; content_pane.add( clock_panel ) ; addWindowListener( this ) ; } public void windowClosing( WindowEvent event ) { clock_panel.stop_animation_thread() ; setVisible( false ) ; System.exit( 0 ) ; } public void windowActivated( WindowEvent event ) { } public void windowDeactivated( WindowEvent event ) { } public void windowClosed( WindowEvent event ) { clock_panel.stop_animation_thread() ; } public void windowDeiconified( WindowEvent event ) { clock_panel.start_animation_thread() ; } public void windowIconified( WindowEvent event ) { clock_panel.stop_animation_thread() ; } public void windowOpened( WindowEvent event ) { clock_panel.start_animation_thread() ; } } public class ClockApplication { public static void main( String[] not_in_use ) { ClockFrame clock_frame = new ClockFrame() ; clock_frame.setVisible( true ) ; } }