This post is part the 100 Days of JavaFX Series.

Together, we’ve seen how to create basic skeleton for a JavaFX application (using FXML). For the next days and articles, I will be using an example project to explore the different aspects of building a JavaFX application.

The example application is a tool that offers a GUI to manage to collection of JSON Schemas. Who knows, if things go well I may even release it as a proper application. In this article we are going to layout the basics for the application UI.

Some of the basic features I want to implement:

  • List schema
  • GUI to build and edit JSON schemas
  • Examples that can be used for validation
  • View and Edit the raw schema with syntax highlighting (like a regular code editor)

FXML Elements

Our root Node — BorderPane

<BorderPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="eu.leward.jschema.AppController"
            prefHeight="400.0" prefWidth="600.0">

  <left> <!-- Content of the left pane --> </left>
  <center> <!-- Content of the center pane --> </center>

</BorderPane>

A BorderPane sets 5 region which can are anchored to different areas of the screen.

Border Pane

BorderPane example from the OpenJFX API Documentation

For our app, we will be only using, for now, the left and center areas.

Listing (Explorer) the JSON Schema — TreeView

<TreeView>
    <TreeItem value="Schemas" expanded="true">
        <children>
            <TreeItem value="event.json"/>
            <TreeItem value="game.json"/>
        </children>
    </TreeItem>
</TreeView>

Tree View

TreeView example

Our tabbed main view — TabPane

<TabPane>
    <Tab text="JSON" closable="false">
       <!-- Content Here -->
    </Tab>
    <Tab text="Designer" closable="false">
        <!-- Content Here -->
    </Tab>
    <Tab text="Examples">
        <Label text="Examples will come here"/>
    </Tab>
</TabPane>

Tab Pane

TabPane example

A GridPane for the Designer Form

GridView allows you to organize the layout of your elements following a grid. It’s very similar to how HTML tables were used back in the days.

GridPane is very useful to align elements of a form.

<GridPane hgap="10" vgap="10" style="-fx-padding: 20px;">
    <Label text="\$id" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
    <TextField text='https://example.com/person.schema.json' GridPane.rowIndex="0"
               GridPane.columnIndex="1"/>

    <Label text="title" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
    <TextField text='Person' GridPane.rowIndex="1" GridPane.columnIndex="1"/>

    <Label text="type" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
    <ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" value="object">
        <String fx:value="object"/>
        <String fx:value="string"/>
        <String fx:value="number"/>
        <String fx:value="boolean"/>
    </ChoiceBox>
</GridPane>

Pay a close attention to the **GridPane.rowIndex** and **GriPane.columnIndex** attributes. Those are the attributes you use to define your grid. Unlike HTML you don’t how have to explicitly create tags for rows and cells, the GridView components will figure that out for you. This is somewhat similar to CSS Grids.

GridPane has more options to it, but we keep it simple here since that’s all we need.

Grid Pane

GridPane example

Full FXML Example

<!-- app.fxml -->
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<?import javafx.collections.FXCollections?>
<BorderPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="eu.leward.jschema.AppController"
            prefHeight="400.0" prefWidth="600.0">

    <left>
        <TreeView>
            <TreeItem value="Schemas" expanded="true">
                <children>
                    <TreeItem value="event.json"/>
                    <TreeItem value="game.json"/>
                </children>
            </TreeItem>
        </TreeView>
    </left>

    <center>
        <TabPane>
            <Tab text="JSON" closable="false">
                <TextArea style="-fx-font-family: 'Inconsolata'">
                    { "$id": "https://example.com/person.schema.json" }
                </TextArea>
            </Tab>
            <Tab text="Designer" closable="false">
                <GridPane hgap="10" vgap="10" style="-fx-padding: 20px;">
                    <Label text="\$id" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
                    <TextField text='https://example.com/person.schema.json' GridPane.rowIndex="0"
                                GridPane.columnIndex="1"/>

                    <Label text="title" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
                    <TextField text='Person' GridPane.rowIndex="1" GridPane.columnIndex="1"/>

                    <Label text="type" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
                    <ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" value="object">
                        <String fx:value="object"/>
                        <String fx:value="string"/>
                        <String fx:value="number"/>
                        <String fx:value="boolean"/>
                    </ChoiceBox>
                </GridPane>
            </Tab>
            <Tab text="Examples">
                <Label text="Examples will come here"/>
            </Tab>
        </TabPane>
    </center>

</BorderPane>

JSON Editor Tab

JSON Editor Tab

Schema Designer Tab

JSON Designer Tab

Example Tab

Examples tab — not much is there yet