Javafx click on a Circle and get it's reference

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

I have a set of Nodes, Circles, on the stage. I want to be able to click on one of them and 'select it' (just get a reference to it so I can move it around, change color etc.)

    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<MouseEvent>() {         @Override         public void handle(MouseEvent mouseEvent) {             // how do I get which Circle I clicked on?         }     });      stage.setTitle(TITLE);     stage.setScene(scene);     stage.show(); 

回答1:

I would simply register a listener with each circle itself. Then you already have the reference to the circle with which the listener was registered.

This example pushes the limit a little as to usability, because it has 10,000 circles shown all at once, but it demonstrates the technique:

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<Circle> selectedCircle = new SimpleObjectProperty<>();       private final ObjectProperty<Point2D> 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);     } } 

with the file grid.css:

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


回答2:

You can get the reference by using getSource of the MouseEvent.

Example in which you can drag a Circle and any other Node:

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<MouseEvent> 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<MouseEvent> 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<MouseEvent> onMouseReleasedEventHandler = event -> {         };      }       public static void main(String[] args) {         launch(args);     } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!