JavaFX检测场景外鼠标移动

3
我正在尝试构建一个颜色选择器,用户可以看到鼠标指针所在位置的 RGB 值。
问题是,当鼠标指针移出场景时,它无法工作。但我使用另一个 KeyTyped 事件,那个事件正常工作。也就是说,当鼠标指针在场景外并且您按下任何键时,您可以看到鼠标指向的 RGB 值。
现在,
  1. 有没有办法在鼠标移动时使用 KeyTyped 事件?
  2. 有没有其他方法来检测场景外的鼠标指向位置?
以下是代码:
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/*
 * @author sapaythhossain
 */
public class ColorPicker extends Application {

    private Stage window;
    private Scene scene;
    private double width;
    private double height;
    private String title;
    private Label colorLabel;
    private Label rgbLabel;
    private Label htmlLabel;
    private Label rgbValueLabel;
    private Label htmlValueLabel;
    private Label bValueLabel;

    private int RGBr;
    private int RGBg;
    private int RGBb;

    private Color currentColor;
    private Robot robot;

    @Override
    public void start(Stage primaryStage) throws Exception {
        title = "Color Picker";
        width = 220;
        height = 80;

        robot = new Robot();

        window = primaryStage;
        window.setTitle(title);

        colorLabel = new Label();
        colorLabel.setWrapText(true);
        colorLabel.setMinSize(50, 50);
        colorLabel.setStyle(
                "-fx-background-color: rgba(" + RGBr + "," + RGBg + "," + RGBb + ",1);"
            );

        VBox leftRow = new VBox(10);
        leftRow.getChildren().addAll(colorLabel);

        rgbLabel = new Label("RGB: ");
        htmlLabel = new Label("HTML: ");

        rgbValueLabel = new Label("");
        htmlValueLabel = new Label("");
        bValueLabel = new Label();

        VBox middleRow = new VBox();
        middleRow.getChildren().addAll(rgbLabel, htmlLabel);

        VBox rightRow = new VBox();
        rightRow.getChildren().addAll(rgbValueLabel, htmlValueLabel, bValueLabel);

        HBox layout = new HBox(10);
        layout.getChildren().addAll(leftRow, middleRow, rightRow);

        EventHandler handler = (EventHandler) (Event event) -> {
            changeColor();
        };

        scene = new Scene(layout, width, height);
        scene.setOnMouseMoved(handler);
        scene.setOnKeyTyped(handler);



        window.setScene(scene);
        window.show();
    }

    public void changeColor() {
        Point p = MouseInfo.getPointerInfo().getLocation();
        currentColor = robot.getPixelColor(p.x, p.y);

        RGBr = currentColor.getRed();
        RGBg = currentColor.getGreen();
        RGBb = currentColor.getBlue();

        String colorString = String.valueOf(RGBr) + ", "
                + String.valueOf(RGBg) + ", " + String.valueOf(RGBb);

        colorLabel.setStyle(
                "-fx-background-color: rgba(" + RGBr + "," + RGBg + "," + RGBb + ",1);"
            );
        String hex = String.format("#%02x%02x%02x", RGBr, RGBg, RGBb);
        htmlValueLabel.setText(hex);
        rgbValueLabel.setText(colorString);
    }

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

}

提前感谢您。


你可以使用Jnativehook库来实现此目的,它可以捕获所有事件,即使它在Java应用程序之外。 - MaQuiNa1995
非常感谢您的建议。我对Java还很陌生。您能否告诉我使用Jnativehook库应该遵循哪些步骤? - sapayth
https://dev59.com/mmQn5IYBdhLWcg3wr446 - SedJ601
1个回答

2
好的,你需要做以下几步:
在你的类中实现 NativeMouseInputListener 接口
然后你需要注册钩子:
private void createHook() {
    try {
        // here you starts the hook
        GlobalScreen.registerNativeHook();
    } catch (NativeHookException ex) {
        //TODO Exception handling
    }

    // here you add the listener for the hook
    GlobalScreen.addNativeMouseListener(this);
}

然后您需要选择鼠标事件并将其放入getMousePointColor()方法中:

    @Override
    public void nativeMouseClicked(NativeMouseEvent nme) {
    }

    @Override
    public void nativeMousePressed(NativeMouseEvent nme) {
    }

    @Override
    public void nativeMouseReleased(NativeMouseEvent nme) {
    }

    @Override
    public void nativeMouseMoved(NativeMouseEvent nme) {
    }

    @Override
    public void nativeMouseDragged(NativeMouseEvent nme) {
    }

private void getMousePointColor() {
    int xLocation = MouseInfo.getPointerInfo().getLocation().x;
    int yLocation = MouseInfo.getPointerInfo().getLocation().y;
    System.out.println("------------------------------------------------------");

    Robot r;
    try {
        r = new Robot();
        System.out.println(r.getPixelColor(xLocation, yLocation));
    } catch (AWTException ex) {
        //TODO Exception handling
    }
    System.out.println("------------------------------------------------------");
}

例如:

@Override
    public void nativeMouseClicked(NativeMouseEvent nme) {
        getMousePointColor();
    }

JNative Hook 最新版本

JNative Hook 文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接