我几天来一直在努力解决这个问题,阅读了很多解释,但当我尝试应用它们时,似乎没有任何效果。
我需要做的是创建一个自定义形状的窗口。我想要的方法是将窗口背景设置为如下图像:
总的来说,我用来尝试实现这一目标的方法是此处描述的方法 https://stackoverflow.com/a/13594794/1387451
但它不太有效。相反,它看起来好像 java 将我的背景解释为 alpha 蒙版:白色变得不透明,黑色变得透明。 我认为 java 能做到这一点非常棒,但这不是我需要的。
我尝试调整 JFrame
内容 Pane 的不透明度。没有什么。
我尝试使用 JLabel
或 JPanel
来显示图像,但没有效果。
请帮我解释一下。
这是相关代码。
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);
}
}
内容 Pane :
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。
这是我的程序执行此操作的两个屏幕截图:
将 ContentPane 涂成红色。
ContentPane 只是一个带有 setOpaque(false)
的普通 JPanel
。
(我们为什么要涂成红色?)
最佳答案
实际上只需要做两件事
setOpaque(false)
用于带有图像的面板。setBackground(new Color(0, 0, 0, 0))
框架,最后一个 0 是 alpha
奖励:为了让事情变得有趣,我添加了一个 MouseMotionListener
,这样你仍然可以移动它:)
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("/image/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/