Like the Aquarium application, where the tank was created in the constructor, the hockey rink is created in Slapshot!'s constructor. Some of this constructor will be familiar from the Aquarium project in the previous chapter, but there's a lot more going on here. To let the user select optionsstarting a game, ending one, setting the speed, and so onthis application uses a menu system. After creating a menu bar, the code creates a File menu and stocks it with items such as Start, End, Set Speed…, and Exit. These menu items are connected to the code using an action listener, which means the Slapshot class must implement the ActionListener interface and add an actionPerformed method to handle menu selections. The menu items are added to a menu, which is then added to the menu bar, which in turn is added to the application itself, as shown here: public class Slapshot extends Frame implements ActionListener, Runnable { . . . Slapshot() { menubar = new MenuBar(); menu1 = new Menu("File"); menuitem0 = new MenuItem("Start"); menu1.add(menuitem0); menuitem0.addActionListener(this); menuitem1 = new MenuItem("End"); menu1.add(menuitem1); menuitem1.addActionListener(this); menuitem2 = new MenuItem("Set speed..."); menu1.add(menuitem2); menuitem2.addActionListener(this); menuitem3 = new MenuItem("Exit"); menu1.add(menuitem3); menuitem3.addActionListener(this); menubar.add(menu1); setMenuBar(menubar); . . . The significant methods of the Menu class appear in Table 2.1, and the significant methods of the MenuItem class appear in Table 2.2.
The constructor next adds a MouseListener and MouseMotionListener to the application to let the user move his blocker with the mouse, and it also implements the MouseListener and MouseMotionListener interfaces. In addition, it creates a dialog box of the OkCancelDialog class (discussed later in the chapter) that's used to let the user enter a new speed:
Slapshot! also needs to display the user's score and the computer's score, and it'll use two AWT Label controls for that. After setting the AWT layout to null, you can use the label's setBounds method to place the labels where you want them: setLayout(null); label1 = new Label(); label1.setText("0"); label1.setBounds(180, 310, 20, 20); label1.setVisible(false); add(label1); label2 = new Label(); label2.setText("0"); label2.setBounds(400, 310, 20, 20); label2.setVisible(false); add(label2); . . . You can see the methods of the Label class in Table 2.3.
Next, a media tracker monitors the loading the images neededthe rink itself, the puck image, and the blocker image (a short upright bar). After that, the main window is sized and displayed: tracker = new MediaTracker(this); backGroundImage = Toolkit.getDefaultToolkit(). getImage("rink.gif"); tracker.addImage(backGroundImage, 0); gifImages[0] = Toolkit.getDefaultToolkit(). getImage("puck.gif"); tracker.addImage(gifImages[0], 0); gifImages[1] = Toolkit.getDefaultToolkit(). getImage("blocker.gif"); tracker.addImage(gifImages[1], 0); try { tracker.waitForID(0); }catch (InterruptedException e) { System.out.println(e); } setTitle("Slapshot!"); setResizable(false); setSize(backGroundImage.getWidth(this), backGroundImage.getHeight(this)); setVisible(true); . . . Finally, the constructor creates a memory image for double buffering, creates and starts the new thread that will move the pucks, and adds a window listener to handle window-closing events: memoryImage = createImage(getSize().width, getSize ().height); memoryGraphics = memoryImage.getGraphics(); thread = new Thread(this); thread.start(); this.addWindowListener(new WindowAdapter(){ public void windowClosing( WindowEvent e){ runOK = false; System.exit(0); } } ); } When the application starts, the constructor runs and the hockey rink appears; to make something actually happen, you have to select the Start item in the File menu. |