gpt4 book ai didi

java - JFrame 的自定义透明背景出错

转载 作者:行者123 更新时间:2023-11-30 08:25:13 24 4
gpt4 key购买 nike

几天来我一直在努力解决这个问题,阅读了很多解释,但正如我尝试应用它们一样,似乎没有任何效果。

我需要做的是创建一个自定义形状的窗口。我想要这样做的方法是将窗口背景设置为这样的图像: Not like this one, but actually this one.

我用来尝试完成此操作的方法大体上就是此处描述的方法 https://stackoverflow.com/a/13594794/1387451

但它并不完全有效。相反,它看起来好像 java 将我的背景解释为 alpha 蒙版:白色变得不透明而黑色变得透明。我认为 java 可以做到这一点非常棒,但这不是我需要的。

我尝试调整我的 JFrame 内容 Pane 的不透明度。没有什么。我尝试对图像使用 JLabelJPanel 无济于事。

请帮我破译这个。

这是相关代码。

JFrame:

public class LectorWindow extends JFrame {

public LectorWindow() {
Dimension winSize = new Dimension(440, 80);
LectorDraggerListener dragger = new LectorDraggerListener(this);
addMouseListener(dragger);
addMouseMotionListener(dragger);

try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}

setUndecorated(true);
setBackground(new Color(0f, 0f, 0f, 0f));
setContentPane(new TransparentContentPane());

setSize(winSize);
int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
setLocation(screenWidth/2 - getWidth()/2, 0);

setLayout(new BorderLayout());

JPanel background = new BackgroundPanel();
background.setLayout(new BoxLayout(background, BoxLayout.X_AXIS));
add(background);

setResizable(false);
setAlwaysOnTop(true);

setUpSysTray();

setVisible(true);
}
}

内容面板:

public class TransparentContentPane extends JPanel {

private static final long serialVersionUID = -386560825154911212L;

public TransparentContentPane() {
setOpaque(false);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
}
}

和背景图片JPanel:

public final class BackgroundPanel extends JPanel {

private static final long serialVersionUID = -5526340149401796784L;

private BufferedImage background;

public BackgroundPanel() {
try {
background = ImageIO.read(BackgroundPanel.class.getResource("/lector/resources/background.png"));
} catch (IOException e) {
e.printStackTrace();
}
setOpaque(false);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(background.getWidth(), background.getHeight());
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);

if (background != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g2d.drawImage(background, x, y, this);
g2d.dispose();
}
}
}

我在启用了窗口合成的 XFCE 上使用 OpenJDK。 (我尝试禁用它,但后来一切变得更奇怪了)。我希望它能在 Java 7 上运行,我不关心 6。

这是我的程序执行此操作的两个屏幕截图: Very wrong

将 ContentPane 涂成红色。

A little less wrong but still...

ContentPane 只是一个带有 setOpaque(false) 的普通 JPanel。(我们为什么要画那个红色?)

最佳答案

真的只有两件事需要做

  1. setOpaque(false) 用于带有图像的面板。
  2. setBackground(new Color(0, 0, 0, 0)) 为框架,最后一个 0 是 alpha

奖励:为了让事情更有趣,我添加了一个 MouseMotionListener 这样你仍然可以移动它:)

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ImageFrame {
private final JFrame frame = new JFrame();
public ImageFrame() {
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.add(new BackGroundPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public class BackGroundPanel extends JPanel {

BufferedImage image;
int pX, pY;

public BackGroundPanel() {
try {
image = ImageIO.read(new URL("http://i.stack.imgur.com/efS42.png"));
} catch (IOException ex) {
Logger.getLogger(ImageFrame.class.getName()).log(Level.SEVERE, null, ex);
}
setOpaque(false);

addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
// Get x,y and store them
pX = me.getX();
pY = me.getY();
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent me) {
frame.setLocation(frame.getLocation().x + me.getX() - pX,
frame.getLocation().y + me.getY() - pY);
}
});
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), this);
}
}

@Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(300, 300) : new Dimension(image.getWidth(), image.getHeight());
}
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ImageFrame();
}
});
}
}

编辑

我只是实际尝试了您的代码,它似乎有效,因为您摆脱了 TransparentContentPane 作为内容 Pane 。我不知道那是什么?

关于java - JFrame 的自定义透明背景出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22329141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com