Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4074495

color&font values not set on Graphics object for lightweight components

XMLWordPrintable

    • generic, x86, sparc
    • generic, solaris_2.5.1, windows_nt

      The color and font settings on the Graphics object associated with lightweight components are not set. See following test case which uses Jeff's sample
      RoundButton lightweight component. (If you swap out the RoundButton with a
      standard AWT Button, you'll see the behavior of the heavyweight vs. lightweight:

      ExampleApplet.java:

      import java.applet.*;
      import java.lang.*;
      import java.util.*;
      import java.awt.*;
      import java.awt.event.*;

      public class ExampleApplet extends Applet {

        public void init() {
            setLayout(new FlowLayout());
            setBackground(Color.gray);

            // Create round button, listener, and add to the panel
            RoundButton button1 = new RoundButton("Button 1");
            button1.setForeground(Color.blue);
            button1.setBackground(Color.yellow);
            add(button1);

            // Create action listener
            ExampleActionListener listener = new ExampleActionListener();
            button1.addActionListener(listener);
        }

      }

      class ExampleActionListener implements ActionListener {
       
          public ExampleActionListener() {
          }
       
          public void actionPerformed(ActionEvent e) {

              Graphics g = ((RoundButton)e.getSource()).getGraphics();
              System.out.println("button color: " + g.getColor());
          }
      }


      RoundButton.java:

      /*
       * @(#)RoundButton.java 1.6 97/06/18 Jeff Dinkins
       *
       * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
       *
       */
      //package actual;

      import java.applet.*;
      import java.lang.*;
      import java.util.*;
      import java.awt.*;
      import java.awt.event.*;

      /**
       * RoundButton - a class that produces a lightweight button.
       *
       * Lightweight components can have "transparent" areas, meaning that
       * you can see the background of the container behind these areas.
       *
       */
      public class RoundButton extends Component {

        ActionListener actionListener; // Post action events to listeners
        String label; // The Button's text
        protected boolean pressed = false; // true if the button is detented.
        
        
        /**
         * Constructs a RoundButton with no label.
         */
        public RoundButton() {
            this("");
        }

        /**
         * Constructs a RoundButton with the specified label.
         * @param label the label of the button
         */
        public RoundButton(String label) {
            this.label = label;
            enableEvents(AWTEvent.MOUSE_EVENT_MASK);
        }

        /**
         * gets the label
         * @see setLabel
         */
        public String getLabel() {
            return label;
        }
        
        /**
         * sets the label
         * @see getLabel
         */
        public void setLabel(String label) {
            this.label = label;
            invalidate();
            repaint();
        }
        
        /**
         * paints the RoundButton
         */
        public void paint(Graphics g) {
            int s = Math.min(getSize().width - 1, getSize().height - 1);
            
            // paint the interior of the button
            if(pressed) {
      g.setColor(getBackground().darker().darker());
            } else {
      g.setColor(getBackground());
            }
            g.fillArc(0, 0, s, s, 0, 360);
            
            // draw the perimeter of the button
            g.setColor(getBackground().darker().darker().darker());
            g.drawArc(0, 0, s, s, 0, 360);
            
            // draw the label centered in the button
            Font f = getFont();
            if(f != null) {
      FontMetrics fm = getFontMetrics(getFont());
      g.setColor(getForeground());
      g.drawString(label,
      s/2 - fm.stringWidth(label)/2,
      s/2 + fm.getMaxDescent());
            }
        }
        
        /**
         * The preferred size of the button.
         */
        public Dimension getPreferredSize() {
            Font f = getFont();
            if(f != null) {
      FontMetrics fm = getFontMetrics(getFont());
      int max = Math.max(fm.stringWidth(label) + 40, fm.getHeight() + 40);
      return new Dimension(max, max);
            } else {
      return new Dimension(100, 100);
            }
        }
        
        /**
         * The minimum size of the button.
         */
        public Dimension getMinimumSize() {
            return new Dimension(100, 100);
        }

        /**
         * Adds the specified action listener to receive action events
         * from this button.
         * @param listener the action listener
         */
         public void addActionListener(ActionListener listener) {
             actionListener = AWTEventMulticaster.add(actionListener, listener);
             enableEvents(AWTEvent.MOUSE_EVENT_MASK);
         }
       
         /**
          * Removes the specified action listener so it no longer receives
          * action events from this button.
          * @param listener the action listener
          */
         public void removeActionListener(ActionListener listener) {
             actionListener = AWTEventMulticaster.remove(actionListener, listener);
         }

        /**
         * Determine if click was inside round button.
         */
         public boolean contains(int x, int y) {
             int mx = getSize().width/2;
             int my = getSize().height/2;
             return (((mx-x)*(mx-x) + (my-y)*(my-y)) <= mx*mx);
         }
         
         /**
          * Paints the button and distribute an action event to all listeners.
          */
         public void processMouseEvent(MouseEvent e) {
             Graphics g;
             switch(e.getID()) {
                case MouseEvent.MOUSE_PRESSED:
      // render myself inverted....
      pressed = true;

                  // Repaint might flicker a bit. To avoid this, you can use
                  // double buffering (see the Gauge example).
      repaint();
      break;
                case MouseEvent.MOUSE_RELEASED:
      if(actionListener != null) {
      actionListener.actionPerformed(new ActionEvent(
      this, ActionEvent.ACTION_PERFORMED, label));
      }
      // render myself normal again
      if(pressed == true) {
      pressed = false;

                      // Repaint might flicker a bit. To avoid this, you can use
                      // double buffering (see the Gauge example).
      repaint();
      }
      break;
                case MouseEvent.MOUSE_ENTERED:

      break;
                case MouseEvent.MOUSE_EXITED:
      if(pressed == true) {
      // Cancel! Don't send action event.
      pressed = false;

                      // Repaint might flicker a bit. To avoid this, you can use
                      // double buffering (see the Gauge example).
      repaint();

      // Note: for a more complete button implementation,
      // you wouldn't want to cancel at this point, but
      // rather detect when the mouse re-entered, and
      // re-highlight the button. There are a few state
      // issues that that you need to handle, which we leave
      // this an an excercise for the reader (I always
      // wanted to say that!)
      }
      break;
             }
             super.processMouseEvent(e);
         }
         
      }

            dcherepanov Dmitry Cherepanov
            jkoenigsunw Janet Koenig (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: