Basic JavaFX controls II

In this chapter, we continue covering basic JavaFX controls. We present a DatePicker, a MenuBar, a ColorPicker, a RadioButton, and a TabPane control.

DatePicker

DatePicker is a control for choosing a date.

DatePickerEx.java
package com.zetcode;

import java.time.LocalDate;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 * ZetCode JavaFX tutorial
 *
 * This program shows a date chosen from 
 * a DatePicker in a label.
 *
 * Author: Jan Bodnar 
 * Website: zetcode.com 
 * Last modified: June 2015
 */

public class DatePickerEx extends Application {
    
    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {
        
        VBox root = new VBox(15);
        root.setPadding(new Insets(10));        
        
        Label lbl = new Label("...");
        
        DatePicker datePicker = new DatePicker();

        datePicker.setOnAction(e -> {
            LocalDate date = datePicker.getValue();
            lbl.setText(date.toString());
        });

        root.getChildren().addAll(datePicker, lbl);

        Scene scene = new Scene(root, 350, 200);
        
        stage.setTitle("Date picker");
        stage.setScene(scene);
        stage.show();        
    }

    
    public static void main(String[] args) {
        launch(args);
    }
}

The example uses a DatePicker control to select and display a date. The date is shown in a label control.

DatePicker datePicker = new DatePicker();

The instance of a DatePicker control is created.

datePicker.setOnAction(e -> {
    LocalDate date = datePicker.getValue();
    lbl.setText(date.toString());
});

The getValue() method returns the selected date as a LocalDate. The chosen date is set to the label control with its setText() method.

DatePicker
Figure: DatePicker

MenuBar

MenuBar consists of Menu objects, which hold MenuItem objects—the commands of the application. It is traditionally placed at the top of the application window.

MenuBarEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

/**
 * ZetCode JavaFX tutorial
 *
 * This program creates a MenuBar with one
 * menu and four menu items.
 *
 * Author: Jan Bodnar
 * Website: zetcode.com
 * Last modified: June 2015
 */

public class MenuBarEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        HBox root = new HBox();

        MenuBar mbar = new MenuBar();
        mbar.prefWidthProperty().bind(stage.widthProperty());

        MyMenuHandler handler = new MyMenuHandler();

        Menu fileMenu = new Menu("File");
        mbar.getMenus().add(fileMenu);

        MenuItem nmi = new MenuItem("New");
        nmi.setOnAction(handler);
        fileMenu.getItems().add(nmi);

        MenuItem omi = new MenuItem("Open");
        omi.setOnAction(handler);
        fileMenu.getItems().add(omi);

        MenuItem smi = new MenuItem("Save");
        smi.setOnAction(handler);
        fileMenu.getItems().add(smi);

        fileMenu.getItems().add(new SeparatorMenuItem());

        MenuItem emi = new MenuItem("Exit");
        emi.setOnAction((ActionEvent event) -> {
            Platform.exit();
        });

        fileMenu.getItems().add(emi);

        root.getChildren().add(mbar);

        Scene scene = new Scene(root, 300, 250);

        stage.setTitle("MenuBar");
        stage.setScene(scene);
        stage.show();
    }

    private class MyMenuHandler implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent event) {
            
            doShowMessageDialog(event);
        }
        
        private void doShowMessageDialog(ActionEvent event) {

            MenuItem mi = (MenuItem) event.getSource();
            String item = mi.getText();
            Alert alert = new Alert(AlertType.INFORMATION);
            alert.setTitle("Information dialog");
            alert.setHeaderText("Menu item selection information");
            alert.setContentText(item + " menu item selected");

            alert.showAndWait();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

The example contains one menu in the menubar. The menu holds four menu items and one separator.

MenuBar mbar = new MenuBar();
mbar.prefWidthProperty().bind(stage.widthProperty());

MenuBar control is created. Inside a horizontal box, it is large enough to show its single menu. By binding it to the stage's widthProperty, the menubar is stretched from left to right.

MyMenuHandler handler = new MyMenuHandler();

A menu handler is created. It is shared by three menu items.

Menu fileMenu = new Menu("File");
mbar.getMenus().add(fileMenu);

The File Menu is created and added to the menubar.

MenuItem nmi = new MenuItem("New");
nmi.setOnAction(handler);
fileMenu.getItems().add(nmi);

The New MenuItem is created and added to the File menu. The handler to the menu item is set with the setOnAction() method.

fileMenu.getItems().add(new SeparatorMenuItem());

SeparatorMenuItem is a horizontal separator which is used to visually separate related menu items.

emi.setOnAction((ActionEvent event) -> {
    Platform.exit();
});

The Exit menu item terminates the application with the Platform.exit() method call.

private class MyMenuHandler implements EventHandler<ActionEvent> {

    @Override
    public void handle(ActionEvent event) {
        
        doShowMessageDialog(event);
    }
...
}

The EventHandler's handle() method is invoked when the menu item with this handler is selected. The method invokes the doShowMessageDialog() method, which shows a message dialog.

private void doShowMessageDialog(ActionEvent event) {

    MenuItem mi = (MenuItem) event.getSource();
    String item = mi.getText();
    Alert alert = new Alert(AlertType.INFORMATION);
    alert.setTitle("Information dialog");
    alert.setHeaderText("Menu item selection information");
    alert.setContentText(item + " menu item selected");

    alert.showAndWait();
}

The doShowMessageDialog() method creates an information dialog with the Alert control. From the event source we determine the name of the menu item, which is used to create the content text.

MenuBar
Figure: MenuBar

ColorPicker

ColorPicker is a built-in dialog for choosing a colour value. It allows the user to select a colour from either a standard palette of colours or to define a custom colour.

ColorPickerEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * ZetCode JavaFX tutorial
 *
 * This program uses the ColorPicker 
 * dialog to choose a colour value.
 *
 * Author: Jan Bodnar 
 * Website: zetcode.com 
 * Last modified: June 2015
 */

public class ColorPickerEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        HBox root = new HBox(25);
        root.setAlignment(Pos.BASELINE_CENTER);
        root.setPadding(new Insets(10));

        Text txt = new Text("ZetCode");

        Font font = Font.font(20);
        txt.setFont(font);

        ColorPicker cp = new ColorPicker();
        cp.setOnAction((ActionEvent event) -> {
            txt.setFill(cp.getValue());
        });

        root.getChildren().addAll(cp, txt);

        Scene scene = new Scene(root, 300, 250);

        stage.setTitle("ColorPicker");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

In the example, we have a ColorPicker and a Text control. The selected colour from the colour picker is used to set the foreground colour of the text control.

Text txt = new Text("ZetCode");

Font font = Font.font(20);
txt.setFont(font);

A Text control is created. We enlarge its font for better visibility.

ColorPicker cp = new ColorPicker();
cp.setOnAction((ActionEvent event) -> {
    txt.setFill(cp.getValue());
});

A ColorPicker is created and an event handler is set. The currently selected colour is retrieved with the ColorPicker's getValue() method. The foreground colour of the text control is changed using the setFill() method.

ColorPicker
Figure: ColorPicker

RadioButton

RadioButton is usually used to create mutually exclusive series of items. Only one RadioButton can be selected when placed in a ToggleGroup. When a RadioButton is selected an ActionEvent is sent.

RadioButtonEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 * ZetCode JavaFX tutorial
 *
 * This program presents the RadioButton
 * control.
 *
 * Author: Jan Bodnar 
 * Website: zetcode.com 
 * Last modified: June 2015
 */

public class RadioButtonEx extends Application {
    
    private final double BORDER = 10d;
    private Label lbl2;

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        AnchorPane root = new AnchorPane();
        
        VBox vbox = new VBox(10);
        vbox.setPadding(new Insets(10));
        
        Label lbl1 = new Label("Difficulty");
        
        lbl2 = new Label("");
        lbl2.setStyle("-fx-background-color:wheat; -fx-padding: 0 0 0 5");
        lbl2.prefWidthProperty().bind(stage.widthProperty().subtract(2*BORDER));

        ToggleGroup tg =  new ToggleGroup();
        tg.selectedToggleProperty().addListener(new MyToggleListener());

        RadioButton rb1 = new RadioButton("Easy");
        rb1.setToggleGroup(tg);
        rb1.setSelected(true);

        RadioButton rb2 = new RadioButton("Medium");
        rb2.setToggleGroup(tg);

        RadioButton rb3 = new RadioButton("Hard");
        rb3.setToggleGroup(tg);
        
        vbox.getChildren().addAll(lbl1, rb1, rb2, rb3);
        
        root.getChildren().addAll(vbox, lbl2);
        
        AnchorPane.setTopAnchor(vbox, BORDER);
        AnchorPane.setBottomAnchor(lbl2, BORDER);
        AnchorPane.setLeftAnchor(lbl2, BORDER);

        Scene scene = new Scene(root, 300, 250);

        stage.setTitle("RadioButton");
        stage.setScene(scene);
        stage.show();
    }
    
    private class MyToggleListener implements ChangeListener<Toggle> {

        @Override
        public void changed(ObservableValue<? extends Toggle> observable, 
                Toggle oldValue, Toggle newValue) {
            
            RadioButton rb = (RadioButton) newValue;
            String txt = rb.getText();
            lbl2.setText(txt);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

The example has three radio buttons. By placing them in a toggle group, only one of them can be selected at a time.

Label lbl1 = new Label("Difficulty");

This label gives description to the radio buttons.

lbl2 = new Label("");
lbl2.setStyle("-fx-background-color:wheat; -fx-padding: 0 0 0 5");
lbl2.prefWidthProperty().bind(stage.widthProperty().subtract(2*BORDER));    

This label shows the text label of the currently selected radio button. Its style is customized with the setStyle() method. The label is enlarged to take to width of the stage minus the specified border.

ToggleGroup tg =  new ToggleGroup();
tg.selectedToggleProperty().addListener(new MyToggleListener());

A ToggleGroup is created and a listener is added to its selectedToggleProperty.

RadioButton rb1 = new RadioButton("Easy");

A RadioButton control is created.

rb1.setToggleGroup(tg);

The setToggleGroup() method sets the radio button to the toggle group.

rb1.setSelected(true);

The setSelected() selects the radio button.

private class MyToggleListener implements ChangeListener<Toggle> {

    @Override
    public void changed(ObservableValue<? extends Toggle> observable, 
            Toggle oldValue, Toggle newValue) {
        
        RadioButton rb = (RadioButton) newValue;
        String txt = rb.getText();
        lbl2.setText(txt);
    }
}

Inside the listener object, we get the radio button's text label with the getText() method and set it to the label using the setText() method.

RadioButton
Figure: RadioButton

TabPane

TabPane is a control that allows switching between a group of Tabs. Only one tab is visible at a time. Tabs in a TabPane can be positioned at any of the four side of the window. The default side is the top side.

TabPaneEx.java
package com.zetcode;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 * ZetCode JavaFX tutorial
 *
 * This program presents the TabPane control.
 *
 * Author: Jan Bodnar 
 * Website: zetcode.com 
 * Last modified: June 2015
 */

public class TabPaneEx extends Application {

    @Override
    public void start(Stage stage) {

        initUI(stage);
    }

    private void initUI(Stage stage) {

        StackPane root = new StackPane();

        TabPane tabPane = new TabPane();
        
        Tab tab1 = new Tab();
        tab1.setText("Rectangle");
        tab1.setContent(new Rectangle(100, 100, Color.LIGHTSTEELBLUE));
        
        Tab tab2 = new Tab();
        tab2.setText("Line");
        tab2.setContent(new Line(0, 0, 100, 100));  
        
        Tab tab3 = new Tab();
        tab3.setText("Circle");
        tab3.setContent(new Circle(0, 0, 50));         
        
        tabPane.getSelectionModel().select(1);
        tabPane.getTabs().addAll(tab1, tab2, tab3);
        
        root.getChildren().add(tabPane);

        Scene scene = new Scene(root, 300, 250);

        stage.setTitle("TabPane");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

The example contains a TabPane control with three tabs. Each tab contains a geometric shape. The second tab is selected when the application starts.

TabPane tabPane = new TabPane();

A TabPane control is created.

Tab tab1 = new Tab();
tab1.setText("Rectangle");
tab1.setContent(new Rectangle(100, 100, Color.LIGHTSTEELBLUE));

A Tab is created. Its text label is set with the setText() method. The content is set with the setContent() method.

tabPane.getSelectionModel().select(1);

The TabPane's selection model handles the selection of tabs. The model's select() method selects the second tab.

tabPane.getTabs().addAll(tab1, tab2, tab3);

The tabs are inserted into the tab pane. The internal list of tabs is retrieved with the getTabs() method.

TabPane
Figure: TabPane

In this chapter, we have continued covering basic JavaFX controls.