我需要使用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
。请参阅下面的示例。
风景:
<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);
}
}
问题内容: 关于它们有很多传说。我想知道真相。以下两个示例之间有什么区别? 问题答案: 不确定从何处获得传说,但: 提交按钮 与: IE6将在标记之间提交此按钮的所有文本,其他浏览器将仅提交值。使用可使您在按钮的设计上享有更大的布局自由度。从各种意图和目的看,它乍一看似乎很棒,但是各种浏览器怪癖使它有时很难使用。 在您的示例中,IE6将发送到服务器,而其他大多数浏览器将不发送任何内容。要使其跨浏览
什么区别以及如何正确重写代码?
我试图理解为什么下面两个代码块会产生不同的结果。 代码块1按预期工作,并返回从数据库中查找的提供程序的数组。另一方面,代码块2返回函数数组。在理解promissione.all()和async/await时,我觉得缺少了一些简单的东西。 代码块的差异如下: > 块1:创建许诺函数数组,然后使用map运算符将其包装在异步函数中。 块2:许诺函数的数组被创建为异步函数。因此,不调用map运算符。 如果
问题内容: 我才刚刚开始研究SQL。 我有一个SQL Server 2008r2数据库,它将返回两个字段DocDate和InvValue。我需要将InvValues汇总为今天的MTD和YTD,所以看起来像 我已经做了大量的Google搜寻,并且可以使用SUM&DATEPART进行一项或多项,但是我坚持尝试两者兼而有之。 有人可以给我一些伪代码,以帮助我进一步谷歌。 谢谢@戈登·利诺夫(Gordon
这个示例代码来自一本Java书籍,从墙上的99瓶啤酒到没有啤酒打印出这首歌。问题是,当墙上是1瓶啤酒时,它仍然写着瓶子。我试图通过在末尾添加部分来解决这个问题。但是,它仍然显示1瓶啤酒在墙上,我瓶啤酒在墙上。 我不知道该改变什么来解决这个问题。是否创建另一个while部分? 如果你能给他们一个提示,这样我就可以自己解决它,那也很酷!因为我知道我的实际歌曲输出是在第一个if部分,但我不知道我应该在哪
原文地址:https://cesiumjs.org/tutorials/cesium-and-webpack/ Cesium 和 Webpack Webpack是非常强大非常流行的JavaScript 模块打包工具。它可以让开发人员以一种简单直观的 require 方式去加载各种页面需要的文件,极大的方便了开源人员对代码和资源文件进行结构化设计。当编译的时候,它会跟踪代码依赖性,把所有的模型打包到