ProblemWie erkennt man die Mausbewegung über den Knoten, während die Taste gedrückt wird?
Sie können einen Ereignis-Listener zu einem Knoten hinzuzufügen, die über sie Mausbewegung erkennt. Dies funktioniert nicht, wenn eine Maustaste gedrückt wurde, bevor Sie den Knoten bewegt haben.
Frage
Wer weiß, wie die Mausbewegung zu erfassen, während die Taste gedrückt wird? Bis jetzt habe ich nur eine Lösung gefunden, indem ich das MOUSE_DRAGGED Ereignis und dann anstelle getSource() benutze getPickResult() und Auswertung der PickResult Daten.
Hier ist der Code einschließlich Uluks Lösung. Die alte und neue Lösung sind schaltbar über die useNewVersion (uluk-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();
}
};
}
}
Am Ende sollten Sie in der Lage sein, über primäre Maustaste zu malen und die Farbe über die rechte Maustaste löschen:
Ist das 'node' unterscheidet sich von der' Button'? Ich verstehe deine Frage nicht genau. Versuchen Sie, die Mausbewegung auf demselben Button zu lesen, wenn Sie darauf drücken? – ItachiUchiha
Der Knoten, der das anfängliche DRAG_DETECTED-Ereignis behandelt, sollte sourceNode.startFullDrag() aufrufen, dann kann der Zielknoten MOUSE_DRAG_OVER-Ereignisse mit der targetNode.setOnMouseDragOver() -Methode behandeln. –
@ItachiUchia: Ich meinte Maustaste. Ich änderte es und fügte Code einschließlich Uluks Version hinzu. Ich brauchte es für den A * -Algorithmus, den ich gestern gepostet habe, so dass es einfacher ist, verschiedene Arten von Wänden durch einfaches Ziehen mit der Maus zu zeichnen (während der primäre Button gedrückt wird). Es funktionierte, aber PickResult fühlte sich merkwürdig an. – Roland