覆盖JButton paintComponent,透明度不显示后面板颜色

gre*_*ard 4 java swing transparency jbutton

这是我想要做的.我已经扩展了JButton并覆盖了paintComponent方法,创建了我想要的圆形边缘按钮效果,以及当按钮被鼠标滚动时的颜色褪色效果.一切都很好.我的问题是JButton仍在绘制一个白色矩形区域,如图所示.

PIC1 PIC1

我想1)白色的角落消失了,2)按钮的cetner显示它背后的面板.这是我尝试过的:

1-绘制按钮时使用getParent().getBackground()并首先绘制按钮.这适用于不透明面板.不过我希望这个按钮可以在部分或完全透明的面板上工作.使用透明面板绘制颜色,但在白色背景上隐藏面板后面的任何内容(如图像).

2-我尝试了很多setOpaque(false)或setContentAreaFilled(false)的组合.我在调用super.paintComponent(g)时没有调用它.这些似乎都不起作用.

3-按钮向右看时,我不使用方法g2.clearRect(0,0,宽,高)(画前清除图形区域),但由于图形对象不会被掩盖了淡入淡出效果后停止工作一个按钮翻转.

4-我使用JLabel作为文本,并尝试将其设置为不透明或只是不使用它,问题仍然存在.所以我认为这不是问题.

因为我只想要对JButton产生影响而不是其他摆动组件,所以我真的希望避免制作我自己的ButtonUI.

谢谢,我希望这是有道理的.下面是我的按钮的代码.

import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;

/**
 * WButton.java
 * 
 * An extension of JButton but with custom graphics
 *
 */

public class WButton extends JButton{

  private Timer timer;
  private float[] background = {.3f,.6f,.8f,0f};
  private boolean fadeUp = true;
  private boolean fadeDown = false;
  private JLabel label;

  /**
   * Default Constructor
   */
  public WButton(){
    super();
    label = new JLabel();
    setupButton();
  }

  /**
   * Text constructor
   */
  public WButton(String text){
    super(text);
    label = new JLabel(text);
    setupButton();
  }

  /**
   * common setup functions
   */
  private void setupButton(){
    timer = new Timer(24,new TimerAction(this));
    label.setLabelFor(this);
    add(label);
  }

  /**
   * Set the background color
   */
  @Override
  public void setBackground(Color bg){
    background = bg.getRGBComponents(background);
    background[3] = 0f;
    super.setBackground(new Color(background[0],background[1],
                                  background[2],background[3]));
    repaint();
  }

  /**
   * get background
   */
  @Override
  public Color getBackground(){
    if(background!=null)
      return new Color(background[0],background[1],background[2],background[3]);

    return new Color(.5f,.5f,.5f);
  }

  /**
   * Set the font of the button
   */
  @Override
  public void setFont(Font font){
    super.setFont(font);
    if(label!=null)
      label.setFont(font);
  }

  /**
   * Override the set text method
   */
  @Override
  public void setText(String t){
    super.setText(t);
    if(label!=null)
      label.setText(t);
  }

  /**
   * Paint the button
   */
  @Override
  public void paintComponent(Graphics g){
    super.paintComponent(g);
    int width = getWidth();
    int height = getHeight();

    Graphics2D g2 = (Graphics2D)g;
    g2.clearRect(0,0,width,height);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);

    //Check Button Model state
    if(model.isPressed())
      paintPressedButton(g2,width,height);
    else{
      if(model.isRollover()){
        if(fadeUp){
          fadeUp = false;
          timer.start();
        }
      }
      else{
        if(fadeDown){
          fadeDown = false;
          timer.start();
        }
      }
      g2.setPaint(new Color(background[0],background[1],background[2],background[3]));
      g2.fillRoundRect(0,0,width-1,height-1,height,height);
    }
  }

  /**
   * Draw a pressed button
   */
  private void paintPressedButton(Graphics2D g2,int width,int height){

    float[] temp = new float[4];
    for(int i=0;i<background.length;i++)
      temp[i] = background[i]-.4f < 0f ? 0f : background[i]-.4f;

    g2.setPaint(new Color(temp[0],temp[1],temp[2],temp[3]));
    g2.fillRoundRect(0,0,width-1,height-1,height,height);

  }

  /**
   * paint the border
   */
  public void paintBorder(Graphics g){

    int width = getWidth();
    int height = getHeight();
    g.setColor(Color.BLACK);
    g.drawRoundRect(0,0,width-1,height-1,height,height);
  }

  /**
   * Inner action listener class
   */
  private class TimerAction implements ActionListener{

    private float alphaInc = .2f;
    WButton button;

    public TimerAction(WButton b){
      button = b;
    }

    public void actionPerformed(ActionEvent e){
      if(model.isRollover()){
        background[3] += alphaInc;
        if(background[3] > 1.0f){
          timer.stop();
          background[3] = 1.0f;
          fadeDown = true;
        }
      }
      else{
        background[3] -= alphaInc;
        if(background[3] < 0f){
          timer.stop();
          background[3] = 0f;
          fadeUp = true;
        }
      }
      button.repaint();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑1

有什么建议让我更接近,但不是那里.而不是g2.clearRect()我用建议的透明颜色绘制了对象.白色的盒子不见了,但有不同的颜色.经过调查,是父面板的颜色,但没有透明度.这是一个例子的图片(面板有70%的透明度).第一张照片是节目开始的时候.第二张图片是在1次鼠标翻转后.

PIC3 在此输入图像描述

aly*_*aly 7

您可以做的不是使用clearRect(),而是使用完全透明的颜色清除背景.

g2.setColor(new Color(0,0,0,0));
g2.drawRect(0,0,width,height);
Run Code Online (Sandbox Code Playgroud)

你仍然需要setOpaque(false)JButton这样一旦你在它悬停一旦不使用蓝色翻转颜色作为背景.

编辑:看到你刚发布的内容后,我认为问题是主框架没有重新绘制.

尝试:

SwingUtilities.getWindowAncestor(this).repaint();    
Run Code Online (Sandbox Code Playgroud)

在paint方法中重新绘制框架,这可能会解决问题.