// WormOffscreenApplet.java (c) 2002-2009 Kari Laitinen // http://www.naturalprogramming.com/ // 2006-10-06 File created. // 2009-11-12 Last modification. // This program works as WormApplet.java, but in this version a // technique called double buffering is in use. This means that // everything that is drawn to the screen is first drawn into an // offscreen image, and finally this image is drawn to the screen. // The previous contents of the applet area do not need to be cleared // because the image covers the entire area. // The use of double buffering prevents the flickering of the screen. // In WormPanelApplet.java a JPanel-based object provides automatic double // buffering. import java.awt.* ; import java.util.* ; import javax.swing.* ; public class WormOffscreenApplet extends JApplet implements Runnable { Thread animation_thread ; boolean thread_must_be_executed = false ; Color applet_background_color = new Color( 240, 240, 255 ) ; // blueish Color worm_color = Color.red ; int worm_position_x ; int worm_position_y = 150 ; int worm_length = 100 ; int worm_height = 30 ; int applet_width, applet_height ; Image offscreen_drawing_surface ; // We'll draw everything to this image Graphics offscreen_graphics ; // by using this graphics. public void init() { applet_width = getSize().width ; applet_height = getSize().height ; offscreen_drawing_surface = createImage( applet_width, applet_height ) ; offscreen_graphics = offscreen_drawing_surface.getGraphics() ; } public void start() { if ( animation_thread == null ) { animation_thread = new Thread( this ) ; thread_must_be_executed = true ; animation_thread.start() ; } } public void stop() { if ( animation_thread != null ) { animation_thread.interrupt() ; thread_must_be_executed = false ; animation_thread = null ; } } public void run() { while ( thread_must_be_executed == true ) { worm_position_x = 50 ; worm_length = 100 ; repaint() ; let_this_thread_sleep( 2000 ) ; while ( worm_position_x + worm_length < applet_width && thread_must_be_executed == true ) { for ( int stretchings_counter = 0 ; stretchings_counter < 7 ; stretchings_counter ++ ) { worm_length = worm_length + 5 ; repaint() ; let_this_thread_sleep( 50 ) ; } for ( int shrinkings_counter = 0 ; shrinkings_counter < 7 ; shrinkings_counter ++ ) { worm_length = worm_length - 5 ; worm_position_x = worm_position_x + 5 ; repaint() ; let_this_thread_sleep( 50 ) ; } } let_this_thread_sleep( 4000 ) ; } } void let_this_thread_sleep( int given_sleeping_time_in_milliseconds ) { // We won't let the thread sleep if it is supposed to die. // Without the following if construct the 'behavior' of the // worm is somewhat unpredictable in certain situations when // the applet window is minimized and 'un-minimized'. if ( thread_must_be_executed == true ) { try { Thread.sleep( given_sleeping_time_in_milliseconds ) ; } catch ( InterruptedException caught_exception ) { } } } public void paint( Graphics graphics ) { // The super.paint( graphics ) ; call is missing from this method // because we'll handle all painting by ourselves. // Not calling the superclass paint() method may be problematic // when an applet contains buttons and other widgets. // Let's clear the offscreen imgage and draw everything into // the image. offscreen_graphics.setColor( applet_background_color ) ; offscreen_graphics.fillRect( 0, 0, applet_width, applet_height ) ; offscreen_graphics.setColor( worm_color ) ; offscreen_graphics.fillRoundRect( worm_position_x, worm_position_y, worm_length, worm_height, 20, 20 ) ; // Now we'll draw the offscreen_drawing_surface by using real graphics graphics.drawImage( offscreen_drawing_surface, 0, 0, this ) ; } }