Below, is a second example program. It draws within a panel contained in an external rrame. It displays up to ten balls which move around the screen following a randomly selected trajectory. Balls can be added or deleted by pressing the appropriate buttons, and the movement of the balls stopped andd restarted. A fifth button allows the user to quit the applet.
Each ball runs as a separate thread, with all threads drawing to the same image. That image is then displayed at once on the panel.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Balls extends Applet implements ActionListener { MyFrame outerBox; Panel drawPanel, bottomPanel, buttonPanel; Button addButton, deleteButton, startButton, stopButton, quitButton; TextField message; Ball balls []; int current = - 1; Image offscreenImage; Graphics offscreenImageG; Graphics drawPanelG; Dimension d; public void init() { buildUI (); d = drawPanel.getSize (); drawPanelG = drawPanel.getGraphics (); offscreenImage = this.createImage ( d.width, d.height ); offscreenImageG = offscreenImage.getGraphics (); offscreenImageG.setColor ( Color.white ); offscreenImageG.fillRect ( 0, 0, d.width, d.height ); balls = new Ball [ 10 ]; run (); } // end init public void run ( ) { while ( true ) { try {Thread.sleep ( 20 );} catch ( InterruptedException e) {;} repaint (); } // end while } // end run // ************* update public void update ( Graphics g ) { paint ( g ); } // end update // ************* paint public void paint ( Graphics g ) { drawPanelG.drawImage ( offscreenImage, 0, 0, this ); } // end paint //*********** Utility Methods *********** public void buildUI () { drawPanel = new Panel ( ); drawPanel.setBackground ( Color.white ); // *** build the buttonPanel panel buttonPanel = new Panel ( ); addButton = new Button ( "Add" ); deleteButton = new Button ( "Delete" ); startButton = new Button ( "Start" ); stopButton = new Button ( "Stop" ); quitButton = new Button ( "Quit" ); addButton.addActionListener ( this ); deleteButton.addActionListener ( this ); startButton.addActionListener ( this ); stopButton.addActionListener ( this ); quitButton.addActionListener ( this ); buttonPanel.add ( addButton ); buttonPanel.add ( deleteButton ); buttonPanel.add ( stopButton ); buttonPanel.add ( startButton ); buttonPanel.add ( quitButton ); // *** build the message display area message = new TextField ( "Messages Displayed Here", 80 ); message.setEditable ( false ); // *** build the bottom panel bottomPanel = new Panel ( ); bottomPanel.setLayout ( new BorderLayout ( ) ); bottomPanel.add ( "North", buttonPanel ); bottomPanel.add ( "South", message ); bottomPanel.setBackground (Color.white); outerBox = new MyFrame ( ); outerBox.addWindowListener ( outerBox ); outerBox.add ( "Center", drawPanel ); outerBox.add ( "South", bottomPanel ); outerBox.resize ( 500, 400 ); outerBox.show (); } // end buildUI //*********** Interface Methods *********** //**** ActionListener methods public void actionPerformed ( ActionEvent e ) { Object s = e.getSource(); if ( s == addButton ) { if ( current < 9 ) { ++current; balls [current] = new Ball ( offscreenImageG, d ); balls[current].start(); message.setText ( (current+1)+" ball(s); room for "+(9-current)+" more." ); } // end if else { message.setText ( "Maximum number of balls exceeded." ); } // end else } // end addButton if ( s == deleteButton ) { synchronized ( offscreenImageG ) { balls[current].delete(); balls[current].stop(); } // end synchronized --current; message.setText ( "Ball deleted; room for "+(9-current)+" more." ); } // end deleteButton if ( s == startButton ) { for ( int i = 0; i <= current; i++ ) { balls[i].resume(); message.setText ( "Action resumed." ); } // end for } // end startButton if ( s == stopButton ) { for ( int i = 0; i <= current; i++ ) { balls[i].suspend(); } // end for message.setText ( "Action suspended." ); } // end stopButton if ( s == quitButton ) { for ( int i = 0; i <= current; i++ ) { balls[i].stop(); } // end for message.setText ( "Applet quitting." ); outerBox.hide (); outerBox.dispose (); System.exit (0); } // end stopButton } // end actionPerformed } // end Balls //******************************* Ball Class **************** class Ball extends Thread { Graphics g; Dimension d; int delay; static Random random = new Random(); int x, y; long inc, xinc, yinc, theta; int left, right, top, bottom; Color color; int diameter; Ball ( Graphics dg, Dimension dd ) { super (); g = dg; d= dd; init (); } // end constructor public void run () { try { while ( true ) { synchronized ( g ) { g.setColor ( Color.white ); g.fillOval ( x, y, diameter, diameter ); moveBall (); g.setColor ( color ); g.fillOval ( x, y, diameter, diameter ); } // end synchronized sleep ( delay ); } // end while } // end try catch ( InterruptedException except) { System.out.println ( "Interrupt in Ball" ); return; } // end catch } // end run private void init () { diameter = 50; inc = 3; delay = 15 - (int) (10 * random.nextFloat() ); boolean test = true; while ( test ) { x = (int)( (d.width - diameter) * random.nextFloat () ); y = (int)( (d.height - diameter) * random.nextFloat () ); if ( ( x > 5 ) && ( y > 5 ) ) test = false; } // end while test = true; while ( test ) { theta = (long)( 360 * random.nextFloat () ); xinc = (long)(inc * Math.cos ( theta ) ); yinc = (long)(inc * Math.sin ( theta ) ); if ( (Math.abs(xinc) > 1 ) && (Math.abs(yinc) > 1) ) test = false; } // end while left = 0; right = d.width - diameter; top = 0; bottom = d.height - diameter ; int rd = (int)( 255 * random.nextFloat () ); int gr = (int)( 255 * random.nextFloat () ); int bl = (int)( 255 * random.nextFloat () ); color = new Color ( rd, gr, bl ); } // end init public void delete () { g.setColor ( Color.white ); g.fillOval ( x, y, diameter, diameter ); } // end delete; //*********** Utility Methods *********** private void moveBall () { if ( (int)(x + xinc) > right || (int)(x + xinc) < left ) { xinc = -1 * xinc; } else x = (int)(x + xinc); if ( (int)(y + yinc) > bottom || (int)(y + yinc) < top ) { yinc = -1 * yinc; } else y = (int)(y + yinc); } // end moveBall } // end BallRun the applet