JavaFX Circle和ImageView

我需要使用javaFX2来执行以下操作:

1-)加载图像并使用imageView显示。 [好]

2-)右键单击并选择“添加节点”选项,屏幕上将出现一个黑色圆圈,您可以将圆圈拖动到图像的任何位置。 [好]

3-)使用鼠标滚轮向上或向下缩放imageView,在图像上显示“Zoom Sensation”。 [好]

3.1-) 然而,每次我缩放图像时,我希望我的圆圈遵循比例比例,这意味着它们不能保持在屏幕的相同位置。 [不知道]

我的问题是项目编号3.1,因为我不知道如何在图像中移动我的圆圈,使其在我向上或向下缩放后看起来像是在图像的位置。 我尝试使用setCenterX()和setCenterY()方法,以及转换方法,但我找不到这样做的方法。

加载我的图片的代码:

@FXML ImageView bluePrintView; @FXML private void loadBtnAction(ActionEvent event) { FileChooser fileChooser = new FileChooser(); //Show open file dialog File file = fileChooser.showOpenDialog(null); /*Load Image*/ System.out.println(file.getPath()); Image img = new Image("file:" + file.getPath()); bluePrintView.setImage(img); bluePrintView.setFitHeight(scrollPaneImage.getHeight()); bluePrintView.setFitWidth(scrollPaneImage.getWidth()); bluePrintView.setSmooth(true); bluePrintView.setScaleX(1); bluePrintView.setScaleY(1); event.consume(); } 

缩放ImageView的代码:

 @FXML private void zoomAction(ScrollEvent event) { if (event.getDeltaY()  0.8 && bluePrintView.getScaleY() > 0.8) { bluePrintView.setScaleX(bluePrintView.getScaleX() - 0.1); bluePrintView.setScaleY(bluePrintView.getScaleY() - 0.1); System.out.println("ImageView(X,Y): "+bluePrintView.getFitHeight()+" "+bluePrintView.getFitWidth()); System.out.println("Image(X,Y): "+bluePrintView.getImage().getHeight()+" "+bluePrintView.getImage().getWidth()); if (!nodeList.isEmpty()) { for (int i = 0; i < nodeList.size(); i++) { nodeList.get(i).zoomOutNode(bluePrintView.getFitHeight(),bluePrintView.getFitWidth()); } } } } else { bluePrintView.setScaleX(bluePrintView.getScaleX() + 0.1); bluePrintView.setScaleY(bluePrintView.getScaleY() + 0.1); System.out.println("ImageView(X,Y): "+bluePrintView.getFitHeight()+" "+bluePrintView.getFitWidth()); System.out.println("Image(X,Y): "+bluePrintView.getImage().getHeight()+" "+bluePrintView.getImage().getWidth()); if (!nodeList.isEmpty()) { for (int i = 0; i < nodeList.size(); i++) { nodeList.get(i).zoomInNode(bluePrintView.getFitHeight(),bluePrintView.getFitWidth()); } } } event.consume(); } 

创建Circle的代码并执行一些操作:

 public class NodeShape { final Circle node = new Circle(); double axisX = 0, axisY = 0; public Circle createNode(Group rootGroup, double axisX, double axisY, double radius, String color) { node.setCenterX(axisX); node.setCenterY(axisY); node.setRadius(radius); node.fillProperty().setValue(Paint.valueOf(color)); System.out.println(node.getTranslateX() + " " + node.getTranslateY()); System.out.println("getCenter: " + node.getCenterX() + " " + node.getCenterY()); rootGroup.getChildren().add(node); node.setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent t) { node.setCenterX(t.getX()); node.setCenterY(t.getY()); NodeShape.this.axisX = t.getX(); NodeShape.this.axisY = t.getY(); System.out.println("Circle getTranslate: " + node.getTranslateX() + " " + node.getTranslateY()); System.out.println("Circle getCenter: " + node.getCenterX() + " " + node.getCenterY()); t.consume(); } }); node.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent t) { if (t.getButton().equals(MouseButton.PRIMARY)) { if (t.getClickCount() == 2) { node.setVisible(false); node.setDisable(true); }else if(t.getClickCount() == 1){ System.out.println("Circle Position: "+node.getCenterX()+" "+node.getCenterY()); } } t.consume(); } }); node.setOnScroll(new EventHandler() { @Override public void handle(ScrollEvent t) { if (t.getDeltaY()  0.8 && node.getScaleY() > 0.8) { node.setScaleX(node.getScaleX() - 0.1); node.setScaleY(node.getScaleY() - 0.1); } } else { node.setScaleX(node.getScaleX() + 0.1); node.setScaleY(node.getScaleY() + 0.1); } t.consume(); } }); return node; } public void zoomInNode(double imgHeight, double imgWidth) { node.setCenterX(0.1); //node.setTranslateY(imgHeight/1100 + 10); //node.setCenterX(node.getCenterX() + Math.abs(axisX - node.getRadius())); //node.setCenterY(node.getCenterY() + Math.abs(axisY - node.getRadius())); System.out.println("Circle getCenter: " + node.getCenterX() + " " + node.getCenterY()); System.out.println("Circle getCenter: " + node.getTranslateX()+ " " + node.getTranslateY()); } public void zoomOutNode(double imgHeight, double imgWidth) { node.setCenterX(-0.1); // node.setTranslateY(imgHeight/200 - 10); //node.setCenterX(node.getCenterX() - Math.abs(axisX - node.getRadius())); //node.setCenterY(node.getCenterY() - Math.abs(axisY - node.getRadius())); System.out.println("Circle getCenter: " + node.getCenterX() + " " + node.getCenterY()); System.out.println("Circle getCenter: " + node.getTranslateX()+ " " + node.getTranslateY()); } public void zoomResetNode() { node.setCenterX(axisX); node.setCenterY(axisY); }} 

我的FXML文件代码:

                                  

我的想法是将ImageViewCircle添加到rootGroup ,然后在rootGroup上应用缩放。 请参阅下面的示例。

风景:

               

控制器:

 public class Controller { @FXML private Group rootGroup; private Group zoomGroup; private double scale = 1; public void initialize() { zoomGroup = new Group(); Image image = new Image(getClass().getResourceAsStream("image.jpg")); ImageView imageView = new ImageView(image); imageView.setX(50); imageView.setY(50); Circle circle = new Circle(); circle.setRadius(20); circle.setCenterX(100); circle.setCenterY(200); circle.setFill(Paint.valueOf("RED")); zoomGroup.getChildren().add(imageView); zoomGroup.getChildren().add(circle); rootGroup.getChildren().add(zoomGroup); } public void scrolling(ScrollEvent scrollEvent) { if (scrollEvent.getDeltaY() > 0) { scale += 0.1; } else if (scrollEvent.getDeltaY() < 0) { scale -= 0.1; } zoomGroup.setScaleX(scale); zoomGroup.setScaleY(scale); } } 

好吧,如果我理解你的问题正确,这个解决方法应该解决你的问题:

想象一下,你有一个宽度和高度为100 * 200的图像。

你在(10,10)位置的图像上有圆圈。

重新缩放图像后,图像的新宽度和高度将变为150 * 300。

要计算圆的新位置,只需执行以下操作:

 newCircleX = (currentCircleX * currentImageWidth) / oldImageWidth; newCircleY = (currentCircleY * currentImageHeight) / oldImageHeight; 

希望这有帮助。