2016-05-21 16 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

0私は予想通りではありません

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

initGraphics()は、今のように見える `ように、私は今のパスにXとYのスケーリングファクターを追加した場合

したがって、三角形のサイズは予想どおりに拡大されましたが、(0,0)から描画されます。これは、ほぼMoveTo()オブジェクトがPathで無視されたかのようです。

Pathの作成時にスケールメソッドが呼び出される場所は関係ありません。結果は同じです。私も最初のPathElementMoveTo(0,0)として設定しようとしましたが、結果は同じです。

これらのメソッド呼び出しの仕組みを誤解していますか、それともJavaFxノードのバグですか?

答えて

1

もしノード上scaleX/scaleYを適用すると、それがセンターの上に適用される:

座標がこの{@codeのX軸に沿って物体の中心スケーリングされる因子を定義ノード}。

スケールが発生するピボットポイントは、変換されていないレイアウトの中心です(layout_layoutBoundsプロパティlayoutBounds)。 relocateとして

は、親中のx、yの位置に、このノードを再配置するために、ノードのlayoutXとlayoutY変換特性を設定します。 このメソッドは、translateXまたはtranslateYを変更しません。も設定されていれば、layoutXおよびlayoutYに追加され、対応する量で最終的な位置を調整します。あなたが言うように、あなたの最初のケースで

(太字ID鉱山)

は、パスが(70、70)に移転されますが、後者の場合には、スケールと、それです (145,145) - (150,150)=(-5)になるように、(70,70)に再配置され、中心は(145,145)にあり、そのサイズは300x300になります。 、-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

こんにちはホセ、Iあなたの答えに従ってください。あなたの説明に従っていることを懸念していることの1つは、私のスクリーンショットでは、頂点が5ピクセルで切り取られると予想していましたが、そうではありません。これを強調するために、scaleX/Yを4に設定すると、これがはっきりと示されるはずですが、そうではありません。頂点は(親の)(0,0)にあります。私は何かを誤解している。 – Kerry

+0

あなたは中心からスケーリングしているので、シーンから伸びて、0から0までの切り取ったパスが表示されます。いずれの場合も、境界ボックス( 'System.out.println(pointer.getBoundsInParent() );)、最小x、y座標を参照してください。 –

+0

私はまだJavaFXでどのようにバインドされているのかについて頭を悩ませていますが、あなたの答えは間違いなく私を助けてくれました。 – Kerry

関連する問題