/* File: Counter03.java Continuing from Counter02, now we make the private inner class "Runnable". Using threads, we can open two windows both counting down. Calls to Thread.sleep() ensure that the two count downs run concurrently. */ import javax.swing.*; import java.awt.Font ; public class Counter03 { private class Window1 implements Runnable { int start = 10 ; // by default, count down from 10 int xpos = 0 ; // window position int ypos = 0 ; // window position Window1() { // do nothing, use default values } Window1(int n) { start = n ; // count down from n } Window1(int n, int x, int y) { start = n ; // set all parameters xpos = x ; ypos = y ; } public void run() { try { // same old, same old, except we pick a window position // JFrame frame = new JFrame( "Start value =" + start ); JLabel label = new JLabel("Hello, Java!", JLabel.CENTER ); label.setFont( new Font("Serif", Font.BOLD, 36) ) ; frame.getContentPane().add( label ); frame.setSize( 300, 300 ); frame.setLocation( xpos, ypos ); // pick window position frame.setVisible( true ); Thread.sleep(1000) ; for(int i = start ; i >= 0 ; i--) { label.setText( Integer.toString(i) ) ; Thread.sleep(2000) ; } label.setText("Kaboom!") ; Thread.sleep(1000) ; } catch ( InterruptedException e ) { System.out.println("Oh look! an exception!") ; } } } // This time we make two windows // public void doThis() { Window1 w1 = new Window1(13) ; Thread t1 = new Thread(w1) ; t1.start() ; Window1 w2 = new Window1(9, 400, 0) ; Thread t2 = new Thread(w2) ; t2.start() ; // don't quit until both windows have stopped running try { t1.join() ; // wait for w1 to stop t2.join() ; // wait for w2 to stop } catch ( InterruptedException e ) { System.out.println("Oh look! an exception!") ; } System.exit(0) ; } public static void main( String[] args ) { Counter03 obj = new Counter03() ; obj.doThis() ; } }