home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / VCSAMPL.BIN / RoundButton.java < prev    next >
Text File  |  1997-03-05  |  5KB  |  195 lines

  1. /*
  2.  * @(#)RoundButton.java    1.5 97/03/05 Jeff Dinkins
  3.  *
  4.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  */
  7.  
  8. import java.applet.*;
  9. import java.lang.*;
  10. import java.util.*;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13.  
  14. /**
  15.  * RoundButton - a class that produces a lightweight button.
  16.  *
  17.  * Lightweight components can have "transparent" areas, meaning that
  18.  * you can see the background of the container behind these areas.
  19.  *
  20.  */
  21. public class RoundButton extends Component {
  22.  
  23.   ActionListener actionListener;     // Post action events to listeners
  24.   String label;                      // The Button's text
  25.   protected boolean pressed = false; // true if the button is detented.
  26.   
  27.   
  28.   /**
  29.    * Constructs a RoundButton with no label.
  30.    */
  31.   public RoundButton() {
  32.       this("");
  33.   }
  34.  
  35.   /**
  36.    * Constructs a RoundButton with the specified label.
  37.    * @param label the label of the button
  38.    */
  39.   public RoundButton(String label) {
  40.       this.label = label;
  41.       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  42.   }
  43.  
  44.   /**
  45.    * gets the label
  46.    * @see setLabel
  47.    */
  48.   public String getLabel() {
  49.       return label;
  50.   }
  51.   
  52.   /**
  53.    * sets the label
  54.    * @see getLabel
  55.    */
  56.   public void setLabel(String label) {
  57.       this.label = label;
  58.       invalidate();
  59.       repaint();
  60.   }
  61.   
  62.   /**
  63.    * paints the RoundButton
  64.    */
  65.   public void paint(Graphics g) {
  66.       int s = Math.min(getSize().width - 1, getSize().height - 1);
  67.       
  68.       // paint the interior of the button
  69.       if(pressed) {
  70.       g.setColor(getBackground().darker().darker());
  71.       } else {
  72.       g.setColor(getBackground());
  73.       }
  74.       g.fillArc(0, 0, s, s, 0, 360);
  75.       
  76.       // draw the perimeter of the button
  77.       g.setColor(getBackground().darker().darker().darker());
  78.       g.drawArc(0, 0, s, s, 0, 360);
  79.       
  80.       // draw the label centered in the button
  81.       Font f = getFont();
  82.       if(f != null) {
  83.       FontMetrics fm = getFontMetrics(getFont());
  84.       g.setColor(getForeground());
  85.       g.drawString(label,
  86.                s/2 - fm.stringWidth(label)/2,
  87.                s/2 + fm.getMaxDescent());
  88.       }
  89.   }
  90.   
  91.   /**
  92.    * The preferred size of the button. 
  93.    */
  94.   public Dimension getPreferredSize() {
  95.       Font f = getFont();
  96.       if(f != null) {
  97.       FontMetrics fm = getFontMetrics(getFont());
  98.       int max = Math.max(fm.stringWidth(label) + 40, fm.getHeight() + 40);
  99.       return new Dimension(max, max);
  100.       } else {
  101.       return new Dimension(100, 100);
  102.       }
  103.   }
  104.   
  105.   /**
  106.    * The minimum size of the button. 
  107.    */
  108.   public Dimension getMinimumSize() {
  109.       return new Dimension(100, 100);
  110.   }
  111.  
  112.   /**
  113.    * Adds the specified action listener to receive action events
  114.    * from this button.
  115.    * @param listener the action listener
  116.    */
  117.    public void addActionListener(ActionListener listener) {
  118.        actionListener = AWTEventMulticaster.add(actionListener, listener);
  119.        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  120.    }
  121.  
  122.    /**
  123.     * Removes the specified action listener so it no longer receives
  124.     * action events from this button.
  125.     * @param listener the action listener
  126.     */
  127.    public void removeActionListener(ActionListener listener) {
  128.        actionListener = AWTEventMulticaster.remove(actionListener, listener);
  129.    }
  130.  
  131.   /**
  132.    * Determine if click was inside round button.
  133.    */
  134.    public boolean contains(int x, int y) {
  135.        int mx = getSize().width/2;
  136.        int my = getSize().height/2;
  137.        return (((mx-x)*(mx-x) + (my-y)*(my-y)) <= mx*mx);
  138.    }
  139.    
  140.    /**
  141.     * Paints the button and distribute an action event to all listeners.
  142.     */
  143.    public void processMouseEvent(MouseEvent e) {
  144.        Graphics g;
  145.        switch(e.getID()) {
  146.           case MouseEvent.MOUSE_PRESSED:
  147.         // render myself inverted....
  148.         pressed = true;
  149.  
  150.             // Repaint might flicker a bit. To avoid this, you can use
  151.             // double buffering (see the Gauge example).
  152.         repaint(); 
  153.         break;
  154.           case MouseEvent.MOUSE_RELEASED:
  155.         if(actionListener != null) {
  156.            actionListener.actionPerformed(new ActionEvent(
  157.            this, ActionEvent.ACTION_PERFORMED, label));
  158.         }
  159.         // render myself normal again
  160.         if(pressed == true) {
  161.         pressed = false;
  162.  
  163.                 // Repaint might flicker a bit. To avoid this, you can use
  164.                 // double buffering (see the Gauge example).
  165.         repaint();
  166.         }
  167.         break;
  168.           case MouseEvent.MOUSE_ENTERED:
  169.  
  170.         break;
  171.           case MouseEvent.MOUSE_EXITED:
  172.         if(pressed == true) {
  173.         // Cancel! Don't send action event.
  174.         pressed = false;
  175.  
  176.                 // Repaint might flicker a bit. To avoid this, you can use
  177.                 // double buffering (see the Gauge example).
  178.         repaint();
  179.  
  180.         // Note: for a more complete button implementation,
  181.         // you wouldn't want to cancel at this point, but
  182.         // rather detect when the mouse re-entered, and
  183.         // re-highlight the button. There are a few state
  184.         // issues that that you need to handle, which we leave
  185.         // this an an excercise for the reader (I always
  186.         // wanted to say that!)
  187.         }
  188.         break;
  189.        }
  190.        super.processMouseEvent(e);
  191.    }
  192.    
  193. }
  194.  
  195.