Search code examples
javajavafxlayoutresponsive-design

How to properly turn custom button set into a responsive object?


Introduction

I am learning how to do responsive a UI with JavaFX 11 for future projects and came up with this doubt about designing a responsive layout.

Problem

Custom Layout

I have built this custom layout which contains two labels and a button, the hierarchy is:

Custom Layout Hierarchy

When I set the app to fullscreen it turns into an unwanted result. The labels and button inside the custom layout stay fixed and do not move with resizing when on fullscreen mode.

Fullscreen unwanted result

Shown in red, there is an undesired white space where I want the items to move into.

How can I do it so the items inside translate accordingly to resize?

Sources visited

FXML

<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="750.0" prefWidth="880.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.GUI.controller.BioJavaController">
   <children>
      <MenuBar>
        <menus>
          <Menu mnemonicParsing="false" text="File">
            <items>
              <MenuItem mnemonicParsing="false" text="Close" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Edit">
            <items>
              <MenuItem mnemonicParsing="false" text="Delete" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Help">
            <items>
              <MenuItem mnemonicParsing="false" text="About" />
            </items>
          </Menu>
        </menus>
      </MenuBar>
      <SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="728.0" prefWidth="883.0">
         <items>
            <AnchorPane prefHeight="200.0" prefWidth="200.0">
               <children>
                  <LineChart fx:id="LineChart" prefHeight="358.0" prefWidth="878.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <xAxis>
                      <CategoryAxis side="BOTTOM" />
                    </xAxis>
                    <yAxis>
                      <NumberAxis side="LEFT" />
                    </yAxis>
                  </LineChart>
               </children>
            </AnchorPane>
            <SplitPane dividerPositions="0.5" prefHeight="333.0" prefWidth="878.0">
              <items>
                <AnchorPane fx:id="measurePanel" minHeight="0.0" minWidth="0.0" prefHeight="436.0" prefWidth="349.0">
                     <children>
                        <ToolBar fx:id="ToolPoint_1" prefHeight="40.0" prefWidth="393.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="-1.0">
                           <items>
                              <AnchorPane prefHeight="40.0" prefWidth="393.0">
                                 <children>
                                    <Button fx:id="measureBtn_1" layoutX="317.0" layoutY="2.0" mnemonicParsing="false" onMouseClicked="#onMeasureClick" text="Count" AnchorPane.leftAnchor="317.0" />
                                    <Label layoutY="9.0" text="Counter" AnchorPane.leftAnchor="0.0" />
                                    <Label layoutX="132.0" layoutY="9.0" prefHeight="17.0" prefWidth="261.0" text="Number: 0" AnchorPane.leftAnchor="132.0" />
                                 </children>
                              </AnchorPane>
                           </items>
                        </ToolBar>
                        <ToolBar fx:id="ToolPoint_11" layoutY="50.0" prefHeight="50.0" prefWidth="436.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                           <items>
                              <AnchorPane prefHeight="40.0" prefWidth="393.0">
                                 <children>
                                    <Button fx:id="measureBtn_11" layoutX="317.0" layoutY="2.0" mnemonicParsing="false" onMouseClicked="#onMeasureClick" text="Count" AnchorPane.leftAnchor="317.0" />
                                    <Label layoutY="9.0" text="Counter" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
                                    <Label layoutX="132.0" layoutY="9.0" prefHeight="17.0" prefWidth="261.0" text="Number: 0" AnchorPane.leftAnchor="132.0" AnchorPane.rightAnchor="0.0" />
                                 </children>
                              </AnchorPane>
                           </items>
                        </ToolBar>
                     </children>
                  </AnchorPane>
                <AnchorPane fx:id="handPanel" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
                     <children>
                        <ImageView fitHeight="286.0" fitWidth="252.0" layoutX="331.0" layoutY="-3.0" pickOnBounds="true" preserveRatio="true">
                           <image>
                              <Image url="@Estilo/Elegant.PNG" />
                           </image>
                        </ImageView>
                     </children>
                  </AnchorPane>
              </items>
            </SplitPane>
         </items>
      </SplitPane>
   </children>
</VBox>

Solution

  • I would replace the ToolBar with HBox and add the three Nodes to the HBox. I would then use CSS to get the style I want.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.chart.CategoryAxis?>
    <?import javafx.scene.chart.LineChart?>
    <?import javafx.scene.chart.NumberAxis?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.Menu?>
    <?import javafx.scene.control.MenuBar?>
    <?import javafx.scene.control.MenuItem?>
    <?import javafx.scene.control.SplitPane?>
    <?import javafx.scene.control.ToolBar?>
    <?import javafx.scene.image.Image?>
    <?import javafx.scene.image.ImageView?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.VBox?>
    
    <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="750.0" prefWidth="880.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.GUI.controller.BioJavaController">
       <children>
          <MenuBar>
            <menus>
              <Menu mnemonicParsing="false" text="File">
                <items>
                  <MenuItem mnemonicParsing="false" text="Close" />
                </items>
              </Menu>
              <Menu mnemonicParsing="false" text="Edit">
                <items>
                  <MenuItem mnemonicParsing="false" text="Delete" />
                </items>
              </Menu>
              <Menu mnemonicParsing="false" text="Help">
                <items>
                  <MenuItem mnemonicParsing="false" text="About" />
                </items>
              </Menu>
            </menus>
          </MenuBar>
          <SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="728.0" prefWidth="883.0">
             <items>
                <AnchorPane prefHeight="200.0" prefWidth="200.0">
                   <children>
                      <LineChart fx:id="LineChart" prefHeight="358.0" prefWidth="878.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                        <xAxis>
                          <CategoryAxis side="BOTTOM" />
                        </xAxis>
                        <yAxis>
                          <NumberAxis side="LEFT" />
                        </yAxis>
                      </LineChart>
                   </children>
                </AnchorPane>
                <SplitPane dividerPositions="0.5, 0.5" prefHeight="333.0" prefWidth="878.0">
                  <items>
                      <VBox>
                         <children>
                            <HBox alignment="CENTER" prefHeight="50.0" style="-fx-background-color: #707070,        linear-gradient(#fcfcfc, #f3f3f3),        linear-gradient(#f2f2f2 0%, #ebebeb 49%, #dddddd 50%, #cfcfcf 100%); -fx-background-insets: 0,1,2;; -fx-background-radius: 3,2,1;; -fx-padding: 3 30 3 30;; -fx-text-fill: black;;">
                               <children>
                                  <Label maxWidth="1.7976931348623157E308" text="Counter" HBox.hgrow="ALWAYS" />
                                  <Label maxWidth="1.7976931348623157E308" text="Number: 0" HBox.hgrow="ALWAYS" />
                                  <Button fx:id="measureBtn_1" mnemonicParsing="false" onMouseClicked="#onMeasureClick" text="Count" />
                               </children>
                               <VBox.margin>
                                  <Insets />
                               </VBox.margin>
                            </HBox>
                            <HBox alignment="CENTER" prefHeight="50.0" style="-fx-background-color: #707070,        linear-gradient(#fcfcfc, #f3f3f3),        linear-gradient(#f2f2f2 0%, #ebebeb 49%, #dddddd 50%, #cfcfcf 100%); -fx-background-insets: 0,1,2;; -fx-background-radius: 3,2,1;; -fx-padding: 3 30 3 30;; -fx-text-fill: black;;">
                               <children>
                                  <Label maxWidth="1.7976931348623157E308" text="Counter" HBox.hgrow="ALWAYS" />
                                  <Label maxWidth="1.7976931348623157E308" text="Number: 0" HBox.hgrow="ALWAYS" />
                                  <Button fx:id="measureBtn_12" mnemonicParsing="false" onMouseClicked="#onMeasureClick" text="Count" />
                               </children>
                               <VBox.margin>
                                  <Insets />
                               </VBox.margin>
                            </HBox>
                         </children>
                      </VBox>
                    <AnchorPane fx:id="handPanel" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
                         <children>
                            <ImageView fitHeight="286.0" fitWidth="252.0" layoutX="331.0" layoutY="-3.0" pickOnBounds="true" preserveRatio="true">
                               <image>
                                  <Image url="@Estilo/Elegant.PNG" />
                               </image>
                            </ImageView>
                         </children>
                      </AnchorPane>
                      <ToolBar prefHeight="40.0" prefWidth="200.0">
                        <items>
                          <Button mnemonicParsing="false" text="Button" />
                        </items>
                      </ToolBar>
                  </items>
                </SplitPane>
             </items>
          </SplitPane>
       </children>
    </VBox>
    

    Normal Normal

    Full Screen Full Screen

    Style code from: http://fxexperience.com/2011/12/styling-fx-buttons-with-css/.