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

Car*_*son 10 java swing click-through transparent jna

我想在Java中创建一个透明的覆盖层,总是在顶部,并且我可以点击.我发现了一些关于这个问题的类似 帖子,但即使按照他们的答案,我也有一个问题.

我的问题是让整个窗口点击.我并没有使其与一个JFrame工作的任何问题,但一旦我添加任何成分给它(的JLabel或ImagePanel)中,点击通过属性不结转给他们.

因为我想为我的应用程序提供一个背景图像,这基本上使我无法看到当我单击文本/图像所覆盖的区域时窗口如何聚焦的代码.

在我展示我正在使用的代码之前,我首先想要参考这些 线程,这些线程基本上准确地描述了我想要的东西,除了在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,问题不在于窗口是否被聚焦(尽管这是问题的结果),而是关于JLabel和ImagePanel不是点击.

Mik*_*rin 1

我尝试制作完全“事件透明”(如您所说的点击)窗口,但该技巧似乎存在一些本机限制。

检查这个窗口示例:

public static void main ( String[] args )
{
    Window w = new Window ( null );

    w.add ( new JComponent ()
    {
        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 );
        }

        public boolean contains ( int x, int y )
        {
            return false;
        }
    } );

    AWTUtilities.setWindowOpaque ( w, false );
    AWTUtilities.setWindowOpacity ( w, 0.5f );

    w.pack ();
    w.setLocationRelativeTo ( null );
    w.setVisible ( true );
}
Run Code Online (Sandbox Code Playgroud)

窗口和组件没有任何:

  1. 鼠标监听器
  2. 鼠标动作监听器
  3. 鼠标滚轮监听器
  4. 主要听众

此外,即使由于修改的方法而存在任何侦听器,组件也应忽略任何类型的鼠标事件contains

正如您所看到的 - 组件上未绘制任何内容的区域是事件透明的,但填充的区域则不是。不幸的是,我没有找到任何解决方法来改变这种行为。似乎一些“低级”java 方法正在阻止事件。

这只是一个基于 JComponent 的基本示例。我什至没有提及更复杂的 Swing 组件,例如标签、按钮等,它们可能有自己的事件侦听器,可能会阻止事件。