【问题标题】:how to set JFrame background transparent but JPanel or JLabel Background opaque?如何设置 JFrame 背景透明但 JPanel 或 JLabel 背景不透明?
【发布时间】:2012-07-27 01:49:17
【问题描述】:

根据任务,我们必须创建一个像 Picasa 一样的图像查看器。中间的图片,半透明的黑色背景和左/右按钮改变图像。

我可以显示将其设置为底涂的图像,将其设置为半透明框架,但随着框架,图片变得半透明。我做错了什么。

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();   

JFrame f1 = new JFrame("ShowImage");
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f1.setSize(dim);

f1.setUndecorated(true);
f1.setOpacity(0.5f);
ShowImage panel = new ShowImage();
panel.setBackground(Color.black);

f1.setContentPane(panel); 
f1.setVisible(true);  

我试过了

si.setOpaque();   
si.setBackground(Color.black);
si.setForeground(Color.red);

没有用

当我取一个布尔值并进行测试时

si.isDisplayable();
si.isVisible();
si.isShowing();

只有可见的返回真,其余的都是假,这些是任何影响因素吗?

【问题讨论】:

  • JLabel 默认情况下是非透明的,为什么你希望它不是?有什么特殊需要吗?
  • JLabel 只是一种显示图片的方法,我认为它是最简单的方法。我试图实现的是透明背景(窗口)和不透明的前景(由 JLabel 导入的图片)。但我以正确的方式导入了它。所以我怀疑标签是否是必要的。感谢您的努力
  • “我试过” si.setOpaque(); 那会是编译错误。为了尽快获得更好的帮助,请发帖SSCCE

标签: java image swing jframe image-viewer


【解决方案1】:

问题是,JFrame 的默认Layout 管理器是BorderLayout,这意味着您的ShowImage 窗格正在填充框架的整个区域(黑色)。我敢打赌,如果您将ShowPane 的背景更改为红色。它会显示为完全填充为红色

现在您可以查看 A Visual Guide to Layout Managers 或更改 ShowPane 的工作方式

更新

抱歉,我不熟悉 Java 7 中的新 Transparency API(仍在使用 Java 6 hack ;))

您能帮我验证一下这就是您正在寻找的那种效果吗?读取的正方形将是图像(黑色背景是框架-nb,我只捕获了框架)

更新

首先您需要阅读Window.isOpaqueWindow.setBackground 以了解此解决方案的工作原理。

接下来,不要使用Window.setOpacity,它不会达到你想要的效果。主要原因是 opacity 值应用于父级及其子级(最初是通过我)。

那么,框架代码:

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Make sure where in the top left corner, please lookup how
// to find the screen insets ;)
setLocation(0, 0);
setSize(dim);
// Set undecorated
setUndecorated(true);
// Apply a transparent color to the background
// This is ALL important, without this, it won't work!
setBackground(new Color(0, 255, 0, 0));

// This is where we get sneaky, basically where going to 
// supply our own content pane that does some special painting
// for us
setContentPane(new ContentPane());
getContentPane().setBackground(Color.BLACK);
setLayout(new BorderLayout());

// Add out image pane...    
ShowImage panel = new ShowImage();
add(panel);

setVisible(true);

ContentPane。基本上,我们需要“欺骗”绘制引擎,让其思考透明(不透明)的位置,然后绘制我们自己的不透明度

public class ContentPane extends JPanel {

    public ContentPane() {

        setOpaque(false);

    }

    @Override
    protected void paintComponent(Graphics g) {

        // Allow super to paint
        super.paintComponent(g);

        // Apply our own painting effect
        Graphics2D g2d = (Graphics2D) g.create();
        // 50% transparent Alpha
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));

        g2d.setColor(getBackground());
        g2d.fill(getBounds());

        g2d.dispose();

    }

}

我很抱歉我之前的回答,但我希望这可以弥补它;)

使用按钮更新

我就是这样修改的

ShowImage panel = new ShowImage();
panel.setBackground(Color.RED);

setContentPane(new ContentPane());
getContentPane().setBackground(Color.BLACK);
setLayout(new BorderLayout());
add(panel);

JPanel pnlButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
pnlButtons.setOpaque(false);
pnlButtons.add(new JButton("<<"));
pnlButtons.add(new JButton("<"));
pnlButtons.add(new JButton(">"));
pnlButtons.add(new JButton(">>"));

// Okay, in theory, getContentPane() is required, but better safe the sorry
getContentPane().add(pnlButtons, BorderLayout.SOUTH);

setVisible(true);

【讨论】:

  • 不,它不起作用,我将背景更改为红色,但仍然是半透明的。我需要将其更改为不透明,使 jframe 保持半透明。正如我提到的,我 setBackground 但它没有用。注意 ShowImage 只是我在其中创建的类。
  • 等一下,我想我可能知道发生了什么,让我再进行一些测试,看看我是否能成功;)
  • 你能验证我的更新是否在正确的轨道上,如果是这样,我会发布一些代码来说明如何让它工作
  • @sabbibJAVA 希望新的更新能更好地满足您的要求
  • 你在哪里工作,Java?或者高中生太笨了:P我在开玩笑。谢谢它就像一个魅力,即使程序进行到一半。我只是好奇,您是如何看到我的问题的,或者您是否浏览过帮助他人,我非常感谢您的帮助。我希望你能回答我未来的问题。再次感谢您。