【问题标题】:JButton Transparency on an BufferedImageBufferedImage 上的 JButton 透明度
【发布时间】:2011-09-12 09:09:50
【问题描述】:

我有一个问题:

我在 JFrame 中渲染一个 BufferedImage。然后我将一个 JButton 添加到同一帧。 当我尝试使按钮透明时,按钮变得透明,但不管它的实际位置,它总是透明的,就像它卡在框架的左上角一样。 我测试了一些不同的方法来使按钮透明,总是得到相同的结果。

有什么想法吗?

谢谢

public class TestPanel extends JPanel {

public TestPanel(){
    JButton foo = new JButton("test");
    foo.setBackground(new Color(0, 0, 0, 0));
    foo.setBounds(20, 100, 300, 50);
    this.add(foo);
}

public void paint(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.drawImage(ImageFactory.getImg(), 0, 0, null); //get a BufferedImage
    g2.dispose();
}

}

【问题讨论】:

    标签: java swing transparency jbutton bufferedimage


    【解决方案1】:

    我看到了几个问题,即使我不确定是哪一个导致了您的问题。我尝试按顺序列出它们:

    1. 您的 TestPanel 没有指定 LayoutManager(我希望您在代码中的其他位置指定它)。
    2. 您正在扩展 JPanel 而不调用 super paintComponent 方法(不要使用paint)。您应该在您的 paintComponent 方法中的任何其他操作之前执行此操作:

      public void paintComponent(Graphics g){
          super.paintComponent(g); 
      }
      
    3. 删除 dispose 方法调用。您不得破坏您的图形对象。

    编辑:

    1. 这是个问题:

      foo.setBounds(20, 100, 300, 50);
      

      您正在尝试显式设置 JButton 的边界。你不应该那样做。如果您使用的是 LayoutManager,它可能会忽略此指令。如果您使用的是空布局,这也可能是个问题。

    【讨论】:

    • 我认为布局问题与 LayoutManager 问题有关。您是否指定了 LayoutManager?如果是,是哪一个,在哪里以及如何?贴出相关代码。
    • @Heisenbug 请将paint() 方法(和两者)更改为paintComponent() :-) +1
    • 不是“不需要破坏”,而是“不能破坏”:)
    • 好的,已修复。问题确实是空布局。现在它可以完美地与 opaque 设置为 false 和透明背景颜色。谢谢!
    【解决方案2】:

    几个问题

    • 覆盖paint是错误的,而是覆盖paintComponent
    • 按钮具有完全透明的背景,但不透明时返回 true,从而欺骗了绘制机制
    • 将传入的Graphics作为参数dispose是错误的

    工作代码(编辑:不小心移除了透明颜色设置线,已修复)

    public TestPanel(){
        JButton foo = new JButton("test");
        foo.setBackground(new Color(0, 0, 0, 0));
        foo.setOpaque(false);
        foo.setBorder(BorderFactory.createLineBorder(Color.RED));
        this.add(foo);
    }
    
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(ImageFactory.getImg(), 0, 0, null); //get a BufferedImage
       //   g2.dispose();
    }
    

    正如其他人已经指出的那样:LayoutManager 是 Swing/AWT 中的必须 - 不使用它们会使 ui 代码变得脆弱且难以维护。

    【讨论】:

      【解决方案3】:

      setBound() 仅在您将布局设置为 null 时才有效。您的代码没有这样说。 现在,JPanel 的默认布局管理器是FlowLayout。默认情况下,此布局管理器会将您的组件从左到右然后从上到下排列。

      现在,让您的代码按预期工作。在构造函数中添加这一行:setLayout(null)。 但请记住,将布局设置为 null 是一种非常糟糕的做法。 另外,Heisenbug 提到的几点也很有价值。尝试关注他们。

      【讨论】:

      • -1 ".. 仅当您将布局设置为 null 时才有效。" ..此时所有 else 都将开始失败。 使用布局。
      • @Andrew:谢谢你的意见。我的意思是“如果布局为空,setBound() 将是有效的”。现在同意了吗? :)
      • 不会改变将布局设置为 null 的坏主意这一事实。现在同意了吗?
      • @Andrew:哦。我误解了你的第一条评论。我还在回答中提到这是一个非常糟糕的主意:“但请记住,将布局设置为 null 是一种非常糟糕的做法”。我只是想弄清楚为什么代码没有按预期工作。甚至我推荐了后来被接受的 Heisenbug 的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2021-11-01
      • 2015-01-11
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      相关资源
      最近更新 更多