繁体   English   中英

JButton动态背景和前景更改

[英]JButton dynamic Background & foreground change

我想动态滑动更改背景和前景,而我正在使用以下自定义按钮。 按钮样式设置为默认样式。 请问有什么可以帮我的忙吗?

public class CustomButton extends JButton {
        private int buttonStyle = JAVA_DEFAULT;

    public static final int JAVA_DEFAULT      = 0;
    public static final int SKINZ             = 1;
    public static final int CLASSIC           = 2;
    public static final int IMAGES            = 3;
    public static final int ROLLOVER          = 4;
    public static final int GRADIENCE         = 5;
    public static final int JAVA_LIKE         = 6;  // A java-look button with our own text handling.

    public void paintComponent(Graphics g){
      // prep for painting.
      Graphics2D g2D = (Graphics2D)g;
      if(buttonStyle != 0 && buttonStyle != IMAGES){
        if(g == null)
            return;
        if(getBackground() == null)
          setBackground(color);
        if(getFadedBackgroundColor() == null)
          setFadedBackgroundColor(Color.white);

        g2D.clearRect(0, 0, getWidth()+getX(), getHeight()+getY());
        // end prep for painting.
      }
      switch (buttonStyle){
      case SKINZ:
        paintSkinz(g2D);
        return;
      case IMAGES:
        paintImages(g2D);
        break;
      case ROLLOVER:
        System.err.println("Rollover look of CustomButton not yet implemented.");
        break;
      case JAVA_LIKE:
        paintJavaLike(g2D);
        return;
      case GRADIENCE:
        paintGradience(g2D);
      case CLASSIC:
      case JAVA_DEFAULT:
      default:
        super.paintComponent(g);
        m_originalborder = getBorder();
        m_originalfont = getFont();
        return;
      }
      paintText(g2D,0,0,getWidth(),getHeight());
    }

     private void paintJavaLike(Graphics2D g2D)
    {
      g2D.setColor(getBackground());
      g2D.fill3DRect(0,0,getWidth(),getHeight(),true);
      if(getIcon()==null)
        paintText(g2D,0,0,getWidth(),getHeight());
      else if (getText() == null || getText().length() == 0)
        this.paintCenteredIcon(g2D, ((ImageIcon)getIcon()).getImage());
      else {
        int w = getWidth() - getIconTextGap() - getIcon().getIconWidth() - (borderWidth*2)-4;
        int h = getHeight()-(borderWidth*2);
        g2D.drawImage(((ImageIcon)getIcon()).getImage(), 2, (getHeight()/2)-(getIcon().getIconHeight()/2), this);
        paintText(g2D,2+getIcon().getIconWidth()+this.getIconTextGap(),0,w,h);
      }
    }

    public void paintText(Graphics2D g2D, int offset_x, int offset_y, int width, int height)
    {
      int idx,x,y,strwidth,strwidth2=0, strHeight=0;
      String myText,myText2=null;
      Font myFont;
      FontMetrics fm;

      myText = getText();
      myFont = getFont();
      if (m_FontSize > 0 && myFont.getSize() != m_FontSize)
        myFont = myFont.deriveFont((float)m_FontSize);

      fm = g2D.getFontMetrics(myFont);
      strwidth = fm.stringWidth(myText);
      strHeight = fm.getAscent() + fm.getDescent();

      // Handle font scaling and line wrapping
      if (strwidth > width || strHeight > height)
      {
        idx = myText.indexOf(' ');

        // Only one word, shrink font to fit.
        if (idx == -1)
        {
          if (m_FontSize == -1)
          {
            while((strwidth > width || strHeight > height) && myFont.getSize() > m_MinimumFontSize)
            {
              myFont = myFont.deriveFont((float)(myFont.getSize()-1));
              fm = g2D.getFontMetrics(myFont);
              strwidth = fm.stringWidth(myText);
              strHeight = fm.getAscent() + fm.getDescent();
            }
          } else {
            strwidth = fm.stringWidth(myText);
          }
        }
        else   // Multiple words
        {
          // Split words up.  This could be enhanced in the future.
          // Currently limited to two words split on the first space.
          if (m_TextWrapOn)    // Only if allowing text wrapping.
          {
            myText2 = myText.substring(idx+1);
            myText  = myText.substring(0,idx);
          }
          strwidth = fm.stringWidth(myText);
          strwidth2 = fm.stringWidth(myText2);
          strHeight = (fm.getAscent() + fm.getDescent()) * 2;  // *2 lines.
          if (m_FontSize == -1)
          {
            while((strwidth > width || strwidth2 > width || strHeight > height) &&
                  myFont.getSize() > m_MinimumFontSize)
            {
              myFont = myFont.deriveFont((float)(myFont.getSize()-1));
              fm = g2D.getFontMetrics(myFont);
              strwidth = fm.stringWidth(myText);
              strwidth2 = fm.stringWidth(myText2);
              strHeight = (fm.getAscent() + fm.getDescent()) * 2;  // *2 lines.
            }
          } else {
            strwidth = fm.stringWidth(myText);
            strwidth2 = fm.stringWidth(myText2);
          }
        }
      }
      // Scale text larger
      else if (strwidth < (width * 0.75)) {
        if (m_FontSize == -1)
        {
          while((strwidth < (width * 0.8)) && (fm.getHeight() < height) &&
                myFont.getSize() < m_MaximumFontSize)
          {
            myFont = myFont.deriveFont((float)(myFont.getSize()+1));
            fm = g2D.getFontMetrics(myFont);
            strwidth = fm.stringWidth(myText);
          }
        } else {
          strwidth = fm.stringWidth(myText);
        }
      }

      if (myText2 == null)
        y = (height/2)+(fm.getMaxAscent()/2)+offset_y;
      else
        y = (height/2)-fm.getDescent()+offset_y;
      if (y < fm.getAscent())
        y = fm.getAscent();
      if (y > height)
        y = height;                      // Don't put chars off bottom of button
      if (buttonStyle == JAVA_LIKE && y == height)
        y = height-2;                    // subtract border

      switch(getHorizontalAlignment())
      {
        case SwingUtilities.LEFT:
          x = 14 + offset_x;
          break;
        case SwingUtilities.RIGHT:
          x = width-strwidth-14+offset_x;
          break;
        case SwingUtilities.CENTER:
        default:
          // the computations here are centering the text.
          x = (width/2)-(strwidth/2)+offset_x;
          break;
      }
      if (x < offset_x) x = offset_x;
      if (this.buttonStyle == JAVA_LIKE && x < (offset_x+1)) x = offset_x+1;

      // go ahead and draw text.
      // prep for painting text
      if (model.isPressed())
        g2D.setColor(getBackground());
      else
        g2D.setColor(getForeground());
      g2D.setFont(myFont);
      g2D.drawString(myText, x, y);

      if (myText2 != null)
      {
        y = (height/2)+fm.getHeight()-fm.getDescent()+offset_y;
        switch(getHorizontalAlignment())
        {
          case SwingUtilities.LEFT:
            // the computations here are centering the text.
            x = borderWidth + getIconTextGap() + offset_x;
            break;
          case SwingUtilities.RIGHT:
            // the computations here are centering the text.
            x = width-strwidth2-(borderWidth+getIconTextGap())+offset_x;
            break;
          case SwingUtilities.CENTER:
          default:
            // the computations here are centering the text.
            x = (width/2)-(strwidth2/2)+offset_x;
            break;
        }
        if (x < offset_x) x = offset_x;
        g2D.drawString(myText2, x, y);
      }
    }

   public void paintOffCenterIcon(Graphics2D g2D, Image image){
      int w = getIcon().getIconWidth();
      int h = getIcon().getIconHeight();
      g2D.drawImage(image, (getWidth()/2)-(w/2)+2 , (getHeight()/2)-(h/2)+2, this);
    }

    public void paintCenteredIcon(Graphics2D g2D, Image image){
      int w = getIcon().getIconWidth();
      int h = getIcon().getIconHeight();
      g2D.drawImage(image, (getWidth()/2)-(w/2), (getHeight()/2)-(h/2), this);
    }

    public void paintGradience(Graphics2D g2D)
    {
      GradientPaint gradientp;
      switch(m_shape){
      case RECTANGLE:
        //stuff for round rectangles
        gradientp = new GradientPaint(m_X1, m_Y1, getBackground(),
            m_X2, m_Y2, getFadedBackgroundColor());
        g2D.setPaint(gradientp);
        g2D.fillRoundRect(0, 0, getWidth(), getHeight(), arc, arc);
        break;
      case OVAL:
        //stuff for ovals
        gradientp = new GradientPaint(m_X1, m_Y1, getBackground(),
            m_X2, m_Y2, getFadedBackgroundColor());
        g2D.setPaint(gradientp);
        g2D.fillOval(0, 0, getWidth(), getHeight());
        break;
      case POLYGON:
        // stuff for triangles
        int xs[] = {0, (int)m_X2, (int)m_Y2};
        int ys[] = {0, (int)m_X2/2, (int)m_Y2};
        g2D.fillPolygon(xs , ys, 3);
        break;
      }
    }

    public void paintSkinz(Graphics2D g2D){
      m_shape = RECTANGLE;  //just for clarity's sake.

      if(getModel().isPressed()){
        beveledPressed(g2D);
        g2D.setClip(null);
        return;
      }
      else if(!getModel().isPressed()){
        beveledUnpressed(g2D);
        g2D.setClip(null);
      }
    }

    public void paintImages(Graphics2D g2D){
      m_shape = RECTANGLE;  //just for clarity's sake.
      Icon icon;

      if(getModel().isPressed()){
        icon = getPressedIcon();
        if(icon!=null)
          paintCenteredIcon(g2D, ((ImageIcon)icon).getImage());
        g2D.setClip(null);
        return;
      }
      else if(!getModel().isPressed()){
        icon = getIcon();
        if(icon!=null)
          paintCenteredIcon(g2D, ((ImageIcon)icon).getImage());
        g2D.setClip(null);
      }
    }

   public void setPreferredSize(Dimension prefSz)
    {
      m_PreferredSize = prefSz;
      super.setPreferredSize(prefSz);
    }

    public Dimension getPreferredSize()
    {
      if (m_PreferredSize != null)
        return m_PreferredSize;
      int insets = borderWidth*2 + 4;      // initial border width and insets;
      switch (buttonStyle)
      {
        case JAVA_LIKE:
          int width  = insets;
          int height = insets;
          if (this.getGraphics() == null || this.getGraphics().getFontMetrics() == null)   // safety net
            return super.getPreferredSize();
          if (this.getText() != null)
          {
            width  += this.getGraphics().getFontMetrics().stringWidth(getText());
            height += this.getGraphics().getFontMetrics().getHeight();
          }
          if (this.getIcon() != null)
          {
            width  += getIcon().getIconWidth();
            if (getText() != null)
              width += this.getIconTextGap();
            if (height < (getIcon().getIconHeight()+insets))
              height = getIcon().getIconHeight();
          }
          return new Dimension(width,height);
        case SKINZ:
        case CLASSIC:
        case IMAGES:
        case ROLLOVER:
        case GRADIENCE:
        case JAVA_DEFAULT:
        default:
          return super.getPreferredSize();
      }
    }

   void dButtonStateChanged(ChangeEvent e)
    {
        // Call 'super' methods in here.  Don't call the overriden versions.
        if (this.getModel().isRollover())
        {
            if (rolloverBackground != null)
                super.setBackground(rolloverBackground);
            if (rolloverForeground != null)
                super.setForeground(rolloverForeground);
            if (rolloverFont != null)
                super.setFont(rolloverFont);
        }
        else
        {
            super.setBackground(normalBackground);
            super.setForeground(normalForeground);
            super.setFont(normalFont);
        }
    } // end dButtonStateChanged()


    protected void fireActionPerformed(ActionEvent event)
    {
      if (event != null)
        super.fireActionPerformed( event);
      if (m_Key != null)
      {
        // just a hack to get this working with the Java Client.
        if (m_ui == null){
          m_ui = getClientUI();
        } // end hack.

      }
    }

    void jbInit()
    {
      setBackground(color); // sets default bg color.
      setForeground(Color.black); //sets default foreground to black
      if(buttonStyle != JAVA_DEFAULT )
        setBorder(null);

      enableEvents(MouseEvent.MOUSE_EVENT_MASK);
      enableEvents(FocusEvent.FOCUS_EVENT_MASK);
      enableEvents(ActionEvent.ACTION_EVENT_MASK);
      enableEvents(KeyEvent.KEY_EVENT_MASK);

      // Sets up a listener for state changes on this button.
      this.getModel().addChangeListener(new ChangeListener()
      {
          public void stateChanged(ChangeEvent e)
        {
            dButtonStateChanged(e);
        }
      });
    } // end jbInit()

    protected void processMouseEvent(MouseEvent e)
    {
      switch(e.getID()) {
      // these are for future development.
      case MouseEvent.MOUSE_ENTERED:
      case MouseEvent.MOUSE_EXITED:
        super.processMouseEvent(e);
        break;
      case MouseEvent.MOUSE_RELEASED:
      case MouseEvent.MOUSE_CLICKED:
        e.consume();
        break;
      case MouseEvent.MOUSE_PRESSED:
        // we call doClick() b/c we may not get a MOUSE_RELEASED event with a
        // touchscreen so we need to make sure it gets sent, and the doClick()
        // method does that.
        doClick(80);
        e.consume();
        break;
      }
    }


    protected void processFocusEvent(FocusEvent e)
    {
      super.processFocusEvent(e);
      switch (e.getID())
      {
      case FocusEvent.FOCUS_LOST:
      //if (m_ui != null)
      //  m_ui.getFieldManager().setCurrentField(null);
        break;
      case FocusEvent.FOCUS_GAINED:
        if (m_ui != null)
          m_ui.getFieldManager().setCurrentField(this); // Tell manager I got the focus.
        break;
      }
    }

    private void beveledUnpressed(Graphics2D g){
      // so, we've got a hashtable of images we've drawn.  We'll try to get this image out or it.
      BufferedImage bi = (BufferedImage)m_imagetable.get("UnPressed."+"SKINZ"+"."+
                          getBackground().toString()+"."+getSize().toString());
      Graphics2D g2D;

      int w = getWidth();
      int h = getHeight();
      //define some border sizes
      /*
       * todo: fix this, i don't like this being hardcoded.
       * */
      if(borderWidth == 0)
        borderWidth = 10;
      int borderheight = borderWidth;
      Rectangle innerRect = new Rectangle(borderWidth, borderheight, w-(borderWidth*2), h-(borderheight*2));

      // if we didn't find this image in the hashtable, we'll draw the image.
      if(bi == null){
        bi = (BufferedImage) createImage(getWidth(), getHeight());
        g2D = bi.createGraphics();

        Color shadowcolor = getBackground().darker();
        // would like to have gotten lightcolor with the brighter() method, but that
        // method doesn't always produce a color different from the original color.
        Color lightcolor = Color.white;

        //sets of polygon points
        int leftXpoints[]   = {0, borderWidth, borderWidth, 0};
        int leftYpoints[]   = {0, borderheight, h-borderheight, h};
        int topXpoints[]    = {0, w, w-borderWidth, borderWidth};
        int topYpoints[]    = {0, 0, borderheight, borderheight};
        int rightXpoints[]  = {w, w, w-borderWidth, w-borderWidth};
        int rightYpoints[]  = {0, h, h-borderheight, borderheight};
        int bottomXpoints[] = {borderWidth, w-borderWidth, w, 0};
        int bottomYpoints[] = {h-borderheight, h-borderheight, h, h};

        //define polys
        Polygon leftpoly   = new Polygon(leftXpoints,   leftYpoints,   4);
        Polygon toppoly    = new Polygon(topXpoints,    topYpoints,    4);
        Polygon rightpoly  = new Polygon(rightXpoints,  rightYpoints,  4);
        Polygon bottompoly = new Polygon(bottomXpoints, bottomYpoints, 4);

        //draw the right-hand beveled edge
        g2D.setClip(rightpoly);
        GradientPaint p = new GradientPaint(w-borderWidth, 0, getBackground(),
            w, 0, shadowcolor);
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc, arc);

        //draw the bottom-hand beveled edge
        g2D.setClip(bottompoly);
        p = new GradientPaint(0, h-borderheight,
                              getBackground(), 0,
                              h, shadowcolor);
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //draw the left-hand beveled edge
        g2D.setClip(leftpoly);
        p = new GradientPaint(0, 0,
                              lightcolor, borderWidth,
                              0, getBackground());
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //draw the top-hand beveled edge
        g2D.setClip(toppoly);
        p = new GradientPaint(0, 0,
                              lightcolor, 0,
                              borderheight, getBackground());
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //now draw inner rectangle
        g2D.setClip(innerRect);
        g2D.setColor(getBackground());
        g2D.fill(innerRect);

        g.drawImage(bi, null, getX(), getY());
        // we only want to draw each image once, so we'll throw this image in the hash table.
        m_imagetable.put("UnPressed."+"SKINZ"+"."+getBackground().toString()+"."+getSize().toString(), bi);
      }
      else {
        g2D = (Graphics2D)bi.getGraphics();
      }

      g.drawImage(bi, 0, 0, this);

      innerRect.x -=6;
      innerRect.width += 12;
      g.setClip(innerRect);

      // icons take precedence over text.
      if(getIcon()==null)
        paintText(g,innerRect.x,innerRect.y,innerRect.width,innerRect.height);
      else
        paintCenteredIcon(g, ((ImageIcon)getIcon()).getImage());
    }


    private void beveledPressed(Graphics2D g){
      // so, we've got a hashtable of images we've drawn.  We'll try to get this image out or it.
      BufferedImage bi = (BufferedImage)m_imagetable.get("Pressed."+"SKINZ"+"."+
                          getBackground().toString()+"."+getSize().toString());
      Graphics2D g2D;

      int w = getWidth();
      int h = getHeight();
      //define some border sizes
      /*
       * todo: fix this, i don't like this being hardcoded.
       * */
      if(borderWidth == 0)
        borderWidth = 10;
      int borderheight = borderWidth;
      Rectangle innerRect = new Rectangle(borderWidth, borderheight, w-(borderWidth*2), h-(borderheight*2));

      // if we didn't find this image in the hashtable, we'll draw the image.
      if(bi == null){
        bi = (BufferedImage) createImage(getWidth(), getHeight());
        g2D = bi.createGraphics();

        Color shadowcolor = getBackground().darker();
        // would like to have gotten lightcolor with the brighter() method, but that
        // method doesn't always produce a color different from the original color.
        Color lightcolor = Color.white;

        //sets of polygon points
        int leftXpoints[]   = {0, borderWidth, borderWidth, 0};
        int leftYpoints[]   = {0, borderheight, h-borderheight, h};
        int topXpoints[]    = {0, w, w-borderWidth, borderWidth};
        int topYpoints[]    = {0, 0, borderheight, borderheight};
        int rightXpoints[]  = {w, w, w-borderWidth, w-borderWidth};
        int rightYpoints[]  = {0, h, h-borderheight, borderheight};
        int bottomXpoints[] = {borderWidth, w-borderWidth, w, 0};
        int bottomYpoints[] = {h-borderheight, h-borderheight, h, h};

        //define polys
        Polygon leftpoly   = new Polygon(leftXpoints,   leftYpoints,   4);
        Polygon toppoly    = new Polygon(topXpoints,    topYpoints,    4);
        Polygon rightpoly  = new Polygon(rightXpoints,  rightYpoints,  4);
        Polygon bottompoly = new Polygon(bottomXpoints, bottomYpoints, 4);

        //draw the right-hand beveled edge
        g2D.setClip(rightpoly);
        GradientPaint p = new GradientPaint(w-borderWidth, 0, getForeground(),
            w, 0, shadowcolor);
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc, arc);

        //draw the bottom-hand beveled edge
        g2D.setClip(bottompoly);
        p = new GradientPaint(0, h-borderheight,
                              getForeground(), 0,
                              h, shadowcolor);
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //draw the left-hand beveled edge
        g2D.setClip(leftpoly);
        p = new GradientPaint(0, 0,
                              lightcolor, borderWidth,
                              0, getForeground());
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //draw the top-hand beveled edge
        g2D.setClip(toppoly);
        p = new GradientPaint(0, 0,
                              lightcolor, 0,
                              borderheight, getForeground());
        g2D.setPaint(p);
        g2D.fillRoundRect(0, 0, w, h, arc,
                          arc);

        //now draw inner rectangle
        g2D.setClip(innerRect);
        g2D.setColor(getForeground());
        g2D.fill(innerRect);

        g.drawImage(bi, null, getX(), getY());
                 m_imagetable.put("Pressed."+"SKINZ"+"."+getBackground().toString()+"."+getSize().toString(), bi);
      }
      else {
        g2D = (Graphics2D)bi.getGraphics();
      }

      g.drawImage(bi, 0, 0, this);

      innerRect.x -=6;
      innerRect.width += 12;
      g.setClip(innerRect);

      // icons take precedence over text.
      if(getIcon()==null)
        paintText(g,innerRect.x,innerRect.y,innerRect.width,innerRect.height);
      else
        paintCenteredIcon(g, ((ImageIcon)getIcon()).getImage());
    }


    public void setButtonStyle(int style){
      switch (style) {
      case SKINZ:
      case IMAGES:
          setFont(m_originalfont);//new Font("Dialog", Font.BOLD, 20));
          setBorder(null);
        break;
      case JAVA_LIKE:
        setBorderWidth(2);
      case JAVA_DEFAULT:
      case CLASSIC:
      case ROLLOVER:
      default:
        setBorder(m_originalborder);
        setFont(m_originalfont);
        break;
      }
      buttonStyle = style;
    }

}

有什么建议可以使用上面的相同代码更改颜色? 谢谢Palanisamy

  • 我认为覆盖BasicButtonUI更好且最简单,大多数更改对外观都不敏感,

  • 您可以决定要覆盖或保持不变的方法之一,原因是在JButton,ButtonModel,ButtonGroups API中实现的每个方法的工作方式均与Swing Team为标准(未触摸)JButton实现的方法相同

  • MetalButtonUI的示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM