Vous êtes ici

My first JavaFX application - 2 - First UI

javaPrevious article

It's now time to write some code. I'll do what I usually do when I have to develop an application with a GUI: I design the UI before anything else.

So, firstly, let's list the functions the UI has to provide:

  • let the user choose a serial port (speed and byte format are fixed by the device)
  • let the user send some frames to the device, after having set up some parameters depending on the frame. Our first version will only send one predetermined frame
  • display received frames

Now that we know what we want to do, let's implement it! After some additional reading and tests, I end up with following architecture and code:

  • GUI is designed using Scene Builder. Resulting FXML code is in file UserInterface.fxml. This UI is based on following elements:
    • a label and a text field (not used in current code)
    • a button
    • a list view
  • the controller associated to the UI is implemented by UserInterfaceController class
  • RecFrames class is used by the controller to handle data displayed by the list view
  • Main class starts the application

Contents of each source file is below:


<?xml version="1.0" encoding="UTF-8"?>

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

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
	prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1"
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <Label text="Enter serial port device:" />
            <TextField fx:id="serialPortTF" GridPane.columnIndex="1" />
            <Button fx:id="sendReadCommandBtn" mnemonicParsing="false" text="Send READ command" GridPane.rowIndex="1" />
      <ListView fx:id="recFramesLV" prefHeight="319.0" prefWidth="600.0" />


package com.monblocnotes.devicecontroller;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;

public class UserInterfaceController implements Initializable {
	@FXML private TextField serialPortTF;
	@FXML private Button sendReadCommandBtn;
	@FXML private ListView<String> recFramesLV;

	private ObservableList<String> lines;
	private RecFrames recFrames;
	private int num;

	public void initialize(URL location, ResourceBundle resources) {

		sendReadCommandBtn.setOnAction(new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {


		lines = FXCollections.observableArrayList();
		recFrames = new RecFrames(lines);
		num = 0;


	public void addFrame() {

		String str = "frame " + num;




package com.monblocnotes.devicecontroller;

import javafx.collections.ObservableList;

public class RecFrames {
	// Maximum number of displayed frames.
	private final static int MAX_NB_FRAMES = 3;
	private ObservableList<String> frameList;

	 * @param frameList
	public RecFrames(ObservableList<String> frameList) {
		this.frameList = frameList;
	 * @param frame
	public void addFrame(String frame) {
		int s = frameList.size();
		if (s >= MAX_NB_FRAMES) {
			// Remove oldest element.
			frameList.remove(s - 1);
		// Add new element.
		frameList.add(0, frame);



package com.monblocnotes.devicecontroller;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main extends Application {
	public void start(Stage primaryStage) {
		try {
			Parent root = FXMLLoader.load(getClass().getResource("UserInterface.fxml"));
			Scene scene = new Scene(root,400,400);
		} catch(Exception e) {
	 * @param args
	public static void main(String[] args) {

What happens when you run this program? The window below is displayed:

version1EmptyWindowQuite ugly, isn't it? Embarassed But it does what I want with this first version, i.e. intercepting clicks on button, and displaying most recent strings in list view. More precisely, every time you click on the Send READ command button, a new string is generated and displayed. Most recent string is displayed at top, and only latest three strings are displayed:


Why this name for the button? Well, you'll discover later. 

Next article