import java.awt.Color; import java.awt.Graphics; import java.awt.Image; // Used to create an image buffer import java.awt.Graphics2D; // Used for anti-aliasing import java.awt.RenderingHints; // Used for anti-aliasing import java.applet.Applet; public class GraphicsMoveObjectsWithThreadAndApplet extends Applet implements Runnable { Thread runner = null; Image image; Graphics graphics; int width = 400, height = 250; int dotSize = 25, dotBlueX = 150, dotBlueY = 70, dotMagentaX = 230, dotMagentaY = 190; int directionBlue = 1, speedBlue = 2, directionMagenta = 1, speedMagenta = 4; public void init() { // Make sure objects can be positioned on the applet window // and set the applet background color, size, and visibility setLayout(null); setBackground(Color.WHITE); setSize(width, height); setVisible(true); } public void start() { // After the applet is initialized, this method will be called; // a thread is started here that will, through the 'run' // method (below), control the movement of the two dots if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { // This method will be called when the user leaves the Web page // on which this applet is running (or manually closes the applet // window if the applet is not being run through a Web browser); // The variable 'runner' will be set to 'null' so that the loop // in the 'run' method (below) will end runner = null; } // Since a timer is not being used, this method should be set to // continuously repeat (loop); a thread is used (below) to pause // the loop, which effectively simulates a timer with an interval public void run() { // This loop condition ensures that the thread will continue to // run only as long as necessary; when the applet is closed, // the 'stop' method is called (above), which will, in turn // (by setting the variable 'runner'), cause this loop to end while (runner != null) { // Update the position/direction of the blue dot dotBlueX += speedBlue * directionBlue; if (dotBlueX < 16 || dotBlueX > width - 18) directionBlue = -directionBlue; // Update the position/direction of the magenta dot dotMagentaX += speedMagenta * directionMagenta; if (dotMagentaX < 16 || dotMagentaX > width - 18) directionMagenta = -directionMagenta; repaint(); try { // Pause for 15/1000 seconds (so that the dots do not move // across the frame too quickly Thread.sleep(15); } catch (InterruptedException e) { // This section is required when using 'Thread.sleep()' } } } public void paint(Graphics g) { // Prepare to create the image on a separate 'Image' instance; this // should prevent flickering by using a "buffer" on which the frame // image will first be drawn before it is displayed to the user image = createImage(width, height); graphics = image.getGraphics(); // This line causes graphics and text to be rendered with anti-aliasing // turned on, making the overall display look smoother and cleaner ((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Draw/Redraw the blue dot graphics.setColor(Color.BLUE); graphics.fillOval(dotBlueX - dotSize / 2, dotBlueY - dotSize / 2, dotSize, dotSize); // Draw/Redraw the magenta dot graphics.setColor(Color.MAGENTA); graphics.fillOval(dotMagentaX - dotSize / 2, dotMagentaY - dotSize / 2, dotSize, dotSize); // Display (Draw) the buffered image on the frame g.drawImage(image, 0, 0, null); } }