2016-01-20 41 views
1

我想知道是否有可能有選擇地將父變換應用於javafx中的子節點。Javafx中的選擇性子變換

據我的理解,當一個節點被轉換時,所述節點的所有子節點也被轉換。

我的問題是:是否有可能禁用父級變換的子類型,以便當父變換時只傳遞一個選擇類型的變換。

與此類似: enter image description here

我想不旋轉文本旋轉組節點,但我想文本位置通過旋轉來實現。

希望我已經解釋了我自己。


目前我僅是相反的旋轉應用於文本當組轉化,但它得到的地步,我不斷擴大的場景圖使得這一更加複雜。

回答

2

總之,否:組的變換總是傳播給它的所有孩子。

不過,我覺得在這裏你只是想文本的旋轉屬性是該組的旋轉特性的負:

text.rotateProperty().bind(group.rotateProperty().multiply(-1)); 

由於rotateProperty定義有關節點的中心旋轉,當該組旋轉時,它(及其所有子節點)將圍繞其中心旋轉,然後該綁定確保文本以相反方向圍繞其中心旋轉。

如果你想要更一般的東西,它會變得有點棘手。一種可能的方法是觀察想要保持水平的文本的父親的localToSceneTransform。該屬性表示將父級中的座標映射到場景中的座標的累積變換。然後,您可以在父級的本地座標空間中取一條水平線,將其轉換爲場景,並查看其創建的角度。然後你想旋轉這個角度的否定文本。

這裏有一個演示:

import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.geometry.Point2D; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.Spinner; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.text.Text; 
import javafx.stage.Stage; 

public class RotateGroupKeepTextAligned extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     BorderPane root = new BorderPane(); 
     StackPane container = new StackPane(); 
     Group outer = new Group(); 
     Rectangle outerRect = new Rectangle(0, 0, 400, 400); 
     outerRect.setFill(Color.ANTIQUEWHITE); 
     outer.getChildren().add(outerRect); 

     Text outerText = new Text(5, 5, "Outer Group"); 
     Group inner = new Group(); 
     inner.relocate(10, 25); 
     Text innerText = new Text(5, 5, "Inner Group"); 
     Rectangle rect = new Rectangle(50, 50, 150, 150); 
     rect.setFill(Color.CORNFLOWERBLUE); 
     Text fixedAlignmentText = new Text(100, 220, "Horizontal Text"); 

     inner.localToSceneTransformProperty().addListener((obs, oldT, newT) -> { 
      // figure overall rotation angle of inner: 
      Point2D leftScene = newT.transform(new Point2D(0, 0)); 
      Point2D rightScene = newT.transform(new Point2D(1, 0)); 

      double angle = Math.toDegrees(Math.atan2(rightScene.getY() - leftScene.getY(), rightScene.getX() - leftScene.getX())); 

      fixedAlignmentText.setRotate(-angle); 
     }); 

     outer.setStyle("-fx-background-color: antiquewhite;"); 
     outer.getChildren().addAll(outerText, inner); 

     inner.setStyle("-fx-background-color: white;"); 
     inner.getChildren().addAll(innerText, rect, fixedAlignmentText); 

     container.getChildren().add(outer); 
     root.setCenter(container); 

     VBox controls = new VBox(5, 
       makeControls("Outer Group", outer), 
       makeControls("Inner Group", inner)); 

     root.setBottom(controls); 

     Scene scene = new Scene(root, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private Node makeControls(String title, Node node) { 
     GridPane grid = new GridPane(); 

     Label label = new Label(title); 
     Spinner<Double> rotateSpinner = new Spinner<>(0, 360, 0, 5); 
     node.rotateProperty().bind(rotateSpinner.getValueFactory().valueProperty()); 
     rotateSpinner.getValueFactory().setWrapAround(true); 

     Button up = createTranslateButton(node, Node::translateYProperty, -2, "^"); 
     Button down = createTranslateButton(node, Node::translateYProperty, 2, "v"); 
     Button left = createTranslateButton(node, Node::translateXProperty, -2, "<"); 
     Button right = createTranslateButton(node, Node::translateXProperty, 2, ">"); 

     grid.add(label, 0, 0, 3, 1); 
     grid.add(new Label("Rotation:"), 0, 1, 1 ,2); 
     grid.add(rotateSpinner, 1, 1, 1, 2); 
     grid.add(up, 3, 1); 
     grid.add(down, 3, 2); 
     grid.add(left, 2, 1, 1, 2); 
     grid.add(right, 4, 1, 1, 2); 

     grid.setHgap(5); 
     grid.setVgap(5); 

     return grid ; 
    } 

    private Button createTranslateButton(Node node, Function<Node, DoubleProperty> property, double delta, String text) { 
     Button button = new Button(text); 
     button.setOnAction(e -> { 
      DoubleProperty prop = property.apply(node); 
      prop.set(prop.get() + delta); 
     }); 
     return button ; 
    } 

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

請問即使旋轉應用到組的根這項工作? – jogden16761

+0

不,在這種情況下,你需要'text.rotateProperty()。bind(root.rotateProperrty()...);'一般化會很困難,只是爲了從幾何角度定義你的意思。 –

+0

啊謝謝你。看起來問題比我想象的要大得多。 我只是試圖讓我的場景圖中的文本不會旋轉,而場景圖中的其他內容卻不會旋轉。現在,隨着我的場景圖變得越來越大,我試圖推廣,但看起來我只需要聲明每個文本節點。 – jogden16761