java 窗口文本_Java:点击窗口(包括文本/图像)

本文介绍了如何在Java中创建一个透明且始终位于顶部的窗口,允许点击穿透。作者遇到的问题是,当添加JLabel或ImagePanel等组件后,点击事件无法传递到窗口。解决方案涉及设置窗口的WS_EX_LAYERED和WS_EX_TRANSPARENT标志,并使用JNA库来实现Windows系统的点击穿透效果。
摘要由CSDN通过智能技术生成

我想在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值