Exercises

Included below are short-answer and programming exercises. Answers are provided for those exercises whose exercise number is a hyperlink. Because college faculty use these exercises in their exams, we have provided answers to roughly half of the exercises included here.


12.4 Fill in the blanks in each of the following:

  1. The JTextField class inherits directly from ________.
  2. The layout managers discussed in this chapter are ________, ________ and ________.
  3. Container method _________ attaches a GUI component to a container.
  4. Method ________ is called when a mouse button is released (without moving the mouse).
  5. The ________ class is used to create a group of JRadioButtons.

12.5 State whether each of the following is true or false. If false, explain why.

  1. Only one layout manager can be used per Container.
  2. GUI components can be added to a Container in any order in a BorderLayout.
  3. JRadioButtons provide a series of mutually exclusive options (only one can be true at a time).
  4. Graphics method setFont is used to set the font for text fields.
  5. A JList displays a scrollbar if there are more items in the list than can be displayed.
  6. A Mouse object contains a method called mouseDragged.

12.6 State whether each of the following is true or false. If false, explain why.

  1. A JApplet does not have a content pane.
  2. A JPanel is a JComponent.
  3. A JPanel is a Component.
  4. A JLabel is a Container.
  5. A JList is a JPanel.
  6. An AbstractButton is a JButton.
  7. A JTextField is an Object.
  8. ButtonGroup inherits from JComponent.

12.7 Find any error(s) in each of the following and explain how to correct it (them).

  1. import javax.swing.* // include swing package
  2. panelObject.GridLayout( 8, 8 ); // set GridLayout
  3. setLayout( new FlowLayout( FlowLayout.DEFAULT ) );
  4. add( eastButton, EAST ); // BorderLayout

12.8 Create the following GUI. You do not have to provide any functionality.

12.9 Create the following GUI. You do not have to provide any functionality.

12.10 Create the following GUI. You do not have to provide any functionality.

12.11 Create the following GUI. You do not have to provide any functionality.

12.12 Write a temperature conversion program that converts from Fahrenheit to Celsius. The Fahrenheit temperature should be entered from the keyboard (via a JTextField). A JLabel should be used to display the converted temperature. Use the following formula for the conversion:

Celsius = 5 /9 _ (Fahrenheit - 32)

12.13 Enhance the temperature conversion program of Exercise 12.12 by adding the Kelvin temperature scale. The program should also allow the user to make conversions between any two scales. Use the following formula for the conversion between Kelvin and Celsius (in addition to the formula in Exercise 12.12):

Kelvin = Celsius + 273

12.14 Write an application that allows the user to draw a rectangle by dragging the mouse on the application window. The upper- left coordinate should be the location where the user presses the mouse button, and the lower-right coordinate should be the location where the user releases the mouse button. Also display the area of the rectangle in a JLabel in the SOUTH region of a BorderLayout. Use the following formula for the area:

area = width _ height

12.15 Modify the program of Exercise. 12.14 to draw different shapes. The user should be allowed to choose from an oval, an arc, a line, a rectangle with rounded corners and a predefined polygon. Also display the mouse coordinates in the status bar.

12.16 Write a program that will allow the user to draw a shape with the mouse. The shape to draw should be determined by a KeyEvent using the following keys: c draws a circle, o draws an oval, r draws a rectangle and l draws a line. The size and placement of the shape should be determined by the mousePressed and mouseReleased events. Display the name of the current shape in a JLabel in the SOUTH region of a BorderLayout. The initial shape should default to a circle.

12.17 Create an application that enables the user to paint a picture. The user should be able to choose the shape to draw, the color in which the shape should appear and whether the shape should be filled with color. Use the graphical user interface components we discussed in this chapter, such as JComboBoxes, JRadioButtons and JCheckBoxes, to allow the user to select various options. The program should provide a JButton object that allows the user to erase the window.

12.18 Write a program that uses System.out.println statements to print out events as they occur. Provide a JComboBox with a minimum of four items. The user should be able to choose an event to "monitor" from the JComboBox. When that particular event occurs, display information about the event in a message dialog box. Use method toString on the event object to convert it to a string representation.

12.19 Write a program that draws a square. As the mouse is moved over the drawing area, the square should be repainted with the upper-left corner of the square following the exact path of the mouse cursor.

12.20 Modify the program of Fig. 12.19 to incorporate colors. Provide a "toolbar" of JRadioButton objects at the bottom of the window that lists the following six colors: red, black, magenta, blue, green and yellow. The toolbar should consist of six buttons, each with the appropriate color name. When a new color is selected, drawing should occur in the new color.

12.21 Write a program that plays "guess the number" as follows: Your program chooses the number to be guessed by selecting an integer at random in the range 1-1000. The program then displays in a label:

I have a number between 1 and 1000 can you guess my number?
Please enter your first guess.

A JTextField should be used to input the guess. As each guess is input the background color should change to either red or blue. Red indicates that the user is getting "warmer" and blue indicates that the user is getting "colder." A JLabel should display either "Too High" or "Too Low" to help the user zero in on the correct answer. When the user gets the correct answer, "Correct!" should be displayed and the JTextField used for input should be changed to uneditable. A JButton should be provided to allow the user to play the game again. When the JButton is clicked, a new random number should be generated and the input JTextField changed to editable.

12.22 It is often useful to display the events that occur during the execution of a program to help understand when the events occur and how they are generated. Write a program that enables the user to generate and process every event discussed in this chapter. The program should provide methods from the ActionListener, ItemListener, ListSelectionListener, MouseListener, MouseMotionListener and KeyListener interfaces to display messages when the events occur. Use method toString to convert the event objects received in each event handler into a String that can be displayed. Method toString creates a String containing all the information in the event object.

12.23 Modify your solution to Exercise 12.17 to enable the user to select a font and a font size, then type text into a JTextField. When the user presses Enter, the text should be displayed on the background in the chosen font and size. Modify the program further to allow the user to specify the exact position at which the text should be displayed.

12.24 Write a program that allows the user to select a shape from a JComboBox, then draws that shape 20 times with random locations and dimensions in method paint. The first item in the JComboBox should be the default shape that is displayed the first time paint is called.

12.25 Modify Exercise 12.24 to draw each of the 20 randomly sized shapes in a randomly selected color. Use all 13 predefined Color objects in an array of Colors.

12.26 Modify Exercise 12.25 to allow the user to select the color in which shapes should be drawn from a JColorChooser dialog.

12.27 Write a program using methods from interface MouseListener that allows the user to press the mouse button, drag the mouse and release the mouse button. When the mouse is released, draw a rectangle with the appropriate upper-left corner, width and height. (Hint: The mousePressed method should capture the set of coordinates at which the user presses and holds the mouse button initially, and the mouseReleased method should capture the set of coordinates at which the user releases the mouse button. Both methods should store the appropriate coordinate values. All calculations of the width, height and upper-left corner should be performed by the paint method before the shape is drawn.)

12.28 Modify Exercise 12.27 to provided a "rubber-banding" effect. As the user drags the mouse, the user should be able to see the current size of the rectangle to know exactly what the rectangle will look like when the mouse button is released. (Hint: Method mouseDragged should perform the same tasks as mouseReleased.)

12.29 Modify Exercise 12.28 to allow the user to select which shape to draw. A JComboBox should provide options including at least rectangle, oval, line and rounded rectangle.

12.30 Modify Exercise 12.29 to allow the user to select the drawing color from a JColorChooser dialog box.

12.31 Modify Exercise 12.30 to allow the user to specify if a shape should be filled or empty when it is drawn. The user should click a JCheckBox to indicate filled or empty.

12.32 (Painting program) Using the techniques of Exercises 9.28, 9.29, 12.27 through 12.30 and the graphics techniques of Chapter 11, rewrite Exercise 12.31 to allow the user to draw multiple shapes and store each shape in an array of shapes (if you feel ambitious, investigate the capabilities of class Vector in Chapter 23). For this program, create your own classes (like those in the class hierarchy described in Exercises 9.28 and 9.29) from which objects will be created to store each shape the user draws. The classes should store the location, dimensions and color of each shape and should indicate if the shape is filled or unfilled. Your classes should all derive from a class called MyShape that has all the common features of every shape type. Every subclass of MyShape should have its own method draw, which returns void and receives a Graphics object as its argument. When the application window's paint method is called, it should walk through the array of shapes and display each shape by polymorphically calling the shape's draw method (passing the Graphics object as an argument). Each shape's draw method should know how to draw the shape. As a minimum, your program should provide the following classes: MyLine, MyOval, MyRect, MyRoundRect. Design the class hierarchy for maximum software reuse and place all your classes in the package shapes. Import this package into your program.

12.33 Modify Exercise 12.32 to provide an Undo button that can be used repeatedly to undo the last painting operation. If there are no shapes in the array of shapes, the Undo button should be disabled. 


Selected Answers

Included below are answers to approximately half the of the exercises in the Cyber Classroom. We are not able to include answers to every exercise because college faculty use these exercises in their classroom exams.


 12.4 Fill in the blanks in each of the following:

  1. The JTextField class inherits directly from .
    ANS: JTextComponent.
  2. The layout managers discussed in this chapter are , and .
    ANS: FlowLayout, BorderLayout and GridLayout.
  3. Container method attaches a GUI component to a container.
    ANS: add.
  4. Method is called when a mouse button is released (without moving the mouse).
    ANS: mouseClicked.
  5. The class is used to create a group of JRadioButtons.
    ANS: ButtonGroup.

12.5 State whether each of the following is true or false. If false, explain why.

  1. Only one layout manager can be used per Container.
    ANS: True.
  2. GUI components can be added to a Container in any order in a BorderLayout.
    ANS: True.
  3. JRadioButtons provide a series of mutually exclusive options (only one can be true at a time).
    ANS: True.
  4. Graphics method setFont is used to set the font for text fields.
    ANS: False. Component method setFont is used.
  5. A JList displays a scrollbar if there are more items in the list than can be displayed.
    ANS: False. A JList never provides a scrollbar.
  6. A Mouse object contains a method called mouseDragged.
    ANS: False. A Mouse object is not provided by Java.

12.8

// Exercise 12.8 Solution
// Align.java
// This program creates a simple GUI
import javax.swing.*;
import java.awt.*;

public class Align extends JApplet {
   private JButton ok, cancel, help; 
   private JTextField xValue, yValue;
   private JCheckBox snap, show;
   private JLabel xLabel, yLabel;
   private JPanel checkPanel, buttonPanel,
                  fieldPanel1, fieldPanel2,
                  fieldPanel;

   public void init()
   {
      // build checkPanel
      snap = new JCheckBox( "Snap to Grid" );
      show = new JCheckBox( "Show Grid" );
      checkPanel = new JPanel();
      checkPanel.setLayout( new GridLayout( 2 , 1 ) );
      checkPanel.add( snap );
      checkPanel.add( show );

      // build field panel1
      xLabel = new JLabel( "X: " );
      xValue = new JTextField( "8", 3 );
      fieldPanel1 = new JPanel();
      fieldPanel1.setLayout( new FlowLayout( FlowLayout.CENTER, 3, 5 ) );
      fieldPanel1.add( xLabel );
      fieldPanel1.add( xValue );

      yLabel = new JLabel( "Y: " );
      yValue = new JTextField( "8", 3 );
      fieldPanel2 = new JPanel();
      fieldPanel2.setLayout( new FlowLayout( FlowLayout.CENTER, 3, 5 ) );
      fieldPanel2.add( yLabel );
      fieldPanel2.add( yValue );

      fieldPanel = new JPanel();
      fieldPanel.setLayout( new BorderLayout() );
      fieldPanel.add( fieldPanel1, BorderLayout.NORTH );
      fieldPanel.add( fieldPanel2, BorderLayout.SOUTH );
      
      // build button panel
      ok = new JButton( "Ok" );
      cancel = new JButton( "Cancel" );
      help = new JButton( "Help" );
      buttonPanel = new JPanel();
      buttonPanel.setLayout( new GridLayout( 3, 1, 10, 5 ) );
      buttonPanel.add( ok );
      buttonPanel.add( cancel );
      buttonPanel.add( help );

      // set layout for applet
      getContentPane().setLayout( 
            new FlowLayout( FlowLayout.CENTER, 10, 5 ) );
      getContentPane().add( checkPanel );
      getContentPane().add( fieldPanel );
      getContentPane().add( buttonPanel );
   }
}

12.9

// Exercise 12.9 Solution
// Align.java
// This program creates a simple GUI
import javax.swing.*;
import java.awt.*;

public class Align extends JApplet {
   private JButton ok, cancel, help; 
   private JTextField xValue, yValue;
   private JCheckBox snap, show;
   private JLabel xLabel, yLabel;
   private JPanel checkPanel, buttonPanel,
                  fieldPanel1, fieldPanel2,
                  fieldPanel;

   public void init()
   {
      // build checkPanel
      snap = new JCheckBox( "Snap to Grid" );
      show = new JCheckBox( "Show Grid" );
      checkPanel = new JPanel();
      checkPanel.setLayout( new GridLayout( 2 , 1 ) );
      checkPanel.add( snap );
      checkPanel.add( show );

      // build field panel1
      xLabel = new JLabel( "X: " );
      xValue = new JTextField( "8", 3 );
      fieldPanel1 = new JPanel();
      fieldPanel1.setLayout( new FlowLayout( FlowLayout.CENTER, 3, 5 ) );
      fieldPanel1.add( xLabel );
      fieldPanel1.add( xValue );

      yLabel = new JLabel( "Y: " );
      yValue = new JTextField( "8", 3 );
      fieldPanel2 = new JPanel();
      fieldPanel2.setLayout( new FlowLayout( FlowLayout.CENTER, 3, 5 ) );
      fieldPanel2.add( yLabel );
      fieldPanel2.add( yValue );

      fieldPanel = new JPanel();
      fieldPanel.setLayout( new BorderLayout() );
      fieldPanel.add( fieldPanel1, BorderLayout.NORTH );
      fieldPanel.add( fieldPanel2, BorderLayout.SOUTH );
      
      // build button panel
      ok = new JButton( "Ok" );
      cancel = new JButton( "Cancel" );
      help = new JButton( "Help" );
      buttonPanel = new JPanel();
      buttonPanel.setLayout( new GridLayout( 3, 1, 10, 5 ) );
      buttonPanel.add( ok );
      buttonPanel.add( cancel );
      buttonPanel.add( help );

      // set layout for applet
      getContentPane().setLayout( 
            new FlowLayout( FlowLayout.CENTER, 10, 5 ) );
      getContentPane().add( checkPanel );
      getContentPane().add( fieldPanel );
      getContentPane().add( buttonPanel );
   }
}

12.10

// Exercise 12.10 solution
// ColorSelect.java
// This program creates a simple GUI
import javax.swing.*;
import java.awt.*;

public class ColorSelect extends JApplet {
   private JButton ok, cancel; 
   private JCheckBox b, f;
   private JComboBox colorList;
   private JPanel p, p1;

   public void init()
   {
      // applet
      getContentPane().setLayout( new BorderLayout() );

      // north
      colorList = new JComboBox();
      colorList.addItem( "RED" );
      getContentPane().add( colorList, BorderLayout.NORTH );

      // center
      p = new JPanel();
      b = new JCheckBox( "background" );
      f = new JCheckBox( "foreground" );
      p.add( b );
      p.add( f );
      getContentPane().add( p, BorderLayout.CENTER );

      // south
      ok = new JButton( "Ok" );
      cancel = new JButton( "Cancel" );
      p1 = new JPanel();
      p1.add( ok );
      p1.add( cancel );
      getContentPane().add( p1, BorderLayout.SOUTH );
   }
}

12.14

// Exercise 12.14 Solution
// Draw.java
// Program draws a rectangle with the mouse
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Draw extends JFrame {
   private int topX, topY;
   private int width, height;
   private int bottomX, bottomY;
   protected JLabel status;

   public Draw()
   {
      super( "Draw" );
      topX = topY = 0;
      addMouseListener( new MouseHandler( this ) );
      
      status = new JLabel();
      getContentPane().add( status, BorderLayout.SOUTH );
      setSize( 300, 150 );
      show();
   }

   public int getTopX() { return topX; }
   public int getTopY() { return topY; }
   public int getWidth() { return width; }
   public int getHeight() { return height; }
   public int getBottomX() { return bottomX; }
   public int getBottomY() { return bottomY; }
   public void setTopX( int x ) { topX = x; }
   public void setTopY( int y ) { topY = y; }
   public void setBottomX( int x ) { bottomX = x; }
   public void setBottomY( int y ) { bottomY = y; }
   public void setWidth( int w ) { width = w; }
   public void setHeight( int h ) { height = h; }

   public void paint( Graphics g )
   { 
      g.drawRect( topX, topY, width, height ); 
   }

   public static void main( String args[] )
   {
      Draw app = new Draw();
      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );
   }  
}

class MouseHandler extends MouseAdapter {
   private Draw draw;

   public MouseHandler( Draw d ) { draw = d; }

   public void mouseReleased( MouseEvent e )
   {
      draw.setBottomX( e.getX() );
      draw.setBottomY( e.getY() );
      draw.setWidth( Math.abs( draw.getTopX() -
                               draw.getBottomX() ) );
      draw.setHeight( Math.abs( draw.getTopY() -
                                draw.getBottomY() ) );

      draw.setTopX( Math.min( draw.getTopX(), draw.getBottomX() ) );
      draw.setTopY( Math.min( draw.getTopY(), draw.getBottomY() ) );
      draw.status.setText( "Area is " +
                       ( draw.getWidth() * draw.getHeight() ) );
      draw.repaint();
   }

   public void mousePressed( MouseEvent e )
   {
      draw.setTopX( e.getX() );
      draw.setTopY( e.getY() );
   }
}

12.16

// Exercise 12.16 Solution
// DrawIII.java
// Program draws different shapes with the mouse
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class DrawIII extends JFrame {
   private int topX, topY;
   private int width, height, shape;
   private int bottomX, bottomY;
   protected JLabel status;
   public static final int CIRCLE = 0,
                           OVAL = 1,
                           LINE = 2,
                           RECT = 3;

   public DrawIII()
   {
      super( "DrawIII" );
      topX = topY = 0;

      status = new JLabel();
      getContentPane().add( status, BorderLayout.SOUTH );

      addMouseListener( new MouseHandler( this ) );
      addKeyListener( new KeyHandler( this ) );
      setSize( 300, 150 );
      show();
   }

   public int getTopX() { return topX; }
   public int getTopY() { return topY; }
   public int getBottomX() { return bottomX; }
   public int getBottomY() { return bottomY; }
   public void setTopX( int x ) { topX = x; }
   public void setTopY( int y ) { topY = y; }
   public void setBottomX( int x ) { bottomX = x; }
   public void setBottomY( int y ) { bottomY = y; }
   public void setWidth( int w ) { width = w; }
   public void setHeight( int h ) { height = h; }

   public void paint( Graphics g )
   {
      if ( shape != LINE ) {
         topX = Math.min( topX, bottomX );
         topY = Math.min( topY, bottomY );
      }

      switch ( shape ) {
         case CIRCLE:
            g.drawOval( topX, topY, width, width );
            break;
         case OVAL:
            g.drawOval( topX, topY, width, height );
            break;
         case LINE:
            g.drawLine( topX, topY, bottomX, bottomY );
            break;
         case RECT:
            g.drawRect( topX, topY, width, height );
            break;
      }
   }

   public void setShape( int s ) { shape = s; }

   public static void main( String args[] )
   {
      DrawIII app = new DrawIII();
      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );
   }  
}

class MouseHandler extends MouseAdapter {
   private DrawIII draw;

   public MouseHandler( DrawIII d ) { draw = d; }

   public void mouseReleased( MouseEvent e )
   {
      draw.setBottomX( e.getX() );
      draw.setBottomY( e.getY() );
      draw.setWidth( Math.abs( draw.getTopX() -
                               draw.getBottomX() ) );
      draw.setHeight( Math.abs( draw.getTopY() -
                                draw.getBottomY() ) );
      draw.repaint();
   }

   public void mousePressed( MouseEvent e )
   {
      draw.setTopX( e.getX() );
      draw.setTopY( e.getY() );
   }
}

class KeyHandler extends KeyAdapter {
   private DrawIII draw;

   public KeyHandler( DrawIII d ) { draw = d; }

   public void keyTyped( KeyEvent e )
   {
      int s = DrawIII.CIRCLE;

      switch ( e.getKeyChar() ) {
         case 'c': case 'C':
            s = DrawIII.CIRCLE;
            draw.status.setText( "Circle" );
            break;
         case 'o': case 'O':
            s = DrawIII.OVAL;
            draw.status.setText( "Oval" );
            break;
         case 'r': case 'R':
            s = DrawIII.RECT;
            draw.status.setText( "Rectangle" );
            break;
         case 'l': case 'L':
            s = DrawIII.LINE;
            draw.status.setText( "Line" );
            break;
         default:
            draw.status.setText( "Circle" );
            break;
      }

      draw.setShape( s );
   }
}

12.21

// Exercise 12.21 Solution
// GuessGame.java
// Guess the number
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GuessGame extends JFrame {
   private int number, guess;
   private int highest, lowest;
   private JTextField guessInput;
   private JTextField message;
   private JLabel text1, text2;
   private JButton newGame;

   public GuessGame()
   {
      super( "Guess Game" );
      text1 = new JLabel( "I have a number between 1 and 1000." );
      text2 = new JLabel( "Can you guess my" +
                         " number? Enter your Guess:" );

      highest = 0;
      lowest = 1000;
      guessInput = new JTextField( 5 );
      guessInput.addActionListener( new GuessHandler( ) );
      message = new JTextField( "<------------------", 15 );
      message.setEditable( false );

      newGame = new JButton( "New Game" );
      newGame.addActionListener( 
         new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
               message.setText( "<------------------" );
               guessInput.setText( "" );         
               guessInput.setEditable( true );
               theGame();
            }
         }
      );

      Container c = getContentPane();
      c.setLayout( new FlowLayout() );
      c.add( text1 );
      c.add( text2 );
      c.add( guessInput );
      c.add( message );      
      c.add( newGame );
      setSize( 300, 200 );
      show();
      theGame();
   }

   public void theGame()
   {  number = ( int ) ( Math.random() * 1000 + 1 );  }

   public static void main( String args[] )
   {
      GuessGame app = new GuessGame();

      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );
   }

   class GuessHandler implements ActionListener
   {
      public void actionPerformed( ActionEvent e )
      {
         guess = Integer.parseInt( guessInput.getText() );

         if ( guess > number ) {
            message.setText( "Too High" );

            if ( guess < lowest ) {
               lowest = guess;
               setBackground( Color.red );   // warmer
            }
            else
               setBackground( Color.blue );  // colder
         }
         else if ( guess < number ) {
            message.setText( "Too Low" );

            if ( guess > highest ) {
               highest = guess;
               setBackground( Color.red );   // warmer
            }
            else
               setBackground( Color.blue );  // colder
         }
         else {
            message.setText( "Correct!" );
            setBackground( Color.white );
            guessInput.setEditable( false );
            lowest = 1000;
            highest = 0;
         }

         repaint();
      }
   }
}

12.24

// Exercise 12.24 Solution
// SelectShape.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SelectShape extends JFrame {
   private final int CIRCLE = 0;
   private final int SQUARE = 1;
   private final int OVAL = 2;
   private final int RECTANGLE = 3;
   private JComboBox choice;
   private int shape;

   public SelectShape()
   {
      choice = new JComboBox();
      choice.addItem( "Circle" );
      choice.addItem( "Square" );
      choice.addItem( "Oval" );
      choice.addItem( "Rectangle" );

      choice.addItemListener(
         new ItemListener() {
            public void itemStateChanged( ItemEvent e )
            {
               setShape( choice.getSelectedIndex() );
               repaint();
            }
         }
      );

      getContentPane().add( choice, BorderLayout.SOUTH );
      setSize( 300, 200 );
      show();
   }

   public void paint( Graphics g )
   {
      for ( int k = 1; k <= 20; k ++ ) {
         int w = ( int ) ( Math.random() * getSize().width );
         int h = ( int ) ( Math.random() * getSize().height );
         int x = ( int ) ( Math.random() * getSize().width );
         int y = ( int ) ( Math.random() * getSize().height );

         switch ( shape ) {
            case CIRCLE:
               g.drawOval( x, y, w, w );
               break;
            case SQUARE:
               g.drawRect( x, y, w, w );
               break;
            case OVAL:
               g.drawOval( x, y, w, h );
               break;
            case RECTANGLE:
               g.drawRect( x, y, w, h );
               break;
         }
      } 
   }

   public void setShape( int s ) { shape = s; }

   public static void main( String args[] )
   {
      SelectShape app = new SelectShape();

      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );
   }
}

12.28

// Exercise 12.28 Solution
// Draw3.java
// Program draws a rectangle with the mouse
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Draw3 extends JFrame {
   private int topX, topY;
   private int width, height, upperX, upperY;
   private int bottomX, bottomY;

   public Draw3()
   {
      super( "Draw3" );
      addMouseListener( new MouseHandler( this ) );
      addMouseMotionListener( new MouseHandler2( this ) );
      setSize( 300, 200 );
      show();
   }

   public void setTopX( int x ) { topX = x; }
   public void setTopY( int y ) { topY = y; }
   public void setBottomX( int x ) { bottomX = x; }
   public void setBottomY( int y ) { bottomY = y; }

   public void paint( Graphics g )
   {
      width = Math.abs( topX - bottomX );
      height = Math.abs( topY - bottomY );
      upperX = Math.min( topX, bottomX );
      upperY = Math.min( topY, bottomY );

      g.drawRect( upperX, upperY, width, height );
   }

   public static void main( String args[] )
   {
      Draw3 app = new Draw3();

      app.addWindowListener(
         new WindowAdapter() {
            public void windowClosing( WindowEvent e )
            {
               System.exit( 0 );
            }
         }
      );
   }
}

class MouseHandler extends MouseAdapter {
   private Draw3 draw;

   public MouseHandler( Draw3 d ) { draw = d; }

   public void mouseReleased( MouseEvent e )
   {
      draw.setBottomX( e.getX() );
      draw.setBottomY( e.getY() );
      draw.repaint();
   }

   public void mousePressed( MouseEvent e )
   {
      draw.setTopX( e.getX() );
      draw.setTopY( e.getY() );
   }
}

class MouseHandler2 extends MouseMotionAdapter {
   private Draw3 draw;

   public MouseHandler2( Draw3 d ) { draw = d; }

   public void mouseDragged( MouseEvent e )
   {
      draw.setBottomX( e.getX() );
      draw.setBottomY( e.getY() );
      draw.repaint();
   }
}