javajavafx

How to connect two vertical line nodes in two TextFlows in JavaFX?


This is my code:

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        var textFlow1 = createTextFlow();
        textFlow1.setStyle("-fx-background-color: cyan");
        var textFlow2 = createTextFlow();
        textFlow2.setStyle("-fx-background-color: yellow");

        VBox vbox = new VBox(textFlow1, textFlow2);
        Scene scene = new Scene(vbox, 300, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TextFlow createTextFlow() {
        Text textA = new Text("ABC");
        textA.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
        Line line = new Line(0, 0, 0, 20);
        Text textB = new Text("DEF");
        textB.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
        TextFlow textFlow = new TextFlow(textA, line, textB);
        return textFlow;
    }

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

and this is the result:

enter image description here

As you see, I have two TextFlows and each of them has a line node. I need that these two lines look like one line, by other words there mustn't be a space between them (now I have about 4px gap)

Could anyone say how to connect these lines (how to make them look line one line)?


Solution

  • Your question probably needs more context and explanation. (E.g. why do you want to do this? Why are you choosing 20 as the height of the line?) Without that, it is hard to know whether this solution will generalize from the example you posted to whatever the real problem is that you are trying to solve.

    That said, the following will achieve what you specifically asked. The idea is to not let the TextFlow manage the positioning of the Line, or the Line to affect the size calculation of the TextFlow, by setting managed to false. Then override TextFlow.layoutChildren() to manually position the line. You need startY to be 0, always, endY to be the height of the text flow, and both startX and endX to be (in this specific example) to be the x location of the second Text element.

        private TextFlow createTextFlow() {
            Text textA = new Text("ABC");
            textA.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
            Line line = new Line();
            line.setManaged(false);
            Text textB = new Text("DEF");
            textB.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
            TextFlow textFlow = new TextFlow(textA, line, textB) {
                @Override
                protected void layoutChildren() {
                    super.layoutChildren();
                    double x = textB.getBoundsInParent().getMinX();
                    line.setStartX(x);
                    line.setEndX(x);
                    line.setEndY(getHeight());
                }
            };
            return textFlow;
        }
    

    enter image description here