import java.applet.*; import java.awt.*; import java.awt.Graphics2D; // Used for anti-aliasing import java.awt.RenderingHints; // Used for anti-aliasing // Applet Life Cycle: // init(): called one time so that an applet can be loaded (initialized) // (when a Web browser page is first loaded) // start(): should be called next, and may be called multiple times if the // applet needs to be started or restarted // stop(): should be called to stop the applet from running, and may be // called multiple times in the life cycle of the applet // destroy(): called one time to unload the applet (when the Web browser // window is closed) // The above methods are built into the 'applet' class, but can be overridden public class GraphicsKeyPressWithApplet extends Applet { Image Buffer; Graphics gBuffer; int width, height; boolean pressedLeft, pressedRight, pressedUp, pressedDown; public void init() { pressedLeft = pressedRight = pressedUp = pressedDown = false; width = 300; height = 300; Buffer = createImage(width, height); gBuffer = Buffer.getGraphics(); setFocusable(true); } // Check to see if the user has PRESSED an arrow key; if so, set the // corresponding arrow color to be changed public boolean keyDown(Event e, int key) { if (key == Event.LEFT) pressedLeft = true; if (key == Event.RIGHT) pressedRight = true; if (key == Event.UP) pressedUp = true; if (key == Event.DOWN) pressedDown = true; repaint(); return true; } // Check to see if the user has RELEASED an arrow key; if so, set the // corresponding arrow color to be changed public boolean keyUp(Event e, int key) { if (key == Event.LEFT) pressedLeft = false; if (key == Event.RIGHT) pressedRight = false; if (key == Event.UP) pressedUp = false; if (key == Event.DOWN) pressedDown = false; repaint(); return true; } // This method creates/updates the images to be displayed in the applet; // note that nothing is actually displayed here, though, as all of the // drawing of the graphics takes place via the 'paint' method public void SetImage() { // This line causes graphics and text to be rendered with anti-aliasing // turned on, making the overall display look smoother and cleaner ((Graphics2D) gBuffer).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gBuffer.setColor(Color.blue); gBuffer.fillRect(0, 0, width, height); gBuffer.setFont(new Font("Arial", Font.BOLD, 14)); gBuffer.setColor(Color.white); gBuffer.drawString("Press the four arrow keys...", 52, 30); // LEFT arrow int xLeft[] = {40, 100, 100}; int yLeft[] = {160, 130, 190}; if (pressedLeft) gBuffer.setColor(Color.yellow); else gBuffer.setColor(Color.red); gBuffer.fillPolygon(xLeft, yLeft, 3); // RIGHT arrow int xRight[] = {260, 200, 200}; int yRight[] = {160, 130, 190}; if (pressedRight) gBuffer.setColor(Color.yellow); else gBuffer.setColor(Color.red); gBuffer.fillPolygon(xRight, yRight, 3); // UP arrow int xUp[] = {120, 150, 180}; int yUp[] = {110, 60, 110}; if (pressedUp) gBuffer.setColor(Color.yellow); else gBuffer.setColor(Color.red); gBuffer.fillPolygon(xUp, yUp, 3); // DOWN arrow int xDown[] = {120, 150, 180}; int yDown[] = {210, 260, 210}; if (pressedDown) gBuffer.setColor(Color.yellow); else gBuffer.setColor(Color.red); gBuffer.fillPolygon(xDown, yDown, 3); } // The 'paint' method is called from the 'update' method, and is responsible for // actually drawing the graphics. The method's sole argument is an instance of // the 'Graphics' class. The built-in (default) implementation of the 'paint' // method provided by class 'Component' does nothing, so a new 'paint' method // should always be created to override the default method. // Calls to the 'paint' method can be generated spontaneously by the user's // environment (GUI) or directly by the program (usually via the 'repaint' or // 'update' methods). There are several situations in which calls are // generated spontaneously: // 1) an applet is covered by another applet or a window and is then re-exposed, // at which point the 'paint' method is called to reconstruct the // previously-covered parts of the uncovered applet // 2) the method 'init' has been called and has just finished // 3) a user returns to a Web browser page which contains an applet (provided // the applet is at least partially exposed) // In general, the 'paint' method should not be called directly, but should // instead be called through the 'repaint' method. This way, the abstract // window toolkit (AWT) system thread will take care of accepting input events // and calling the 'paint' method. Programmers should leave the 'paint' // calls to this thread. public void paint(Graphics g) { setSize(width, height); SetImage(); g.drawImage(Buffer, 0, 0, this); } // The 'update' method is automatically called in response to a 'repaint' // request, or in response to a portion of the applet being uncovered or // displayed for the first time. The method's sole argument is an instance // of the 'Graphics' class. The Graphics instance is valid only within the // context of the 'update' method (and any methods that it calls), but is // disposed of soon after the 'update' method returns. // Since the built-in (default) implementation of the 'update' method erases // the background of the applet and then calls the 'paint' method, a new // 'update' method is created below to override the default 'update' method // so that it does NOT erase the background of the applet. Instead, the // new 'update' method will just call the 'paint' method, which can be set // to handle any erasing that needs to take place. // public void update(Graphics g) // { // paint(g); // } // The built-in (default) method 'repaint' does not call (invoke) the 'paint' // method directly. Instead, it SCHEDULES a call to the 'update' method which, // in turn, calls the 'paint' method (unless it has been overridden, in which // case it may or may not call the 'paint' method). The reason for this complex // process is Java's support for concurrent programming (via threads). // The 'repaint' method merely REQUESTS that the abstract window toolkit (AWT) // thread place a call to the method 'update' to repaint a component. It then // returns immediately. This is called asynchronous behavior. How the AWT // thread acts is up to it, and if the programming is not handled carefully, this // can lead to problems, such as multiple 'repaint' requests unintentionally // being combined into a single request. // When the 'repaint' method is called, the calling method may request that // repainting occur as soon as possible, or it may specify a period of time (in // milliseconds), which should cause the painting operation to occur when the // period of time has elapsed. The calling method may also specify that only a // portion of a component be repainted. This technique is useful if the paint // operation is time-consuming, or if only a portion of the display needs to be // repainted. // To reduce the time required to repaint a display, the AWT takes two shortcuts: // First, the AWT repaints only those components that need repainting, either // because they have been uncovered, or because a request was made to repaint // them. Second, if a component was covered and then uncovered, the AWT repaints // only the portion of the component that was previously covered. // public void repaint() // { // } }