我需要使用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) { if (bluePrintView.getScaleX() > 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(); }
创建圆并执行一些操作的代码:
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<MouseEvent>() { @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<MouseEvent>() { @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<ScrollEvent>() { @Override public void handle(ScrollEvent t) { if (t.getDeltaY() < 0) { if (node.getScaleX() > 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文件代码:
<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.image.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" fx:id="rootPane" pickOnBounds="true" prefHeight="420.0" prefWidth="817.0" snapToPixel="true" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="blueprints.NewSonarViewController"> <children> <Group id="Group" layoutX="0.0" layoutY="0.0"> <children> <ScrollPane fx:id="scrollPaneImage" layoutX="0.0" layoutY="0.0" prefHeight="420.0" prefWidth="817.0"> <content> <Group id="Group" fx:id="rootGroup"> <children> <ImageView fx:id="bluePrintView" cache="false" fitHeight="419.0" fitWidth="816.0" layoutX="0.0" layoutY="0.0" onMouseClicked="#zoomResetAction" onScroll="#zoomAction" pickOnBounds="true" preserveRatio="false" rotate="0.0" visible="true" /> </children> </Group> </content> <contextMenu> <ContextMenu> <items> <MenuItem mnemonicParsing="false" onAction="#loadBtnAction" text="Load Image" /> <MenuItem mnemonicParsing="false" onAction="#addSynk" text="Add Synk" /> <MenuItem mnemonicParsing="false" onAction="#addNode" text="AddNode" /> </items> </ContextMenu> </contextMenu> </ScrollPane> </children> </Group> </children> </AnchorPane>
我的想法是,将ImageView和和添加Circle到中rootGroup,然后在上应用比例rootGroup。请参阅下面的示例。
ImageView
Circle
rootGroup
风景:
<AnchorPane id="AnchorPane" fx:id="rootPane" pickOnBounds="true" prefHeight="420.0" prefWidth="817.0" snapToPixel="true" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="javafx.scale.Controller"> <children> <Group id="Group" layoutX="0.0" layoutY="0.0" onScroll="#scrolling"> <children> <ScrollPane fx:id="scrollPaneImage" layoutX="0.0" layoutY="0.0" prefHeight="420.0" prefWidth="817.0"> <content> <Group id="Group" fx:id="rootGroup"> </Group> </content> </ScrollPane> </children> </Group> </children> </AnchorPane>
控制器:
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); } }