首页 > 解决方案 > Splitpane JavaFX:两个窗格上相同级别的文本呈现

问题描述

我正在构建一个语音到文本的应用程序。我正在使用拆分窗格来显示它。左窗格显示动态变化的语音到文本信息。右侧窗格显示在同一级别左侧窗格中说出的每个句子的“是/否”固定文本。

为了确保“是/否”出现在与左窗格上的句子完全相同的级别,我将左右窗格上的文本添加到各自的 Hboxes(Splitpane_left_hbox(Speech to text sentence) 和 Splitpane_right_hbox (“Yes/否") ) 每当说出一个新句子时。

左右框分别放在left_Vbox和right_vbox中,用于语音到文本句子的垂直渲染。

我正在测量 Splitpane_left_hbox 的高度(包含文本句子的可变宽度语音)以将相同的高度分配给右侧的 Hbox。这样当一个新句子出现时,Splitpane_left_hbox 和 Splitpane_right_hbox 上的文本都会出现在新行的同一级别。

问题:

  1. 即使其中有文本,Splitpane_left_hbox.getHeight() 也会返回 0.0。
  2. 这可以防止我为 Splitpane_left_hbox 设置一个值以将它们定位在同一级别。

问题:

  1. 添加语音到文本文本后,如何获得 Splitpane_left_hbox 的最终高度?

  2. 有没有更有效的方法可以使这些文本在两个窗格中显示在同一级别?

FXML 文件:

<SplitPane fx:id="split_pane" dividerPositions="0.49613899613899615" prefHeight="497.0" prefWidth="1040.0">
     <items>
        <ScrollPane prefViewportHeight="341.0" prefViewportWidth="512.0">
           <content>
              <VBox fx:id="split_pane_1_Vbox" prefHeight="494.0" prefWidth="513.0">
                 <children>
                    <HBox fx:id="split_pane_1_hbox" fillHeight="false">
                       <children>
                          <Text fx:id="text_1" />
                       </children>
                    </HBox>
                 </children>
              </VBox>
           </content>
        </ScrollPane>
        <ScrollPane prefViewportHeight="341.0" prefViewportWidth="520.0">
           <content>
              <VBox fx:id="split_pane_2_Vbox" prefHeight="496.0" prefWidth="523.0">
                 <children>
                    <HBox fx:id="split_pane_2_hbox" prefHeight="300.0" prefWidth="200.0" />
                    <children>
                       <Text fx:id="text_2" />
                   </children>
              </VBox>
           </content>
        </ScrollPane>
     </items>
  </SplitPane>

Java方法:

void addFinalText(String sentence) {



    Text text_1 = new Text(sentence.trim());
    text_1.setFont(Font.font(null, FontWeight.MEDIUM, textSize));
    double[] dividerPositions = split_pane.getDividerPositions();



    double split_pane_width = split_pane.getPrefWidth();
    double single_pane_width = dividerPositions[0] * split_pane_width;
    text_1.setWrappingWidth(single_pane_width);


    Text text_2 = new Text();
    text_2.setFont(Font.font(null, FontWeight.MEDIUM, textSize));




    Text text = new Text();
    text.setText(sentence.trim() +  " ");
    text.setFont(Font.font(null, FontWeight.MEDIUM, textSize));


    if (sentence.contains("hi")) {

        text_2.setText("Yes" + "\n");
        text_2.setFill(Color.RED);
        text_1.setFill(Color.RED);
    }
    else {
        text_2.setText("No" + "\n");
    }

    HBox left_hbox = new HBox();
    left_hbox.getChildren().add(text_1);
    double leftHboxHeight = left_hbox.getHeight();

    HBox right_hbox = new HBox();
    right_hbox.setHeight(leftHboxHeight);
    right_hbox.getChildren().add(text_2);

    right_hbox.getChildren().add(text_2);
    left_hbox.getChildren().add(text_1);

}

应用截图:

我是 JavaFx 的新手。提前致谢。`

标签: javajavafx

解决方案


节点不会在下一个布局传递之前定位。此布局传递发生在方法返回后的某个时间。最好将 aPane用于是/否文本并将layoutY这些节点的属性绑定到该layoutY属性。只需确保添加到右侧的文本的垂直对齐方式正确。

简化示例

@Override
public void start(Stage primaryStage) {
    VBox left = new VBox();
    Pane right = new Pane();
    
    Button button = new Button("Add");
    
    HBox hbox = new HBox(left, right, button);
    button.setOnAction(new EventHandler<ActionEvent>() {
        private int count = 1;
        
        private final StringBuilder builder = new StringBuilder("1");
        
        @Override
        public void handle(ActionEvent event) {
            Text text = new Text(builder.toString());
            Text yesNo = new Text(count % 2 == 0 ? "Yes" : "No");
            yesNo.setTextOrigin(VPos.TOP);
            
            HBox container = new HBox(text);
            
            left.getChildren().add(container);
            left.getChildren().add(text);
            right.getChildren().add(yesNo);
            yesNo.layoutYProperty().bind(container.layoutYProperty());
            
            count++;
            builder.append('\n');
            for (int i = 0; i < count; i++) {
                builder.append('1');
            }
        }
    
    });
    
    Scene scene = new Scene(hbox, 400, 400);
    primaryStage.setScene(scene);
    primaryStage.show();
}

请注意,这不会同步两个ScrollPanes 的滚动。我建议使用 aGridPane并将文本添加到相同的ScrollPane位置。


推荐阅读