Как получить внешние границы узла в JavaFX - PullRequest
1 голос
/ 10 июля 2019

Я пытаюсь вручную выровнять узлы на панели JavaFX, но не могу получить реальные внешние границы узлов.

Я не знаю, как лучше объяснить проблему, чем показывать следующий пример, который я создал для ее демонстрации:

Screenshot of the result of the code below

Это окно генерируется следующим кодом:

public class JavaFXMWE extends Application {
    private Pane root;

    @Override
    public void start(Stage primaryStage) {
        root = new Pane();

        normal();
        bold();
        inStackPane();
        inStackPaneWithInsets();

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("MWE");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void normal() {
        Text text1 = new Text("Some Text");
        Text text2 = new Text("Some other Text");

        text1.relocate(20, 20);
        text2.relocate(text1.getBoundsInParent().getMaxX(), 20);

        root.getChildren().addAll(text1, text2);
    }

    private void bold() {
        Text text1 = new Text("Some Text");
        Text text2 = new Text("Some other Text");
        text1.setStyle("-fx-font-weight: bold");
        text2.setStyle("-fx-font-weight: bold");

        text1.relocate(20, 40);
        text2.relocate(text1.getBoundsInParent().getMaxX(), 40);

        root.getChildren().addAll(text1, text2);
    }

    private void inStackPane() {
        Text text1 = new Text("Some Text");
        Text text2 = new Text("Some other Text");
        StackPane pane1 = new StackPane(text1);
        StackPane pane2 = new StackPane(text2);
        setBorder(pane1);
        setBorder(pane2);

        pane1.relocate(20, 60);
        pane2.relocate(pane1.getBoundsInParent().getMaxX(), 60);

        root.getChildren().addAll(pane1, pane2);
    }

    private void inStackPaneWithInsets() {
        Text text1 = new Text("Some Text");
        Text text2 = new Text("Some other Text");
        StackPane pane1 = new StackPane(text1);
        StackPane pane2 = new StackPane(text2);
        setBorderAndInsets(pane1);
        setBorderAndInsets(pane2);

        pane1.relocate(20, 85);
        pane2.relocate(pane1.getBoundsInParent().getMaxX(), 85);

        root.getChildren().addAll(pane1, pane2);
    }

    private static void setBorder(Region node) {
        node.setBorder(new Border(new BorderStroke(Color.BLACK, 
            BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
    }

    private static void setBorderAndInsets(Region node) {
        setBorder(node);
        node.setPadding(new Insets(5));
    }


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Как получить фактические внешние границы узлов?

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

Стиль CSS применяется непосредственно перед первым проходом макета. Свойство style не влияет на узел, пока это не произойдет. По этой причине лучше позиционировать детей, переопределив метод layoutChildren; этот метод вызывается во время прохода макета. Или вы можете добавить слушателя к свойству boundsInParent.

@Override
public void start(Stage primaryStage) throws Exception {
    Text text1 = new Text("Some Text");
    Text text2 = new Text("Some other Text");
    text1.setStyle("-fx-font-weight: bold");
    text2.setStyle("-fx-font-weight: bold");

    Pane root = new Pane(text1, text2) {

        @Override
        protected void layoutChildren() {
            text1.relocate(20, 40);
            text2.relocate(text1.getLayoutX() + text1.prefWidth(-1), 40); // using text1.boundsInParent would work too, usually the size constraints returned by the minWidth, prefWidth and maxWidth methods should be used
        }

    };

    Scene scene = new Scene(root, 300, 300);
    primaryStage.setScene(scene);
    primaryStage.show();
}
0 голосов
/ 10 июля 2019

Вы должны попытаться получить границы после primaryStage.show().

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {

    @Override
    public void start(Stage primaryStage) {
        Text text1 = new Text("Some Text");
        text1.relocate(10, 10);


        Pane root = new Pane(text1);

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);

        primaryStage.show();

        double midpoint = text1.getBoundsInParent().getWidth() / 2;
        text1.relocate(300 / 2 - midpoint, 10);
    }

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

}

enter image description here

...