如何在按下按钮时检测节点上的鼠标移动? [英] How to detect mouse movement over node while button is pressed?

查看:163
本文介绍了如何在按下按钮时检测节点上的鼠标移动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



您可以向检测鼠标在其上移动的节点添加事件侦听器。如果在移动节点之前按下鼠标按钮,则不起作用。



问题



有人知道如何在按下按钮时检测鼠标移动吗?到目前为止,我只是通过使用,例如 MOUSE_DRAG_OVER MOUSE_DRAG_ENTERED 具有相应 targetNode.setOn< MouseDragEvent>()方法的事件。


Problem

You can add an event listener to a node which detects mouse movement over it. This doesn't work if a mouse button was pressed before you moved over the node.

Question

Does anyone know how to detect mouse movement while the button is pressed? So far I've only found a solution by using the MOUSE_DRAGGED event and then instead of using getSource() using getPickResult() and evaluating the PickResult data.

Here's the code including Uluk's solution. The old and new solution are switchable via the useNewVersion (Uluk's version) boolean:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    boolean useNewVersion= true;

    int rows = 10;
    int columns = 20;
    double width = 1024;
    double height = 768;

    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();

            // create grid
            Grid grid = new Grid( columns, rows, width, height);

            MouseGestures mg = new MouseGestures();

            // fill grid
            for (int row = 0; row < rows; row++) {
                for (int column = 0; column < columns; column++) {

                    Cell cell = new Cell(column, row);

                    mg.makePaintable(cell);

                    grid.add(cell, column, row);
                }
            }

            root.setCenter(grid);

            // create scene and stage
            Scene scene = new Scene(root, width, height);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();



        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    private class Grid extends Pane {

        int rows;
        int columns;

        double width;
        double height;

        Cell[][] cells;

        public Grid( int columns, int rows, double width, double height) {

            this.columns = columns;
            this.rows = rows;
            this.width = width;
            this.height = height;

            cells = new Cell[rows][columns];

        }

        /**
         * Add cell to array and to the UI.
         */
        public void add(Cell cell, int column, int row) {

            cells[row][column] = cell;

            double w = width / columns;
            double h = height / rows;
            double x = w * column;
            double y = h * row;

            cell.setLayoutX(x);
            cell.setLayoutY(y);
            cell.setPrefWidth(w);
            cell.setPrefHeight(h);

            getChildren().add(cell);

        }

    }

    private class Cell extends StackPane {

        int column;
        int row;

        public Cell(int column, int row) {

            this.column = column;
            this.row = row;

            getStyleClass().add("cell");

            Label label = new Label(this.toString());

            getChildren().add(label);
        }

        public void highlight() {
            getStyleClass().add("cell-highlight");
        }

        public void unhighlight() {
            getStyleClass().remove("cell-highlight");
        }

        public String toString() {
            return this.column + "/" + this.row;
        }
    }

    public class MouseGestures {

        public void makePaintable( Node node) {

            if( useNewVersion) {

                node.setOnMousePressed( onMousePressedEventHandler);
                node.setOnDragDetected( onDragDetectedEventHandler);
                node.setOnMouseDragEntered( onMouseDragEnteredEventHandler);

            } else {

                node.setOnMousePressed( onMousePressedEventHandler);
                node.setOnMouseDragged( onMouseDraggedEventHandler);
                node.setOnMouseReleased( onMouseReleasedEventHandler);

            }

        }

        /* old version */

        EventHandler<MouseEvent> onMousePressedEventHandler = event -> {

            Cell cell = (Cell) event.getSource();

            if( event.isPrimaryButtonDown()) {
                cell.highlight();
            } else if( event.isSecondaryButtonDown()) {
                cell.unhighlight();
            }
        };

        EventHandler<MouseEvent> onMouseDraggedEventHandler = event -> {

            PickResult pickResult = event.getPickResult();
            Node node = pickResult.getIntersectedNode();

            if( node instanceof Cell) {

                Cell cell = (Cell) node;

                if( event.isPrimaryButtonDown()) {
                    cell.highlight();
                } else if( event.isSecondaryButtonDown()) {
                    cell.unhighlight();
                }       

            }

        };

        EventHandler<MouseEvent> onMouseReleasedEventHandler = event -> {
        };

        EventHandler<MouseEvent> onDragDetectedEventHandler = event -> {

            Cell cell = (Cell) event.getSource();
            cell.startFullDrag();

        };

        EventHandler<MouseEvent> onMouseDragEnteredEventHandler = event -> {

            Cell cell = (Cell) event.getSource();

            if( event.isPrimaryButtonDown()) {
                cell.highlight();
            } else if( event.isSecondaryButtonDown()) {
                cell.unhighlight();
            }       

        };

    }

}

In the end you should be able to paint via primary mouse button and erase the paint via secondary mouse button:

解决方案

The (source) node which handles the initial DRAG_DETECTED event should invoke sourceNode.startFullDrag(), then the target node will able to handle one of MouseDragEvents, for instance MOUSE_DRAG_OVER or MOUSE_DRAG_ENTERED event with respective targetNode.setOn<MouseDragEvent>() method.

这篇关于如何在按下按钮时检测节点上的鼠标移动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆