2016-05-21 20 views
0

我在应用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; 
    } 

} 

这导致位于载通过共oridinates(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)中抽取的。这几乎就好像在Path中忽略了MoveTo()对象。

在创建路径过程中调用缩放方法的位置并不重要,结果是相同的。我也尝试将第一个PathElement设置为MoveTo(0,0),但结果是相同的。

我误解了这些方法调用是如何工作的,或者这是JavaFx节点中的错误?

回答

1

当应用scaleX/scaleY过的节点,它被施加在它的中心:

定义由该坐标被缩放关于对象沿着该{@code的X轴中心的因子节点}。

出现比例的枢轴点是未转换的{@link #layoutBoundsProperty layoutBounds}的中心。

至于relocate

设置,以这个节点搬迁到x,y位置在父节点的layoutX和layoutY翻译性能。 此方法不会更改translateX或translateY,如果同时设置,则会将其添加到layoutX和layoutY,并将最终位置调整为相应的数量。

(粗体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)缩放,利用其左上顶点作为支点,并使用Scale变换:

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

+0

嗨何塞,我有点跟随你的答案,但有一件事让我担心,在你的解释之后,在我的屏幕截图中,我预计顶点已被5个像素剪辑,但事实并非如此。要强调这一点,将scaleX/Y设置为4应清楚地表明这一点,但事实并非如此。最高顶点位于(0,0)(父级)。我误解了一些东西。 – Kerry

+0

由于您是从中心缩放,它将长出场景,并且您将看到从0,0裁剪的路径。无论如何,请检查边框('System.out.println(pointer.getBoundsInParent() );')并查看最小的x,y坐标。 –

+0

好的,我仍然对JavaFX的工作方式感到满意,但你的答案肯定对我有帮助。 – Kerry

相关问题