Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将鼠标事件从Java UI传递给后面的应用程序_Java_Events_Mouse_Transparency - Fatal编程技术网

将鼠标事件从Java UI传递给后面的应用程序

将鼠标事件从Java UI传递给后面的应用程序,java,events,mouse,transparency,Java,Events,Mouse,Transparency,我的问题在需求上与完全相同,但我需要一个透明的JavaUI。我可以使用6.0轻松创建一个透明的Java UI,但无法获得有关通过应用程序将事件传递给后面任何应用程序(例如浏览器)的任何信息。您可以尝试使用Robot类,该类允许您为低级操作系统指定系统事件,特别是鼠标事件。我相信这会回答你的问题。要运行它,您需要Java6Update10及更高版本。 我在WindowsVista上测试了它 import java.awt.AlphaComposite; import java.awt.Color;

我的问题在需求上与完全相同,但我需要一个透明的JavaUI。我可以使用6.0轻松创建一个透明的Java UI,但无法获得有关通过应用程序将事件传递给后面任何应用程序(例如浏览器)的任何信息。

您可以尝试使用Robot类,该类允许您为低级操作系统指定系统事件,特别是鼠标事件。

我相信这会回答你的问题。要运行它,您需要Java6Update10及更高版本。 我在WindowsVista上测试了它

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class ClickThrough {

    public static void main(String[] args) {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame f = new JFrame("Test");
        f.setAlwaysOnTop(true);
        Component c = new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D)g.create();
                g2.setColor(Color.gray);
                int w = getWidth();
                int h = getHeight();
                g2.fillRect(0, 0, w,h);
                g2.setComposite(AlphaComposite.Clear);
                g2.fillRect(w/4, h/4, w-2*(w/4), h-2*(h/4));
            }
        };
        c.setPreferredSize(new Dimension(300, 300));
        f.getContentPane().add(c);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
        com.sun.awt.AWTUtilities.setWindowOpaque(f,false);
    }

}

请注意,您需要一个未装饰的窗口或一个仅由Java装饰的窗口(不是默认的操作系统装饰),否则代码将无法工作。

Savvas的回答对我非常有帮助,即使在使用Java 1.6.0的MacOS X 10.7.3上。谢谢 唯一的一件事是:我必须另外设置

f.setUndecorated(true);

这不是答案,而是一个更新,它将危险问题更正为公认的答案,并提供了一个与Java 7+兼容的示例。

逐像素alphering检查窗口中的每个像素,以确定其是否透明。如果它是透明的,则允许鼠标事件通过它,如果它不是透明的,则窗口将捕获鼠标事件。这通常是操作系统级别的问题

您提供的示例实际上是在做一些非常危险的事情,首先它在不透明组件上绘制半透明的颜色,这意味着Swing不知道它实际上应该在组件下绘制任何东西,还可能导致一些非常恶劣的绘制瑕疵,由于Swing只知道不透明和透明组件,它不知道半透明组件,所以需要欺骗API

执行自定义绘制时,应始终调用
super.paintComponent
,以确保在绘制之前正确设置了
图形
上下文。在您的情况下,还应该使用
setOpaque
使组件透明,并将其传递给
false

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestFrame {

    public static void main(String[] args) {
        new TestFrame();
    }

    public TestFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setAlwaysOnTop(true);
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLUE);
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
            g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
            g2d.dispose();
        }

    }

}

Robot可用于生成系统事件,但如果我的透明框架已经位于我需要单击的位置,java框架不会再次接收事件吗?您可以在玻璃窗格(阅读java教程)上捕捉偶数,然后简单地使用事件。您可以暂时隐藏窗口。它将引入一些闪烁,我知道,但我想不出其他的东西…仅仅因为你改变了窗口的不透明度并不意味着事件被传输通过。然后需要使用robot类触发事件。windows 7上的jdk 1.6、1.7、XP上的jdk 1.6、1.7似乎允许点击。但不确定其他操作系统……这是一个危险的例子,因为它试图在不透明组件上“伪造”透明度,这可能导致图形重影和其他图形瑕疵。我认为更好、更简单的解决方案是通过使用
setopue
并传递
false
使
组件
c
透明。您还破坏了绘制链。我发现这是在OS X 10.9和Java 1.7.0_4上无例外运行所必需的,但透明区域不允许单击事件传递到下面的应用程序。这似乎是一个平台相关的问题,在和中也有说明