The MVC View (datecalculator Package)

So lecture over, let’s cut to the chase.  Figure 5 is the latest version of the Date Difference Calculator GUI; Listing 2 is the FXML file used to generate it:

DateCalc UI 

Figure 5 – Date Difference Calculator At Startup

<?xml version="1.0" encoding="UTF-8"?>
 
<?import javafx.scene.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?scenebuilder-background-color 0xbfbfbfff?>
 
<AnchorPane fx:id="dateCalcPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="627.0" prefWidth="449.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="datecalculator.DateCalculatorUI">
  <children>
    <MenuBar fx:id="calcMenuBar" layoutX="14.0" layoutY="14.0" prefHeight="20.0" prefWidth="421.0">
      <menus>
        <Menu id="fileMenu" fx:id="fileMenu" text="File">
          <items>
            Menu Items…
          </items>
        </Menu>
        <Menu id="optionsMenu" fx:id="optionsMenu" text="Options" />
        <Menu id="helpMenu" fx:id="helpMenu" text="Help">
          <items>
             Menu Items…
          </items>
        </Menu>
      </menus>
    </MenuBar>
    <Button fx:id="calculateButton" layoutX="102.0" layoutY="247.0" prefHeight="25.0" prefWidth="65.0" text="Calculate" />
    <Button fx:id="resetButton" layoutX="192.0" layoutY="247.0" prefHeight="25.0" prefWidth="65.0" text="Reset" />
    <Button fx:id="closeButton" layoutX="282.0" layoutY="247.0" prefHeight="25.0" prefWidth="65.0" text="Close" />
    <TitledPane fx:id="startDTPane" alignment="CENTER" animated="false" collapsible="false" contentDisplay="CENTER" layoutX="14.0" layoutY="42.0" prefHeight="84.0" prefWidth="421.0" text="START DATE &amp; TIME" textAlignment="CENTER">
      <content>
        <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="56.0" prefWidth="364.0">
          <children>
            <ChoiceBox fx:id="startMonthSelect" layoutX="6.0" layoutY="5.0" prefHeight="18.0" prefWidth="54.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="startDaySelect" layoutX="65.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <TextField fx:id="startYearSelect" alignment="CENTER_RIGHT" layoutX="116.0" layoutY="5.0" prefHeight="19.0" prefWidth="56.0" />
            <ChoiceBox fx:id="startHourSelect" layoutX="204.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="startMinuteSelect" layoutX="255.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="startSecondSelect" layoutX="304.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <CheckBox fx:id="startUseCurrentDT" layoutX="7.0" layoutY="37.0" text="Use Current Date/Time" />
            <Label fx:id="startEventLabel" alignment="CENTER_RIGHT" contentDisplay="RIGHT" layoutX="150.0" layoutY="38.0" prefHeight="13.0" prefWidth="65.0" text="Start Event" />
            <TextField fx:id="startEventField" editable="false" layoutX="222.0" layoutY="34.0" prefHeight="19.0" prefWidth="190.0" />
            <ChoiceBox fx:id="startZoneSelect" layoutX="356.0" layoutY="5.0" prefHeight="18.0" prefWidth="56.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
          </children>
        </AnchorPane>
      </content>
    </TitledPane>
    <TitledPane fx:id="finishDTPane" alignment="CENTER" animated="false" collapsible="false" contentDisplay="CENTER" layoutX="14.0" layoutY="138.0" prefHeight="84.0" prefWidth="421.0" text="FINISH DATE &amp; TIME" textAlignment="CENTER">
      <content>
        <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="56.0" prefWidth="364.0">
          <children>
            <ChoiceBox fx:id="finishMonthSelect" layoutX="6.0" layoutY="5.0" prefHeight="18.0" prefWidth="54.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="finishDaySelect" layoutX="65.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <TextField fx:id="finishYearSelect" alignment="CENTER_RIGHT" layoutX="116.0" layoutY="5.0" prefHeight="19.0" prefWidth="56.0" />
            <ChoiceBox fx:id="finishHourSelect" layoutX="204.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="finishMinuteSelect" layoutX="255.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <ChoiceBox fx:id="finishSecondSelect" layoutX="304.0" layoutY="5.0" prefHeight="18.0" prefWidth="44.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
            <CheckBox fx:id="finishUseCurrentDT" layoutX="7.0" layoutY="37.0" text="Use Current Date/Time" />
            <Label fx:id="finishEventLabel" alignment="CENTER_RIGHT" contentDisplay="RIGHT" layoutX="150.0" layoutY="38.0" prefHeight="13.0" prefWidth="65.0" text="Finish Event" />
            <TextField fx:id="finishEventField" editable="false" layoutX="222.0" layoutY="34.0" prefHeight="19.0" prefWidth="190.0" />
            <ChoiceBox fx:id="finishZoneSelect" layoutX="356.0" layoutY="5.0" prefWidth="56.0">
              <items>
                ChoiceBox Items…
              </items>
            </ChoiceBox>
          </children>
        </AnchorPane>
      </content>
    </TitledPane>
    <Separator fx:id="resultPanelSeparator" layoutY="280.0" prefHeight="8.0" prefWidth="449.0" />
    <Label fx:id="fromLabel" alignment="CENTER_RIGHT" layoutX="62.0" layoutY="306.0" text="FROM" textAlignment="RIGHT" />
    <TextField fx:id="fromField" editable="false" layoutX="106.0" layoutY="300.0" prefHeight="19.0" prefWidth="313.0" />
    <Label fx:id="toLabel" alignment="CENTER_RIGHT" layoutX="79.0" layoutY="328.0" text="TO" textAlignment="RIGHT" />
    <TextField fx:id="toField" editable="false" layoutX="106.0" layoutY="325.0" prefHeight="19.0" prefWidth="313.0" />
    <AnchorPane fx:id="resultPane" layoutX="21.0" layoutY="360.0" prefHeight="221.0" prefWidth="414.0">
      <children>
        <Label fx:id="totalTimeLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="8.0" text="Total Time" textAlignment="RIGHT" />
        <TextField fx:id="totalTimeField" editable="false" layoutX="71.0" layoutY="4.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="yearsLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="34.0" prefHeight="13.0" prefWidth="52.0" text="Years" textAlignment="RIGHT" />
        <TextField fx:id="yearsField" editable="false" layoutX="71.0" layoutY="30.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="monthsLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="60.0" prefHeight="13.0" prefWidth="52.0" text="Months" textAlignment="RIGHT" />
        <TextField fx:id="monthsField" editable="false" layoutX="71.0" layoutY="56.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="weeksLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="86.0" prefHeight="13.0" prefWidth="52.0" text="Weeks" textAlignment="RIGHT" />
        <TextField fx:id="weeksField" editable="false" layoutX="71.0" layoutY="83.0" prefHeight="19.0" prefWidth="340.9998779296875" />
        <Label fx:id="daysLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="112.0" prefHeight="13.0" prefWidth="52.0" text="Days" textAlignment="RIGHT" />
        <TextField fx:id="daysField" editable="false" layoutX="71.0" layoutY="108.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="hoursLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="138.0" prefHeight="13.0" prefWidth="52.0" text="Hours" textAlignment="RIGHT" />
        <TextField fx:id="hoursField" editable="false" layoutX="71.0" layoutY="135.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="minutesLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="164.0" prefHeight="13.0" prefWidth="52.0" text="Minutes" textAlignment="RIGHT" />
        <TextField fx:id="minutesField" editable="false" layoutX="71.0" layoutY="161.0" prefHeight="19.0" prefWidth="341.0" />
        <Label fx:id="secondsLabel" alignment="CENTER_RIGHT" layoutX="8.0" layoutY="190.0" prefHeight="13.0" prefWidth="52.0" text="Seconds" textAlignment="RIGHT" />
        <TextField fx:id="secondsField" editable="false" layoutX="71.0" layoutY="187.0" prefHeight="19.0" prefWidth="341.0" />
      </children>
    </AnchorPane>
    <Label fx:id="statusLabel" layoutX="40.0" layoutY="593.0" text="STATUS" />
    <TextField fx:id="statusField" editable="false" layoutX="92.0" layoutY="589.0" prefHeight="19.0" prefWidth="341.0" />
  </children>
  <properties>
 
  </properties>
</AnchorPane>

Listing 2 – Date Calculator UI FXML file

(Note that the top AnchorPane tag identifies the Controller.  Also, I commented out the Menu and ChoiceBox content)

And here is SceneBuilder in action, showing the UI with layout pretty much complete.  I won’t go into the details of how to use the tool, other than to note that you can drag UI features from the Library Panel in the upper left into the Content Panel in the center, and define properties including CSS references, layout attributes, and event handlers for a selected graphical object in the Inspector Panel on the right.

SceneBuilder

 Figure 6 – SceneBuilder layout, Date Difference Calculator UI

If you look at the GUI and FXML file you will see I added a couple of features that were not in the original concept, including the ability to save dates as named Events and load an Event into the calculator from a data store.  From the SceneBuilder perspective that only required adding a couple of menu items, and creating a pop-up window that the main Stage references.  More on pop-up windows below.

I think the results of the FXML file speak for themselves; clearly you do not want to maintain either the graphical or file content manually.  As I said, using SceneBuilder consistently pays off handsomely over time.