2016-09-14 40 views
-1

我試圖在JavaFX中可視化一個圖。節點應該是交互式的。此刻,我有一個VBox,並將多個HBox放入其中,因爲我需要圖中的水平。所有的HBox都將把他們的孩子定位在中心位置。兒童代表單個節點並且是按鈕。 VBox本身被放置在一個StackPane中,其中一個Canvas作爲StackPane的另一個子元素。 然後將此StackPane放置到場景中。 我想使用Canvas繪製節點之間的連接邊。爲了讓我使用節點的座標:JavaFX:節點的座標錯誤沒有明顯的原因

System.out.println(button.localToScene(button.getBoundsInLocal().getMinX(), 
button.getBoundsInLocal().getMinY())); 

但無論身在何處按鈕定位,相應的座標遺體:

Point2D [x = 0.0, y = 108.0] 

所有按鈕。儘管顯示正確,但每個Button都顯然具有相同的座標!

請幫我而言,我很絕望,現在...

編輯:

這裏是工作的小例子:

Main.java

public class Main extends Application { 

@Override 
public void start(Stage primaryStage) throws Exception { 
    VBox root = new VBox(); 
    HBox buttons = new HBox(); 
    TabPane tabs = new TabPane(); 
    buttons.getChildren().addAll(
      new Button("1"), 
      new Button("2"), 
      new Button("3")); 
    tabs.getTabs().addAll(
      new TabBoxes("____A____"), 
      new TabBoxes("____B____"), 
      new TabBoxes("____C____") 
    ); 
    root.getChildren().addAll(buttons, tabs); 
    primaryStage.setScene(new Scene(root, 500, 400)); 
    primaryStage.show(); 
} 


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

TabBoxes.java

public class TabBoxes extends Tab { 
private VBox vBox = new VBox(); 
private ArrayList<HBox> hBoxes; 
private Canvas canvas = new Canvas(); 
private StackPane stack = new StackPane(); 
private static final int V_INIT_SPACING = 60; 
private static final int V_SPACING = 60; 
private static final int H_SPACING = 60; 

TabBoxes(String s){ 
    super(s); 
    this.setContent(stack); 
    setClosable(false); 
    stack.getChildren().add(canvas); 
    stack.getChildren().add(vBox); 
    canvas.setWidth(2000); 
    canvas.setHeight(1080); 
    hBoxes = new ArrayList<>(); 
    vBox.setSpacing(V_SPACING); 
    vBox.translateYProperty().set(V_INIT_SPACING); 
    for (int i = 0; i < 5; i++) { 
     hBoxes.add(new HBox() { 
      { 
       setSpacing(H_SPACING); 
       setAlignment(Pos.CENTER); 
      } 
     }); 
    } 
    for (int i = 0; i < 5; i++) { 
     for (int j = 0; j <= i; j++) { 
      hBoxes.get(i).getChildren().add(new Button(i + "||" + j){ 
       { 
        setPrefSize(100,60); 
        setOnAction(e-> System.out.println("My coordinates are: " + localToScene(getBoundsInLocal().getMinX(),getBoundsInLocal().getMinY()))); 
       } 
      }); 
     } 
    } 
    vBox.getChildren().addAll(hBoxes); 

} 
} 
+0

這應該工作,它的'StackPane'是根的場景。你可以發佈一個[mcve]讓我們重現這個問題嗎? – fabian

+1

特別是,這個代碼被調用時很重要;它需要在按鈕添加到場景和佈局後調用。 –

+0

我無法在最少的示例中重現該問題,這導致我再次檢查我的代碼。我不知道爲什麼,但顯然包括設置場景的方法調用必須在讀出座標之前完成完成(儘管在設置方法內部佈局後讀出座標)。我結束了分裂這兩件事情,現在我首先將按鈕添加到佈局,然後我調用另一種方法來更新可以正常工作的行。感謝您鼓勵我創建一個最小的例子!有時幫助很多簡化。 – FluffyPal

回答

1

boundsInLocalButton自己的座標系中的座標。這並不奇怪,這些值是相同的。
如果要計算在Canvas座標系的座標,變換座標到StackPane座標,然後變換座標到Canvas座標:

Node n = button; 
Point2D p = new Point2D(button.getBoundsInLocal().getMinX(), button.getBoundsInLocal().getMinY()); 
while (n != stackPane) { 
    p = n.localToParent(p); 
    n = n.getParent(); 
} 

p = canvas.parentToLocal(p); 
+0

對不起,我沒有複製有趣的代碼行。在使用座標之前,我還在本地座標上使用'localToScene'。所以完全它是: 'button.localToScene(button.getBoundsInLocal()。getMinX(),button.getBoundsInLocal()。getMinY())' 據我所知,你的while循環迭代通過不同的座標系統,直到達到最高水平。但'localToScene'也應該給我基於場景座標系統的座標。或者我錯過了什麼? – FluffyPal