Javafx点击Circle并获得它的参考

我在舞台上有一组节点,圆圈。 我希望能够点击其中一个并“选择它”(只需获取它的引用,这样我就可以移动它,改变颜色等)

Pane root = new Pane(); root.getChildren().addAll( /* an array of Circle objects */ ); Scene scene = new Scene(root, 500, 500, BACKGROUND_COLOR); scene.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent mouseEvent) { // how do I get which Circle I clicked on? } }); stage.setTitle(TITLE); stage.setScene(scene); stage.show(); 

我只想在每个圆圈中注册一个听众。 然后,您已经获得了监听器注册的圆圈的引用。

这个例子略微提高了可用性,因为它有10,000个圆圈同时显示,但它演示了这个技术:

 import javafx.application.Application; import javafx.beans.binding.Bindings; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.css.PseudoClass; import javafx.geometry.Point2D; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.stage.Stage; public class GridOfCircles extends Application { private static final PseudoClass SELECTED_P_C = PseudoClass.getPseudoClass("selected"); private final int numColumns = 100 ; private final int numRows = 100 ; private final double radius = 4 ; private final double spacing = 2 ; private final ObjectProperty selectedCircle = new SimpleObjectProperty<>(); private final ObjectProperty selectedLocation = new SimpleObjectProperty<>(); @Override public void start(Stage primaryStage) { selectedCircle.addListener((obs, oldSelection, newSelection) -> { if (oldSelection != null) { oldSelection.pseudoClassStateChanged(SELECTED_P_C, false); } if (newSelection != null) { newSelection.pseudoClassStateChanged(SELECTED_P_C, true); } }); Pane grid = new Pane(); for (int x = 0 ; x < numColumns; x++) { double gridX = x*(spacing + radius + radius) + spacing ; grid.getChildren().add(new Line(gridX, 0, gridX, numRows*(spacing + radius + radius))); } for (int y = 0; y < numRows ; y++) { double gridY = y*(spacing + radius + radius) + spacing ; grid.getChildren().add(new Line(0, gridY, numColumns*(spacing + radius + radius), gridY)); } for (int x = 0 ; x < numColumns; x++) { for (int y = 0 ;y < numRows ; y++) { grid.getChildren().add(createCircle(x, y)); } } Label label = new Label(); label.textProperty().bind(Bindings.createStringBinding(() -> { Point2D loc = selectedLocation.get(); if (loc == null) { return "" ; } return String.format("Location: [%.0f, %.0f]", loc.getX(), loc.getY()); }, selectedLocation)); BorderPane root = new BorderPane(new ScrollPane(grid)); root.setTop(label); Scene scene = new Scene(root); scene.getStylesheets().add("grid.css"); primaryStage.setScene(scene); primaryStage.show(); } private Circle createCircle(int x, int y) { Circle circle = new Circle(); circle.getStyleClass().add("intersection"); circle.setCenterX(x * (spacing + radius + radius) + spacing); circle.setCenterY(y * (spacing + radius + radius) + spacing); circle.setRadius(radius); circle.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { selectedCircle.set(circle); selectedLocation.set(new Point2D(x, y)); }); return circle ; } public static void main(String[] args) { launch(args); } } 

使用grid.css文件:

 .intersection { -fx-fill: blue ; } .intersection:selected { -fx-fill: gold ; } 

您可以使用MouseEvent的 getSource获取引用。

您可以拖动Circle和任何其他节点的示例:

 import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.scene.text.Text; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception { Circle circle = new Circle( 100,100,50); circle.setStroke(Color.BLUE); circle.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3)); Rectangle rectangle = new Rectangle( 0,0,100,100); rectangle.relocate(200, 200); rectangle.setStroke(Color.GREEN); rectangle.setFill(Color.GREEN.deriveColor(1, 1, 1, 0.3)); Text text = new Text( "Example Text"); text.relocate(300, 300); Pane root = new Pane(); root.getChildren().addAll(circle, rectangle, text); MouseGestures mouseGestures = new MouseGestures(); mouseGestures.makeDraggable(circle); mouseGestures.makeDraggable(rectangle); mouseGestures.makeDraggable(text); Scene scene = new Scene(root, 1024, 768); primaryStage.setScene(scene); primaryStage.show(); } public static class MouseGestures { class DragContext { double x; double y; } DragContext dragContext = new DragContext(); public void makeDraggable( Node node) { node.setOnMousePressed( onMousePressedEventHandler); node.setOnMouseDragged( onMouseDraggedEventHandler); node.setOnMouseReleased(onMouseReleasedEventHandler); } EventHandler onMousePressedEventHandler = event -> { if( event.getSource() instanceof Circle) { Circle circle = (Circle) (event.getSource()); dragContext.x = circle.getCenterX() - event.getSceneX(); dragContext.y = circle.getCenterY() - event.getSceneY(); } else { Node node = (Node) (event.getSource()); dragContext.x = node.getTranslateX() - event.getSceneX(); dragContext.y = node.getTranslateY() - event.getSceneY(); } }; EventHandler onMouseDraggedEventHandler = event -> { if( event.getSource() instanceof Circle) { Circle circle = (Circle) (event.getSource()); circle.setCenterX( dragContext.x + event.getSceneX()); circle.setCenterY( dragContext.y + event.getSceneY()); } else { Node node = (Node) (event.getSource()); node.setTranslateX( dragContext.x + event.getSceneX()); node.setTranslateY( dragContext.y + event.getSceneY()); } }; EventHandler onMouseReleasedEventHandler = event -> { }; } public static void main(String[] args) { launch(args); } }