java - 应用比例时不支持路径转换

标签 java javafx javafx-8

我在将平移和缩放应用于 JavaFx Path node 时遇到一些问题。我发现每当通过调用 setScaleX() 来应用比例时或scaleY()然后通过调用 relocate() 应用任何翻译不再受到尊重。

例如,使用这个主类:

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class MainApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {

        StackPane myPane = new StackPane(new MyRegion());
        Scene myScene = new Scene(myPane);
        stage.setScene(myScene);
        stage.setWidth(500);
        stage.setHeight(500);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

以及 MyRegion 类:

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;

public class MyRegion extends Region{

    private Path pointer;
    private ObjectProperty<Color> pointerColour = 
        new SimpleObjectProperty<>(Color.ORANGE);

    public MyRegion() {
        initGraphics();
    }

    private void initGraphics(){
        pointer = new Path();
        pointer.setFill(pointerColour.get());
        pointer.setStrokeWidth(0);
        pointer.getElements().add(new MoveTo(50, 50));
        pointer.getElements().add(new LineTo(50, 200));
        pointer.getElements().add(new LineTo(200, 200));
        pointer.getElements().add(new ClosePath());
        pointer.relocate(70, 70);
    }

    @Override
    protected void layoutChildren() {
        getChildren().removeAll(pointer);
        getChildren().addAll(pointer);
    }

    @Override
    protected double computePrefHeight(double width) {
        return 200;
    }

    @Override
    protected double computePrefWidth(double height) {
        return 200;
    }

}

这会产生一个位于坐标 (70,70) 处的三角形,由方法 initGraphics() 中的 pointer.relocate(70, 70) 行设置:

Working example

如果我现在向路径添加 X 和 Y 缩放因子,则 `initGraphics() 现在看起来像:

private void initGraphics(){
    pointer = new Path();
    pointer.setFill(pointerColour.get());
    pointer.setStrokeWidth(0);
    pointer.getElements().add(new MoveTo(50, 50));
    pointer.getElements().add(new LineTo(50, 200));
    pointer.getElements().add(new LineTo(200, 200));
    pointer.getElements().add(new ClosePath());
    pointer.relocate(70, 70);
    pointer.setScaleX(2);
    pointer.setScaleY(2);
}

结果如下,不符合我的预期:

enter image description here

因此三角形的大小已按预期缩放,但它是从 (0,0) 绘制的。这几乎就像 MoveTo() 对象在 Path 中被忽略一样。

在创建 Path 的过程中,无论在哪里调用缩放方法,结果都是一样的。我还尝试将第一个 PathElement 设置为 MoveTo(0,0) 但结果是相同的。

我是否误解了这些方法调用的工作原理,或者这是 JavaFx Node 中的错误?

最佳答案

当您在节点上应用 scaleX/scaleY 时,它会应用于其中心:

Defines the factor by which coordinates are scaled about the center of the object along the X axis of this {@code Node}.

The pivot point about which the scale occurs is the center of the untransformed {@link #layoutBoundsProperty layoutBounds}.

至于搬迁:

Sets the node's layoutX and layoutY translation properties in order to relocate this node to the x,y location in the parent. This method does not alter translateX or translateY, which if also set will be added to layoutX and layoutY, adjusting the final location by corresponding amounts.

(粗体ID是我的)

在第一种情况下,正如您所说,路径将被重新定位到 (70, 70),但在第二种情况下,随着比例,它重新定位到 (70, 70) ,中心位于 (145, 145),大小为 300x300,这意味着左上角顶点位于 (145, 145) - (150, 150) = (-5, -5)。

这是边界框的结果:

System.out.println(pointer.getBoundsInParent());

>> BoundingBox [minX:-5.5, minY:-5.5, minZ:0.0, width:302.0, height:302.0, depth:0.0, maxX:296.5, maxY:296.5, maxZ:0.0]

(它为路径的描边添加 1 像素)。

所以它正在做它应该做的事情。

如果您希望路径从 (70, 70) 缩放,请将其左上角顶点作为枢轴,并使用缩放变换:

private void initGraphics(){
    pointer = new Path();
    pointer.setFill(pointerColour.get());
    pointer.setStrokeWidth(0);
    pointer.getElements().add(new MoveTo(50, 50));
    pointer.getElements().add(new LineTo(50, 200));
    pointer.getElements().add(new LineTo(200, 200));
    pointer.getElements().add(new ClosePath());
    pointer.relocate(70, 70);
    pointer.getTransforms().add(new Scale(2, 2, 50, 50));
}

scaling

关于java - 应用比例时不支持路径转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37364570/

相关文章:

javafx - FXML 设置 ButtonType onAction

java - 从轴中删除负值

java - 当我在 JavaFX 中拖动鼠标时,圆圈不可见

java - 来自 Java 的 CPU 负载

java - 我们如何从可编辑的Java代码在IntelliJ IDEA中生成流程图?

java - 在 Spring Boot 中将 jsessonid cookie 设置为 SameSite=Strict 属性?

java - 将数据填充到 Excel 时超链接不起作用

JavaFX 如何使 GridPane 适合 ScrollPane 父级?

java - 使用 CSS 在 tabpane 中居中选项卡

css - 更改 TextField 中插入符号的大小 (JavaFX 8)