当前位置: 首页 > 知识库问答 >
问题:

使用不显示后面板颜色的透明度重写JButton paintComponent

毋炳
2023-03-14

这就是我正在努力做的。我已经扩展了JButton并覆盖了paintComponent方法,创建了我想要的圆角边缘按钮的效果,以及鼠标翻转按钮时的颜色褪色效果。一切都很有效。我的问题是JButton仍然在绘制一个白色矩形区域,就像图像显示的那样。

我希望1)白色的角落去和2)按钮的cetner显示它后面的面板。以下是我尝试的:

1-在绘制按钮时,使用getParent().getBackground()并首先绘制按钮。这适用于不透明的面板。然而,我希望这个按钮在一个部分或完全透明的面板上工作。使用透明面板时,它会绘制颜色,但在白色背景上,面板后面隐藏了任何东西(如图像)。

3-当我不使用方法g2.clearrect(0,0,width,height)(在绘画前清除图形区域)时,按钮看起来是正确的,但由于图形对象从未被掩盖,在按钮翻转一次后,褪色效果停止工作。

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

因为我只想要JButton的效果,而不是其他swing组件,所以我真的希望避免制作自己的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();
    }
  }
}

编辑1

艾丽的建议让我更近了,但还没有完全做到。我按照建议使用透明颜色来绘制对象,而不是g2.clearrect()。白色的盒子不见了,但一种不同的颜色在那里。经调查,是父面板的颜色,但没有透明度。下面是一个例子的图片(面板有70%的透明度)。第一张图片是程序开始的时候。第二张图片是1次鼠标翻转后。

共有1个答案

端木安国
2023-03-14

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

g2.setColor(new Color(0,0,0,0));
g2.drawRect(0,0,width,height);

您仍然需要在JButtonsetopaque(false),以便在您悬停一次时,它不会使用蓝色翻转色作为背景。

编辑:在看到你刚刚发布的内容后,我认为问题是主框架没有重新粉刷。

SwingUtilities.getWindowAncestor(this).repaint();    
 类似资料:
  • 在Canvas绘图时,可以通过绘制上下文的strokeStyle属性和fillStyle属性来设置图形的描边颜色和填充颜色。默认颜色为不透明的黑色。 strokeStyle属性和fillStyle属性可以被设置为任意有效的CSS颜色字符串,可以使用颜色名称、十六进制RGB颜色、RGB、RGBA、HSL、HSLA颜色中的任意一种。 在使用RGBA或HSLA颜色时,可以通过设置其透明度(alpha)来

  • ffmpeg-i video.mp4-vf“rotate=pi/6:fillcolor=red@0x00”-acodec复制输出.mp4 而且不起作用。颜色保持不透明,无论不透明度的值是多少(0.0到1.0) 你们谁能知道发生了什么?

  • 本文向大家介绍Android 颜色透明度(Alpha)级别,包括了Android 颜色透明度(Alpha)级别的使用技巧和注意事项,需要的朋友参考一下 示例 十六进制不透明度值 如果要将45%设置为红色。 红色的十六进制值-#FF0000 您可以在前缀中添加73以实现45%的不透明度-#73FF0000

  • 问题内容: CSS3动画出现问题。 仅当我删除的更改时,此代码才有效。 我想在悬停后立即更改显示,但不透明度应使用过渡进行更改。 问题答案: 我改变了一点,但结果很漂亮。 谢谢大家

  • 如果我使用以下形状可绘制 然后不知何故圆角结束了颜色(黑灰色)。除了拐角处,形状的内部是透明的。当我将纯色设置为白色或黑色时,边框内的所有东西都是预期的颜色。 我的问题是,为什么当纯色是透明的(甚至没有设置)时,圆角似乎会显示颜色? 谢啦

  • 我试着用特定的透明颜色在Android画布中显示一个jpg。它与png配合得很好,我也知道如何用java将jpg转换为png,所以最后我在文件系统上有了一个新的png文件。 现在我的问题是:有没有办法从文件系统读取jpg文件,在运行时设置透明颜色(转换为png)并在运行时显示图像? 附加注释:我尝试在自定义视图中使用ondraw方法和drawbitmap来实现这一点。我不能使用imageview: