Input controls (building forms)

IA tooling, not an exam topic. These are JavaFX form-building patterns to adapt for your IA. Nothing here is examinable, and your IA must be your own work.

This page covers the controls a form is built from: pick one option, toggle options on and off, choose from a list, choose a date, and restrict a field to numbers.

New here? Read Start here: how every recipe fits together first; it explains the two places you edit and the fx:id link every recipe relies on.


Choose exactly one option

What this does: groups radio buttons so only one can be selected at a time, then reads which one the user chose.

When you would use it in your IA: picking a single category, a difficulty level, a payment method, or a size, where the choices are mutually exclusive.

In SceneBuilder (the layout): add one RadioButton per choice and give each an fx:id (rbSmall, rbMedium, rbLarge). You can group them here by dropping a ToggleGroup on one and reusing it, or do the grouping in code as shown below.

<RadioButton fx:id="rbSmall" text="Small" />
<RadioButton fx:id="rbMedium" text="Medium" />
<RadioButton fx:id="rbLarge" text="Large" />

In the controller (the .java file):

Imports:

import javafx.fxml.FXML;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;

Controller:

@FXML private RadioButton rbSmall;
@FXML private RadioButton rbMedium;
@FXML private RadioButton rbLarge;

private final ToggleGroup sizeGroup = new ToggleGroup();

@FXML
public void initialize() {
    rbSmall.setToggleGroup(sizeGroup);     // the group lets only one be on at once
    rbMedium.setToggleGroup(sizeGroup);
    rbLarge.setToggleGroup(sizeGroup);
    rbSmall.setSelected(true);             // a sensible default
}

private String selectedSize() {
    RadioButton chosen = (RadioButton) sizeGroup.getSelectedToggle();
    if (chosen == null) {
        return null;                       // nothing picked
    }
    return chosen.getText();
}

Where your own logic goes: call selectedSize() from your own handler (a Save or Next button, say) and act on the result:

String size = selectedSize();
// your IA logic here: use the chosen option

Make it your own:

  • Rename the buttons and the group for your own set of options.
  • The ToggleGroup is the key part: without it, the radio buttons act independently and the user could turn on more than one.
  • getSelectedToggle() returns the chosen toggle, or null if none is selected. Setting a default avoids the null case.

Watch out for:

  • The fx:id values in the layout must match the @FXML field names exactly, or the screen will not load.
  • You can also create the ToggleGroup in FXML with <ToggleGroup fx:id="sizeGroup" /> and point each radio button at it with toggleGroup="$sizeGroup". Pick one place to define it, not both.
  • If you forget to assign the group, every radio button stays independent and the “only one” behaviour is lost.

Mix with: Switch options on and off, Tell the user something.


Switch options on and off

What this does: reads whether a checkbox is ticked, for options that are independent of each other.

When you would use it in your IA: opt-in settings like “remember me”, “include weekends”, or a list of toppings where any number can be chosen at once.

In SceneBuilder (the layout): add a CheckBox and give it an fx:id of chkIncludeWeekends. Nothing else to add here.

<CheckBox fx:id="chkIncludeWeekends" text="Include weekends" />

In the controller (the .java file):

Imports:

import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;

Controller:

@FXML private CheckBox chkIncludeWeekends;

@FXML
private void handleGenerate() {
    boolean includeWeekends = chkIncludeWeekends.isSelected();
    // your IA logic here: branch on includeWeekends
    if (includeWeekends) {
        // include weekend days
    } else {
        // skip them
    }
}

Where your own logic goes: the spot marked // your IA logic here, where you act on the ticked or unticked state. Reading isSelected() is the wiring.

Make it your own:

  • Rename the checkbox for your setting.
  • isSelected() returns true when ticked and false when not. Read it whenever you need the current state.

Watch out for:

  • The fx:id chkIncludeWeekends must match the @FXML field name exactly, or the screen will not load.
  • Use checkboxes when choices are independent and radio buttons when exactly one must be chosen. Mixing the two up confuses users.

Mix with: Choose exactly one option, Pick from a list.


Pick from a list

What this does: shows a dropdown of options and reads the one the user selected.

When you would use it in your IA: choosing a category, a country, a class group, or any single value from a longer list where radio buttons would take too much space.

In SceneBuilder (the layout): add a ComboBox and give it an fx:id of cmbCategory. The options are filled from code below.

<ComboBox fx:id="cmbCategory" />

In the controller (the .java file):

Imports:

import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;

Controller:

@FXML private ComboBox<String> cmbCategory;

@FXML
public void initialize() {
    cmbCategory.getItems().addAll("Fruit", "Vegetable", "Dairy", "Other");
}

private String chosenCategory() {
    return cmbCategory.getValue();      // null until the user picks one
}

Where your own logic goes: call chosenCategory() from your own handler and act on the result:

String category = chosenCategory();
// your IA logic here: use the chosen category (check for null first)

Make it your own:

  • Replace the list passed to addAll(...) with your own options.
  • getValue() returns the selected item, or null if nothing has been chosen, so check for null before using it.
  • The <String> after ComboBox is a type parameter, the same idea as ArrayList<String>: it says this box holds text. You can hold your own objects instead, but start with String.

Watch out for:

  • The fx:id cmbCategory must match the @FXML field name exactly, or the screen will not load.
  • ChoiceBox is the simpler cousin of ComboBox. It works the same way for a short fixed list but has fewer features, so reach for ComboBox unless you specifically want the lighter control.
  • A ComboBox is not editable by default, so the user can only pick from your list. That is usually what you want for a category.

Mix with: Choose exactly one option, Fill a table from your data.


Pick a date

What this does: lets the user choose a date from a calendar pop-up and reads it as a LocalDate.

When you would use it in your IA: a due date, a booking date, a date of birth, or any field where you need a real date rather than free text the user might mistype.

In SceneBuilder (the layout): add a DatePicker and give it an fx:id of dpDueDate. Nothing else to add here.

<DatePicker fx:id="dpDueDate" />

In the controller (the .java file):

Imports:

import javafx.fxml.FXML;
import javafx.scene.control.DatePicker;
import java.time.LocalDate;

Controller:

@FXML private DatePicker dpDueDate;

@FXML
private void handleSave() {
    LocalDate due = dpDueDate.getValue();      // null if nothing picked yet
    if (due == null) {
        // ask the user to choose a date, then stop
        return;
    }
    // your IA logic here: use the chosen date
    saveDueDate(due);
}

Where your own logic goes: the line marked // your IA logic here, which runs once a real date has been chosen. The null check is wiring.

Make it your own:

  • Rename the date picker for your field.
  • getValue() gives you a LocalDate. You can compare dates with due.isBefore(...) or due.isAfter(...), and format them with a DateTimeFormatter when you need text.

Watch out for:

  • The fx:id dpDueDate must match the @FXML field name exactly, or the screen will not load.
  • The picker returns null until the user actually chooses a date, so always handle the not-yet-picked case before using the value.
  • LocalDate holds a date with no time of day. If you need a time as well, that is a separate field, since DatePicker does not collect one.

Mix with: Catch and explain bad input, Save and load text.


Allow only numbers in a field

What this does: blocks any non-digit character from being typed into a text field, so the value is always a clean number.

When you would use it in your IA: a quantity, an age, a price, or a score field where letters and symbols would only cause errors later.

In SceneBuilder (the layout): add a TextField and give it an fx:id of txtAge. The filter that blocks non-digits is attached in code.

<TextField fx:id="txtAge" />

In the controller (the .java file):

Imports:

import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;

Controller:

@FXML private TextField txtAge;

@FXML
public void initialize() {
    txtAge.setTextFormatter(new TextFormatter<>(change -> {
        if (change.getControlNewText().matches("\\d*")) {
            return change;       // accept: the new text is digits only (or empty)
        }
        return null;             // reject the change, so the character never appears
    }));
}

Where your own logic goes: this recipe is pure wiring; it just keeps the field clean. Your own logic is wherever you read the field later (for example with Integer.parseInt), which is the Catch and explain bad input recipe.

Make it your own:

  • The pattern \\d* means “zero or more digits”. For a decimal field, use \\d*\\.?\\d* to also allow a single dot.
  • Attach a formatter like this to every field that should be numbers only.

Watch out for:

  • The fx:id txtAge must match the @FXML field name exactly, or the screen will not load.
  • This snippet uses a lambda (the change -> { ... } part) and a type parameter on TextFormatter. Both sit outside the exam-style Java subset, so do not treat them as examinable. They are the standard JavaFX way to filter typing.
  • This stops bad characters at the keyboard, but you should still convert with Integer.parseInt inside a try/catch, because an empty field is still not a number. Pair it with Catch and explain bad input.

Mix with: Catch and explain bad input, Show progress toward a goal.


© EduCS.me — A resource hub for Computer Science education

This site uses Just the Docs, a documentation theme for Jekyll.