Chapter 15: More Widgets

The exercises here are taken from my forthcoming book, The Java Developer's Resource.

Quiz

  1. What would happen if you tried to set more than one Checkbox in a CheckboxGroup to true initially?

    The last Checkbox that was set to true should be true. All others, including those previously set to true, should be false. This behavior isn't very well defined. I've also seen setting more than one checkbox in a group to true simultaneously cause an application crash, though this theoretically shouldn't happen.

Exercises

  1. Write a Headline Component which implements the same methods as java.awt.Label but draws all text in 24 point Helvetica bold.

  2. Add two constructors to the PanicButton class. One that takes no arguments and produces a PanicButton with a fifty pixel radius, and one that takes an int and produces a PanicButton with that size radius.

    This is a tricky problem. Although it seems simple to add the constructors, you also need to rewrite the paint method to take into account the different possible sizes of the button. The version in the book hardcodes a lot of values that really need to be variables.

    import java.awt.Graphics;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Event;
    import java.awt.Font;
    import java.awt.FontMetrics;
    
    
    public class PanicButton extends Canvas {
    
      int radius;
      
      public PanicButton() {
      
        radius = 50;
      
      }
      
        
      public PanicButton(int r) {
      
        radius = r;
      
      }
    
      public void paint(Graphics g) {
      
        g.setFont(new Font("Helvetica", Font.BOLD, 24));
        FontMetrics fm = g.getFontMetrics();
        int w = fm.stringWidth("Panic");
        int h = fm.getHeight();
        g.setColor(Color.red);
        g.fillOval(0, 0, 2*radius, 2*radius);
        g.setColor(Color.yellow);
        g.drawString("Panic", radius-w/2, radius+h/2);
          
      }
        
      public boolean mouseUp(Event e, int x, int y) {
        
        // Was the click inside the circle??
        if (Math.sqrt( (x-radius)*(x-radius) + 
          (y-radius)*(y-radius)) <= radius)  {
          postEvent(new Event(this, Event.ACTION_EVENT, "Panic"));
          return true;
        }
        else {
          return false;
        }
        
      }
        
      public Dimension minimumSize() {
        return new Dimension(2*radius,2*radius);
      }
    
      public Dimension preferredSize() {
        return minimumSize();
      }
    
    }
    
  3. Write a CircleButton class that creates a circular button as a subclass of Canvas. It should allow (but not require) the creator to specify the label and the radius of the button. Furthermore, it should post an action event if the mouse is pressed and released inside the circle.

    
    import java.awt.Graphics;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Event;
    import java.awt.Font;
    import java.awt.FontMetrics;
    
    
    public class CircleButton extends Canvas {
    
      int radius;
      String label;
      
      public CircleButton() {
      
        label = "Button";
        radius = 50;
      
      }
      
      public CircleButton(String s) {
      
        label = s;
        radius = 50;
      
      }
      
        
      public CircleButton(String s, int r) {
      
        label = s;
        radius = r;
      
      }
    
      public void paint(Graphics g) {
      
        g.setFont(new Font("Helvetica", Font.BOLD, 12));
        FontMetrics fm = g.getFontMetrics();
        int w = fm.stringWidth(label);
        int h = fm.getHeight();
        g.setColor(Color.blue);
        g.fillOval(0, 0, 2*radius, 2*radius);
        g.setColor(Color.black);
        g.drawString(label, radius-w/2, radius+h/2);
          
      }
        
      public boolean mouseUp(Event e, int x, int y) {
        
        // Was the click inside the circle??
        if (Math.sqrt( (x-radius)*(x-radius) + 
          (y-radius)*(y-radius)) <= radius)  {
          postEvent(new Event(this, Event.ACTION_EVENT, label));
          return true;
        }
        else {
          return false;
        }
        
      }
        
      public Dimension minimumSize() {
        return new Dimension(2*radius,2*radius);
      }
    
      public Dimension preferredSize() {
        return minimumSize();
      }
    
    }
    
  4. Add getLabel and setLabel methods to the CircleButton class. If the size of the button was not specified at creation time, adjust the minimum size of the button to be large enough for the text in the current font.

      
      public String getLabel() {
        return label;
      }
      
      
      public void setLabel(String s) {
        label = s;
      }
    
  5. Add setColor, setTextColor and setFont methods to the CircleButton. You now have a fairly generic circular button.

    
    import java.awt.Graphics;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Event;
    import java.awt.Font;
    import java.awt.FontMetrics;
    
    
    public class CircleButton extends Canvas {
    
      int radius;
      String label;
      Color buttonColor;
      Color textColor;
      Font theFont;
      
      public CircleButton() {
      
        label = "Button";
        radius = 50;
      
      }
      
      public CircleButton(String s) {
      
        label = s;
        radius = 50;
      
      }
      
          
      public CircleButton(String s, int r) {
      
        label = s;
        radius = r;
      
      }
      
      public String getLabel() {
        return label;
      }
      
      
      public void setLabel(String s) {
        label = s;
      }
    
      
      public void setFont(Font f) {
        theFont = f;
      }
    
      public void setFont(String s) {
        theFont = new Font(s, Font.BOLD, 12);
      }
      
      
      public void setColor(Color c) {
        buttonColor = c;
      }
      
        
      public void setTextColor(Color c) {
        textColor = c;
      }
    
    
      public void paint(Graphics g) {
      
        g.setFont(theFont);
        FontMetrics fm = g.getFontMetrics();
        int w = fm.stringWidth(label);
        int h = fm.getHeight();
        g.setColor(buttonColor);
        g.fillOval(0, 0, 2*radius, 2*radius);
        g.setColor(textColor);
        g.drawString(label, radius-w/2, radius+h/2);
          
      }
        
      public boolean mouseUp(Event e, int x, int y) {
        
        // Was the click inside the circle??
        if (Math.sqrt( (x-radius)*(x-radius) + 
          (y-radius)*(y-radius)) <= radius)  {
          postEvent(new Event(this, Event.ACTION_EVENT, label));
          return true;
        }
        else {
          return false;
        }
        
      }
        
      public Dimension minimumSize() {
        return new Dimension(2*radius,2*radius);
      }
    
      public Dimension preferredSize() {
        return minimumSize();
      }
    
    }
    


[ Exercises | Cafe Au Lait | Books | Trade Shows | Links | FAQ | Tutorial | User Groups ]

Copyright 1996 Elliotte Rusty Harold
elharo@sunsite.unc.edu
Last Modified August 27, 1996