2016-09-14 1 views
-1

Я пытаюсь визуализировать график в JavaFX. Узлы должны быть интерактивными. На данный момент у меня есть VBox и помещаю в него столько HBoxes, сколько мне нужно в графе. Все HBoxes настроены таким образом, чтобы их дочерние элементы были центрированы. Дети представляют собой отдельные узлы и являются кнопками. Сам VBox помещается в StackPane с холстом в качестве еще одного дочернего элемента StackPane. Эта StackPane затем помещается в Сцена. Я хочу использовать холст, чтобы нарисовать соединительные края между узлами. Чтобы получить координаты узлов я использую:JavaFX: Координаты узлов неверны по какой-либо очевидной причине

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

Но независимо от того, где кнопка расположена, получившейся координаты остается:

Point2D [x = 0.0, y = 108.0] 

для всех кнопок. Каждая кнопка имеет, по-видимому, одну и ту же координату, хотя она отображается правильно!

Пожалуйста, помогите мне, им совсем отчаянным прямо сейчас ...

Edit:

Вот минимальный пример, который работает:

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

boundsInLocal координаты в собственной системе координат Button «s. Неудивительно, что эти значения одинаковы.
Если вы хотите, чтобы вычислить координаты в 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-loop выполняет итерацию через другую координату до тех пор, пока он не достигнет верхнего уровня. Но 'localToScene' также должен дать мне координаты, основанные на системе координат сцены. Или мне что-то не хватает? – FluffyPal