Is there an easier (lighter) way to center text in

2020-04-18 06:53发布

问题:

So, first things first, I have achieved what I wanted, and that is, display some amount of text in the center of a "zone". Screenshot (upper right corner):

Now, the problem I have is how I achieved this... This is the FXML extract for the whole tab:

<Tab text="Statistics" closable="false">
    <SplitPane orientation="VERTICAL" dividerPositions="0.5">
        <SplitPane orientation="HORIZONTAL" dividerPositions="0.5">
            <GridPane gridLinesVisible="false">
               <!-- snip -->
            </GridPane>
            <!-- HERE -->
            <BorderPane>
                <center>
                    <Label text="No information"/>
                </center>
            </BorderPane>
        </SplitPane>
        <TableView fx:id="stats">
            <!-- snip -->
        </TableView>
    </SplitPane>
</Tab>

As you can see, in order to achieve something which intuitively should be simple (display some text in the center of a zone), I had to create a BorderPane and put a Label in its <center>; and I didn't even have to specify that the text on the label should be centered...

The other things I have tried are:

  • put the Label itself: then the divider of the ScrollPane would be blatanly ignored; the left side would expand to the full width of the Scene (is that it?) minus the width of the divider plus the text of the label, and what is more, the text would be at the top of the zone;
  • enclose it with an AnchorPane: while this would indeed keep the size of the zone, the text would appear on the top left corner and not in the center.

Is there an easier solution than the above?

回答1:

Use a StackPane rather than a BorderPane. By default a StackPane will center any node you put in it. To me, this is the simplest, most intuitive solution.

<StackPane>
    <Label text="No information"/>
</StackPane>

Another way to handle it is to set constraints on the label itself so that the label will expand to fill a resizable area and center itself within the area:

<SplitPane dividerPositions="0.5" 
           prefHeight="400.0" 
           prefWidth="600.0" 
           xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
   <items>
      <StackPane />
      <Label alignment="CENTER" 
             maxHeight="1.7976931348623157E308" 
             maxWidth="1.7976931348623157E308" 
             text="Label" />
   </items>
</SplitPane>

If it is a multi-line label (e.g. it has \n new lines in the text or the available width forces a wrap because you constrain the width and set wrapText="true"), then you need an additional setting to center the multi-line text within the label: textAlignment="true". textAlignment is different from alignment; in particular, textAlignment applies only to multi-line controls.