JavaFX: getWidth () и getLayoutBounds () возвращают 0 - PullRequest
0 голосов
/ 15 мая 2018

enter image description here

Привет, ребята, Я разрабатываю простой редактор для создания некоторых сценариев использования с использованием JavaFX. Теперь, когда я хочу соединить два узла друг с другом, я бы хотел дать этой ссылке имя. В настоящее время идея состоит в том, чтобы поместить метку в anchorPane и центрировать эту панель в середине ссылки. Проблема в том, что ни функция getWidth (), ни функция getLayoutBounds () не возвращают правильных результатов, но 0 во всех случаях. Как я могу определить ширину этой anchorPane? Спасибо за все ответы!

// Java-код

public class Link extends AnchorPane{

    public Link() {
        FXMLLoader fxmlLoader = new FXMLLoader(
            getClass().getResource("../view/Link.fxml")
        );

        fxmlLoader.setRoot(this); 
        fxmlLoader.setController(this);

        try { 
            fxmlLoader.load();

        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public void bindAnchorPane(DraggableNode source, DraggableNode target){
        //Middlepoint X source and target node
        NumberBinding middleX = Bindings.add(Bindings.divide(source.layoutXProperty(), 2), Bindings.add(Bindings.divide(target.layoutXProperty(), 2), source.getWidth() / 2.0));
        //Middlepoint Y source and target node
        NumberBinding middleY = Bindings.add(Bindings.divide(source.layoutYProperty(), 2), Bindings.add(Bindings.divide(target.layoutYProperty(), 2), source.getWidth() / 2.0));

        //X position of the anchorPane
        //Middlepoint X - anchor.getWidth()/2
        NumberBinding coordX = Bindings.subtract(middleX, anchor_link_label.getWidth()/2;
//        Bounds bounds = anchor_link_label.getLayoutBounds();
//        NumberBinding coordX = Bindings.subtract(middleX, (bounds.getMaxX() - bounds.getMinX()));

        anchor_link_label.layoutXProperty().bind(coordX);
        anchor_link_label.layoutYProperty().bind(middleY);

    }
}

// файл FXML

<fx:root stylesheets="@application.css" type="Pane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
       <children>
            <CubicCurve fx:id="node_link" controlX2="50.0" controlY1="10.0" controlY2="10.0" endX="10.0" fill="#1f93ff00" stroke="BLACK" />
            <AnchorPane fx:id="anchor_link_label" managed="false">
                <Label fx:id="label_link" text="" onMouseClicked="#showTextField" visible="false" managed="false"/>
                <TextField fx:id="textField_link" minWidth="100" visible="true" managed="true"/>
            </AnchorPane>
       </children>
    </fx:root>

1 Ответ

0 голосов
/ 15 мая 2018

В то время, когда этот код запускает высоту и ширину равны нулю, так как я предполагаю, что узел еще не был размечен.

, если вы хотите middleXПривязки, middleY и coordX для обновления с текущей шириной / высотой, тогда вам нужно привязать их к свойствам / привязкам ширины к высоте, а не только к ширине / высоте при одном вызове, который вы делаете "source.getWidth() / 2.0", когдаэто ноль.

Попробуйте это:

// Middlepoint X source and target node
NumberBinding middleX = source.layoutXProperty().divide(2)
        .add(target.layoutXProperty().divide(2).add(source.widthProperty().divide(2)));

// Middlepoint Y source and target node
NumberBinding middleY = source.layoutYProperty().divide(2)
        .add(target.layoutYProperty().divide(2).add(source.heightProperty().divide(2)));

// X position of the anchorPane
// Middlepoint X - anchor.getWidth()/2
NumberBinding coordX = middleX.subtract(anchor_link_label.widthProperty().divide(2));

// anchor_link_label.layoutXProperty().bind(coordX);
// anchor_link_label.layoutYProperty().bind(middleY);

// To avoid binding and getting a "bound value cannot be set" error
// you can just use listeners instead.

// However, this is slightly hackish, since you are re-laying-out this child 
// after the parent tries to lay it out already.
// What you probably should do is define a parent that overrides 
// `layoutChildren()` and determines how to layout this node.

// Here are the listeners:
coordX.addListener((obs, oldVal, newVal) -> {
    anchor_link_label
        .setLayoutX(
            newVal.doubleValue() - anchor_link_label.getLayoutBounds().getMinX());
    });

middleY.addListener((obs, oldVal, newVal) -> {
    anchor_link_label
        .setLayoutY(
             newVal.doubleValue() - anchor_link_label.getLayoutBounds().getMinY());
    });

Возможной альтернативой будет использование HBox в качестве родителя и установка выравнивания по центру, а не использование универсального Pane так как кажется, что все, что вам действительно нужно, это поместить ярлык в центр панели.

...