有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使点可拖动并存储新坐标JavaFx

我有这个:

Circle circle = null; 
List<Circle> circles = new ArrayList<>();

for(List row: list)  //list is list of coordinates i.e. [[200,100],[10,5.5],[15,100],[200,25]...]        
{
    circle = new Circle((double) row.get(0), (double) row.get(1), 4f);
    circle.setFill(Color.BLUE);

    Tooltip toolTipx = new Tooltip("The point is : " + (double) row.get(0));
    Tooltip.install(circle, toolTipx);

    circles.add(circle);
}
        
System.out.println(circles.size());
Pane pane = new Pane();
pane.getChildren().addAll(circles);

这将完美地在窗口上绘制所述点,工具提示将描绘该点的坐标

现在,我想要的是创建可拖动的绘制点。这样我就可以将点拖动到窗口中的任何位置,新的位置(拖动点的坐标)将存储在工具提示或窗口末端的固定标签中

我遇到了this(makeDraggable()),但找不到一个起点

我怎样才能做到这一点?谢谢


共 (2) 个答案

  1. # 1 楼答案

    使用:

    circle.setOnMouseDragged( event -> {
                 circle.setCenterX(event.getX());
                circle.setCenterY(event.getY());
                });
    

    在任何创建的圆/点上触发鼠标标记事件。 然后,简单地用event.getX()(目标X点)和event.getY()(目标Y点)重置centerX和centerY

    我的完整代码:

    public void start(Stage stage) throws IOException 
        {    
                Label b = new Label("The coordinates are : "); 
                b.setLayoutX(190);
                b.setLayoutY(280);
                
                Label value = new Label(); 
                value.setLayoutX(320);
                value.setLayoutY(280);
                
              List<Circle> circles = new ArrayList<>();
            for(List row: list) 
            {
                Circle circle = new Circle((double) row.get(0), (double) row.get(1), 5f);
                circle.setFill(Color.BLUE);
                
                //this did the trick for me
                circle.setOnMouseDragged( event -> {
                 circle.setCenterX(event.getX());
                circle.setCenterY(event.getY());
                });
                
                //for printing the values in a Label
                 circle.setOnMouseClicked(new EventHandler<MouseEvent>() {
                        public void handle(MouseEvent event) {
                            System.out.println("Clicked");
                            value.setText(circle.getCenterX()+" , "+circle.getCenterY());
                        }
                    });
                
                circles.add(circle);
            }
           
            System.out.println(circles.size());
            Pane pane = new Pane();
    
            pane.getChildren().addAll(circles);
            pane.getChildren().add(b);
            pane.getChildren().add(value);
     Scene scene = new Scene(pane, 600, 300);  
          
          //Setting title to the Stage 
          stage.setTitle("Show Points"); 
             
          //Adding scene to the stage 
          stage.setScene(scene); 
    
          scene.getStylesheets().add(Main.class.getResource("application.css").toExternalForm());
          //Displaying the contents of the stage 
          stage.show(); 
                
        } //end of start
        
        public static void main(String[] args) throws IOException {
            launch(args);
        }
    
    
  2. # 2 楼答案

    下面是一个示例,可以通过在窗格中拖动来实现这一点。 只有两点,但你可以在列表中列出你想要的任意多点。 还有一个帮助器类可以更好、更容易地处理一个点,还有一些帮助器方法可以使代码更容易阅读

    我想把Main/fxml/Controller分开,但请随时为您获取相关信息

    文件如下:

    控制器:

    public class Controller implements Initializable {
    
        @FXML
        private Pane pane;
        @FXML
        private Label circlePos;
        @FXML
        private AnchorPane aPane;
    
        @Override
        public void initialize(URL location, ResourceBundle resources) {
    
            pane.prefWidthProperty().bind(aPane.widthProperty());
            pane.prefHeightProperty().bind(aPane.heightProperty());
    
            // Here are two circles to play around with but you can have as many as you want.
            // The center and radius are set randomly but within some borders to dont get rendered out of the visible pane.
            Circle circle = createCircle(new Point(randomBetween(5, 379), randomBetween(5, 200)), randomBetween(5, 10));
            circle.setFill(Color.BLUE);
    
            Circle circle1 = createCircle(new Point(randomBetween(5, 379), randomBetween(5, 200)), randomBetween(5, 10));
            circle1.setFill(Color.GREEN);
    
            pane.getChildren().addAll(circle, circle1);
    
        }
    
        /**
         * Creates a new Circle object with a given center and radius
         * It sets mouse events to be dragged on the pane and a label will be updated when the mouse hovers over
         * the circle
         *
         * @param center given center as Point object
         * @param radius given radius
         * @return created circle
         */
        private Circle createCircle(Point center, double radius) {
            Circle circle = new Circle(radius);
            circle.setCenterX(center.getX());
            circle.setCenterY(center.getY());
    
            // When the mouse hovers the circle sets the position label to this circle center's position
            circle.setOnMouseEntered(event -> setPosLabelText(circle));
            // When the mouse exits the circle (no more over it) resets the label to empty string.
            circle.setOnMouseExited(event -> circlePos.setText(""));
            // When a mouse drag is detected it sets the x and y coords of the circle's center to the mouse position
            // which is obtained from the event. 
            // Note: It is implemented so that the circle cannot be dragged out of the Pane, if it needed just remove
            // the if-s and set the CenterX/Y to event.getX/Y 
            circle.setOnMouseDragged(event -> {
                if (event.getX() < radius) {
                    circle.setCenterX(radius);
                } else {
                    circle.setCenterX(Math.min(event.getX(), pane.getWidth() - radius));
                }
                if (event.getY() < radius) {
                    circle.setCenterY(radius);
                } else {
                    circle.setCenterY(Math.min(event.getY(), pane.getHeight() - radius));
                }
                setPosLabelText(circle);
            });
    
            return circle;
        }
    
        /**
         * Sets the position label's text to the given circle's center coordinates.
         *
         * @param circle given circle
         */
        private void setPosLabelText(Circle circle) {
            circlePos.setText("x: " + (int) circle.getCenterX() + " y:" + (int) circle.getCenterY());
        }
    
        /**
         * Generates a random number between two integers
         *
         * @param from random number from inclusive
         * @param to   random number to exclusive
         * @return generated random number
         */
        private int randomBetween(int from, int to) {
            return new Random().nextInt(to - from) + from;
        }
    
        /**
         * Represents a 2D point
         */
        private static class Point {
    
            int x;
            int y;
    
            private Point(int x, int y) {
                this.x = x;
                this.y = y;
            }
    
            private int getX() {
                return x;
            }
    
            private int getY() {
                return y;
            }
        }
    }
    

    主要内容:

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws IOException {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
            AnchorPane anchorPane =  loader.load();
            primaryStage.setScene(new Scene(anchorPane,384,216));
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    Fxml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.Pane?>
    <?import javafx.scene.layout.VBox?>
    <AnchorPane xmlns="http://javafx.com/javafx"
                xmlns:fx="http://javafx.com/fxml"
                fx:id="aPane"
                fx:controller="drag.Controller">
        <VBox AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0">
            <Pane fx:id="pane"/>
            <Label fx:id="circlePos">
                <padding>
                    <Insets left="5" right="5"/>
                </padding>
            </Label>
        </VBox>
    </AnchorPane>
    

    希望有帮助