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.


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.

The pattern:

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();
}

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:

  • 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.

The pattern:

Imports:

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

Controller:

@FXML private CheckBox chkIncludeWeekends;

@FXML
private void handleGenerate() {
    boolean includeWeekends = chkIncludeWeekends.isSelected();
    if (includeWeekends) {
        // include weekend days
    } else {
        // skip them
    }
}

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:

  • 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.

The pattern:

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
}

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:

  • 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.

The pattern:

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;
    }
    saveDueDate(due);                          // your own action
}

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 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.

The pattern:

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
    }));
}

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:

  • 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.