问题
您可以向检测鼠标在其上移动的节点添加事件侦听器.如果在移动节点之前按下鼠标按钮,则不起作用.
题
有人知道如何在按下按钮时检测鼠标移动吗?到目前为止,我只是通过使用MOUSE_DRAGGED事件找到了解决方案,然后使用getPickResult()而不是使用getSource()并评估PickResult数据.
这是代码,包括Uluk的解决方案.旧的和新的解决方案可通过useNewVersion(Uluk的版本)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();
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您应该能够通过主鼠标按钮绘制并通过辅助鼠标按钮擦除绘画:

一种解决方案是向场景添加事件过滤器,以启用sourceNode.startFullDrag().即使您开始将鼠标拖到画布外部(如果您想要在应用程序中没有节点的任何空间),这也会起作用.
像这样:
scene.addEventFilter(MouseEvent.DRAG_DETECTED , new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
scene.startFullDrag();
}
});
Run Code Online (Sandbox Code Playgroud)
然后你可以:
node.setOnMouseDragEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
led.setOn(true);
}
});
Run Code Online (Sandbox Code Playgroud)
处理初始DRAG_DETECTED事件的(源)节点应该调用sourceNode.startFullDrag(),然后目标节点将能够处理MouseDragEvent之一,例如MOUSE_DRAG_OVER或MOUSE_DRAG_ENTERED具有相应targetNode.setOn<MouseDragEvent>()方法的事件。
| 归档时间: |
|
| 查看次数: |
7168 次 |
| 最近记录: |