我想在Java中创建一个透明的覆盖层,总是在顶部,并且我可以点击.我已经找到了关于这个问题的一些similar posts,但即使在听完他们的答案后,我也遇到了一个问题.
我的问题是让整个窗口点击.我在使用JFrame时没有任何问题,但是一旦我向它添加了任何组件(JLabel或ImagePanel),点击属性就不会延续到它们.
因为我想为我的应用程序提供一个背景图像,这基本上使我无法看到当我单击文本/图像所覆盖的区域时窗口如何聚焦的代码.
在我展示我正在使用的代码之前,我首先要参考these threads,它基本上描述了我想要的东西,除了在C#中.
我的目标是创建一个带有透明.png图像的叠加层和一些将在关键事件上更改的文本.如果它使用JFrame或任何其他库无关紧要.我只需要它与Windows兼容.
我还想提一下,我有一些Java经验,但是使用JFrame是一个新手.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import com.sun.jna.platform.WindowUtils;
public class Overlay {
public static void main(String[] args) {
JFrame frame = new JFrame("Overlay Window");
frame.setUndecorated(true);
frame.setAlwaysOnTop(true);
frame.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", false);
frame.setLocation(400, 400);
frame.getContentPane().setLayout(new java.awt.BorderLayout());
JLabel textLabel = new JLabel("I'm a label in the window", SwingConstants.CENTER);
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
frame.pack();
System.setProperty("sun.java2d.noddraw", "true");
WindowUtils.setWindowTransparent(frame, true);
WindowUtils.setWindowAlpha(frame, 1.0f);
//Using AWTUtilities gives the same result as WindowUtils
//AWTUtilities.setWindowOpaque(frame, false);
//AWTUtilities.setWindowOpacity(frame, 1.0f);
frame.setVisible(true);
}
}
请注意,问题不在于窗口是否被聚焦(尽管这是问题的结果),而是关于JLabel和ImagePanel不是点击.
解决方法:
使窗口“点击”的问题在于它是在系统级别上处理的,超出了标准API的范围.这意味着为使窗口“点击”而编写的任何代码都将取决于系统.话虽如此,在Windows上实现这一目标的过程相当直接.
在Windows 2000及更高版本中,通过在窗口上设置标志WS_EX_LAYERED and WS_EX_TRANSPARENT,然后将单击该窗口.示例代码使用JNA来完成此任务:
public static void main(String[] args) {
Window w = new Window(null);
w.add(new JComponent() {
/**
* This will draw a black cross on screen.
*/
protected void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, getHeight() / 2 - 10, getWidth(), 20);
g.fillRect(getWidth() / 2 - 10, 0, 20, getHeight());
}
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
});
w.pack();
w.setLocationRelativeTo(null);
w.setVisible(true);
w.setAlwaysOnTop(true);
/**
* This sets the background of the window to be transparent.
*/
AWTUtilities.setWindowOpaque(w, false);
setTransparent(w);
}
private static void setTransparent(Component w) {
WinDef.HWND hwnd = getHWnd(w);
int wl = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT;
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
}
/**
* Get the window handle from the OS
*/
private static HWND getHWnd(Component w) {
HWND hwnd = new HWND();
hwnd.setPointer(Native.getComponentPointer(w));
return hwnd;
}
标签:jna,java,swing,transparent,click-through
来源: https://codeday.me/bug/20190926/1822087.html