home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / Chip_1998-07_cd.bin / zkuste / JBuilder / BDK / Win / bdk_sep97.exe / _SETUP.1 / OurButton.java < prev    next >
Encoding:
Java Source  |  1997-09-10  |  9.9 KB  |  400 lines

  1.  
  2. package sunw.demo.buttons;
  3.  
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.beans.*;
  7. import java.io.Serializable;
  8. import java.util.Vector;
  9.  
  10.  
  11. /**
  12.  * A simple Java Beans button.  OurButton is a "from-scratch" 
  13.  * lightweight AWT component.  It's a good example of how to
  14.  * implement bound properties and support for event listeners.
  15.  *
  16.  * Parts of the source are derived from sun.awt.tiny.TinyButtonPeer.
  17.  */
  18.  
  19. public class OurButton extends Component implements Serializable,
  20.                 MouseListener, MouseMotionListener {
  21.  
  22.     /**
  23.      * Constructs a Button with the a default label.
  24.      */
  25.     public OurButton() {
  26.     this("press");
  27.     }
  28.  
  29.     /**
  30.      * Constructs a Button with the specified label.
  31.      * @param label the label of the button
  32.      */
  33.     public OurButton(String label) {
  34.     super();
  35.     this.label = label;
  36.     setFont(new Font("Dialog", Font.PLAIN, 12));
  37.     setBackground(Color.lightGray);
  38.     addMouseListener(this);
  39.     addMouseMotionListener(this);
  40.     }
  41.  
  42.     //----------------------------------------------------------------------
  43.  
  44.     /**
  45.      * Paint the button: the label is centered in both dimensions.
  46.      * 
  47.      */
  48.     public synchronized void paint(Graphics g) {
  49.     int width = getSize().width;
  50.     int height = getSize().height;
  51.  
  52.     g.setColor(getBackground());
  53.     g.fill3DRect(0, 0, width - 1, height - 1, !down);
  54.  
  55.     g.setColor(getForeground());
  56.     g.setFont(getFont());
  57.  
  58.     g.drawRect(2, 2, width - 4, height - 4);
  59.  
  60.     FontMetrics fm = g.getFontMetrics();
  61.     g.drawString(label, (width - fm.stringWidth(label)) / 2, 
  62.                   (height + fm.getMaxAscent() - fm.getMaxDescent()) / 2);
  63.     }    
  64.  
  65.     //----------------------------------------------------------------------
  66.  
  67.     // Mouse listener methods.
  68.  
  69.     public void mouseClicked(MouseEvent evt) {
  70.     }
  71.  
  72.     public void mousePressed(MouseEvent evt) {
  73.     if (!isEnabled()) {
  74.         return;
  75.     }
  76.     down = true;
  77.     repaint();
  78.     }
  79.  
  80.     public void mouseReleased(MouseEvent evt) {
  81.     if (!isEnabled()) {
  82.         return;
  83.     }
  84.     if (down) {
  85.         fireAction();
  86.         down = false;
  87.         repaint();
  88.     }
  89.     }
  90.  
  91.     public void mouseEntered(MouseEvent evt) {
  92.     }
  93.  
  94.     public void mouseExited(MouseEvent evt) {
  95.     }
  96.  
  97.     public void mouseDragged(MouseEvent evt) {
  98.     if (!isEnabled()) {
  99.         return;
  100.     }
  101.     // Has the mouse been dragged outside the button?
  102.     int x = evt.getX();
  103.     int y = evt.getY();
  104.     int width = getSize().width;
  105.     int height = getSize().height;
  106.     if (x < 0 || x > width || y < 0 || y > height) {
  107.         // Yes, we should deactivate any pending click.
  108.         if (down) {
  109.         down = false;
  110.         repaint();
  111.         }
  112.     } else if (!down) {
  113.         down = true;
  114.         repaint();
  115.     }
  116.     }
  117.  
  118.     public void mouseMoved(MouseEvent evt) {
  119.     }
  120.  
  121.     //----------------------------------------------------------------------
  122.  
  123.     // Methods for registering/deregistering event listeners
  124.  
  125.     /**
  126.      * The specified ActionListeners <b>actionPerformed</b> method will 
  127.      * be called each time the button is clicked.  The ActionListener
  128.      * object is added to a list of ActionListeners managed by 
  129.      * this button, it can be removed with removeActionListener.
  130.      * Note: the JavaBeans specification does not require ActionListeners
  131.      * to run in any particular order.
  132.      * 
  133.      * @see #removeActionListener
  134.      * @param l the ActionListener
  135.      */      
  136.  
  137.     public synchronized void addActionListener(ActionListener l) {
  138.     pushListeners.addElement(l);
  139.     }
  140.  
  141.     /** 
  142.      * Remove this ActionListener from the buttons internal list.  If the
  143.      * ActionListener isn't on the list, silently do nothing.
  144.      * 
  145.      * @see #addActionListener
  146.      * @param l the ActionListener
  147.      */      
  148.     public synchronized void removeActionListener(ActionListener l) {
  149.     pushListeners.removeElement(l);
  150.     }
  151.  
  152.     /**
  153.      * The specified PropertyChangeListeners <b>propertyChange</b> method will
  154.      * be called each time the value of any bound property is changed.
  155.      * The PropertyListener object is addded to a list of PropertyChangeListeners
  156.      * managed by this button, it can be removed with removePropertyChangeListener.
  157.      * Note: the JavaBeans specification does not require PropertyChangeListeners
  158.      * to run in any particular order.
  159.      *
  160.      * @see #removePropertyChangeListener
  161.      * @param l the PropertyChangeListener
  162.      */      
  163.     public void addPropertyChangeListener(PropertyChangeListener l) {
  164.     changes.addPropertyChangeListener(l);
  165.     }
  166.  
  167.     /** 
  168.      * Remove this PropertyChangeListener from the buttons internal list.  
  169.      * If the PropertyChangeListener isn't on the list, silently do nothing.
  170.      * 
  171.      * @see #addPropertyChangeListener
  172.      * @param l the PropertyChangeListener
  173.      */      
  174.     public void removePropertyChangeListener(PropertyChangeListener l) {
  175.     changes.removePropertyChangeListener(l);
  176.     }
  177.  
  178.     //----------------------------------------------------------------------
  179.  
  180.  
  181.     /** 
  182.      * This method has the same effect as pressing the button.
  183.      * 
  184.      * @see #addActionListener
  185.      */      
  186.     public void fireAction() {
  187.     if (debug) {
  188.         System.err.println("Button " + getLabel() + " pressed.");
  189.     }
  190.     Vector targets;
  191.     synchronized (this) {
  192.         targets = (Vector) pushListeners.clone();
  193.     }
  194.     ActionEvent actionEvt = new ActionEvent(this, 0, null);
  195.     for (int i = 0; i < targets.size(); i++) {
  196.         ActionListener target = (ActionListener)targets.elementAt(i);
  197.         target.actionPerformed(actionEvt);
  198.     }
  199.  
  200.     }
  201.  
  202.     /** 
  203.      * Enable debugging output.  Currently a message is printed each time
  204.      * the button is clicked.  This is a bound property.
  205.      * 
  206.      * @see #getDebug
  207.      * @see #addPropertyChangeListener
  208.      */      
  209.     public void setDebug(boolean x) {
  210.     boolean old = debug;
  211.     debug = x;
  212.     changes.firePropertyChange("debug", new Boolean(old), new Boolean(x));
  213.     }
  214.  
  215.     /** 
  216.      * Returns true if debugging output is enabled.  
  217.      * 
  218.      * @see #setDebug
  219.      */
  220.     public boolean getDebug() {
  221.     return debug;
  222.     }
  223.  
  224.     /** 
  225.      * Set the font size to 18 if true, 12 otherwise.  This property overrides
  226.      * the value specified with setFontSize.  This is a bound property.
  227.      * 
  228.      * @see #isLargeFont
  229.      * @see #addPropertyChangeListener
  230.      */      
  231.     public void setLargeFont(boolean b) {
  232.     if (isLargeFont() == b) {
  233.         return;
  234.     }
  235.     int size = 12;
  236.     if (b) {
  237.        size = 18;
  238.     }
  239.     Font old = getFont();
  240.     setFont(new Font(old.getName(), old.getStyle(), size));
  241.     changes.firePropertyChange("largeFont", new Boolean(!b), new Boolean(b));
  242.     }
  243.  
  244.     /** 
  245.      * Returns true if the font is "large" in the sense defined by setLargeFont.
  246.      * 
  247.      * @see #setLargeFont
  248.      * @see #setFont
  249.      */      
  250.     public boolean isLargeFont() {
  251.         if (getFont().getSize() >= 18) {
  252.         return true;
  253.     } else {
  254.         return false;
  255.     }
  256.     }
  257.  
  258.  
  259.    /** 
  260.      * Set the point size of the current font.  This is a bound property.
  261.      * 
  262.      * @see #getFontSize
  263.      * @see #setFont
  264.      * @see #setLargeFont
  265.      * @see #addPropertyChangeListener
  266.      */      
  267.     public void setFontSize(int x) {
  268.     Font old = getFont();
  269.     setFont(new Font(old.getName(), old.getStyle(), x));
  270.     changes.firePropertyChange("fontSize", new Integer(old.getSize()), new Integer(x));
  271.     }
  272.  
  273.     /** 
  274.      * Return the current font point size.
  275.      * 
  276.      * @see #setFontSize
  277.      */
  278.     public int getFontSize() {
  279.          return getFont().getSize();
  280.     }
  281.  
  282.     /**
  283.      * Set the current font and change its size to fit.  This is a 
  284.      * bound property.
  285.      *
  286.      * @see #setFontSize
  287.      * @see #setLargeFont
  288.      */
  289.     public void setFont(Font f) {
  290.     Font old = getFont();
  291.     super.setFont(f);
  292.     sizeToFit();
  293.     changes.firePropertyChange("font", old, f);
  294.     }
  295.  
  296.     /** 
  297.      * Set the buttons label and change it's size to fit.  This is a 
  298.      * bound property.
  299.      * 
  300.      * @see #getLabel
  301.      */
  302.     public void setLabel(String newLabel) {
  303.     String oldLabel = label;
  304.     label = newLabel;
  305.     sizeToFit();
  306.     changes.firePropertyChange("label", oldLabel, newLabel);
  307.     }
  308.  
  309.     /**
  310.      * Returns the buttons label.
  311.      * 
  312.      * @see #setLabel
  313.      */
  314.     public String getLabel() {
  315.     return label;
  316.     }
  317.  
  318.     public Dimension getPreferredSize() {
  319.     FontMetrics fm = getFontMetrics(getFont());
  320.     return new Dimension(fm.stringWidth(label) + TEXT_XPAD, 
  321.                  fm.getMaxAscent() + fm.getMaxDescent() + TEXT_YPAD);
  322.     }
  323.  
  324.     /**
  325.      * @deprecated provided for backward compatibility with old layout managers.
  326.      */
  327.     public Dimension preferredSize() {
  328.     return getPreferredSize();
  329.     }
  330.  
  331.     public Dimension getMinimumSize() {
  332.     return getPreferredSize();
  333.     }
  334.  
  335.     /**
  336.      * @deprecated provided for backward compatibility with old layout managers.
  337.      */
  338.     public Dimension minimumSize() {
  339.     return getMinimumSize();
  340.     }
  341.  
  342.     private void sizeToFit() {
  343.     Dimension d = getSize();
  344.     Dimension pd = getPreferredSize();
  345.  
  346.     if (pd.width > d.width || pd.height > d.height) {
  347.         int width = d.width;
  348.         if (pd.width > width) {
  349.         width = pd.width;
  350.         }
  351.         int height = d.height;
  352.         if (pd.height > height) {
  353.         height = pd.height;
  354.         }
  355.         setSize(width, height);
  356.  
  357.         Component p = getParent();
  358.         if (p != null) {
  359.             p.invalidate();
  360.             p.validate();
  361.         }
  362.     }
  363.     }
  364.  
  365.     /**
  366.      * Set the color the buttons label is drawn with.  This is a bound property.
  367.      */
  368.     public void setForeground(Color c) {
  369.     Color old = getForeground();
  370.     super.setForeground(c);
  371.     changes.firePropertyChange("foreground", old, c);
  372.     // This repaint shouldn't really be necessary.
  373.     repaint();
  374.     }
  375.  
  376.  
  377.     /**
  378.      * Set the color the buttons background is drawn with.  This is a bound property.
  379.      */
  380.     public void setBackground(Color c) {
  381.     Color old = getBackground();
  382.     super.setBackground(c);
  383.     changes.firePropertyChange("background", old, c);
  384.     // This repaint shouldn't really be necessary.
  385.     repaint();
  386.     }
  387.  
  388.  
  389.     private boolean debug;
  390.     private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  391.     private Vector pushListeners = new Vector();
  392.     private String label;
  393.     private boolean down;
  394.     private boolean sized;
  395.  
  396.     static final int TEXT_XPAD = 12;
  397.     static final int TEXT_YPAD = 8;
  398. }
  399.  
  400.