You are currently viewing TextField Autocompletion in JavaFX using ControlsFX

TextField Autocompletion in JavaFX using ControlsFX

TextField autocompletion is a convenient feature that enhances user experience by providing suggestions or predictions as users type into a text field. JavaFX is a powerful framework for building rich desktop applications, and ControlsFX is a library that extends the capabilities of JavaFX. In this article, we will explore how to implement TextField autocompletion using ControlsFX in a JavaFX application.

Setting Up ControlsFX

Before we begin, make sure you have added the ControlsFX library to your JavaFX project. You can download the ControlsFX library from the official GitHub repository or include it as a dependency using a build tool like Maven or Gradle.

You also need to add the following VM option to your runtime command line:

--add-exports javafx.base/com.sun.javafx.event=ALL-UNNAMED

Basic Autocompletion

ControlsFX provides a convenient API to bind autocompletion to a TextField. Let’s start with the basic usage of autocompletion using a list of possible suggestions.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.controlsfx.control.textfield.TextFields;

import java.util.Arrays;
import java.util.List;

public class Main extends Application {

    private final BorderPane parent = new BorderPane();

    @Override
    public void init() throws Exception {
        super.init();

        // Build the user interface
        this.buildUI();

    }

    private void buildUI() {

        // Create the TextField
        TextField textField = new TextField();

        // Set the TextField width to 300.0 pixels
        textField.setMaxWidth(300.0);

        // A list of possible suggestions
        List<String> possibleSuggestions = Arrays.asList(
                "C", "C#", "C++", "F#", "GoLang",
                "Dart", "Java", "JavaScript", "Kotlin", "PHP",
                "Python", "R", "Swift", "Visual Basic .NET"
        );


        // Bind autocompletion to the TextField
        TextFields.bindAutoCompletion(textField, possibleSuggestions);

        // Add the TextField to the center of the BorderPane
        this.parent.setCenter(textField);

    }

    @Override
    public void start(Stage stage) throws Exception {

        // Setup and display the stage
        this.setupStage(stage);

    }

    private void setupStage(Stage stage) {

        // Create a scene with the BorderPane as the root
        Scene scene = new Scene(this.parent, 640, 480);

        // Set the scene for the stage
        stage.setScene(scene);

        // Set the stage title
        stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");

        // Center the stage on the screen
        stage.centerOnScreen();

        // Display the stage
        stage.show();

    }

}

In this example, we create a TextField and a list of possible suggestions. The TextFields.bindAutoCompletion method binds autocompletion to the TextField using the list of suggestions. As the user types in the TextField, the autocompletion feature will provide suggestions from the list.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.controlsfx.control.textfield.TextFields;

import java.util.Arrays;
import java.util.List;

public class Main extends Application {

    private final BorderPane parent = new BorderPane();

    @Override
    public void init() throws Exception {
        super.init();

        // Build the user interface
        this.buildUI();

    }

    private void buildUI() {

        // Create the TextField
        TextField textField = new TextField();

        // Set the TextField width to 300.0 pixels
        textField.setMaxWidth(300.0);

        // A list of possible suggestions
        List<String> possibleSuggestions = Arrays.asList(
                "C", "C#", "C++", "F#", "GoLang",
                "Dart", "Java", "JavaScript", "Kotlin", "PHP",
                "Python", "R", "Swift", "Visual Basic .NET"
        );


        // Bind autocompletion to the TextField
        TextFields.bindAutoCompletion(textField, possibleSuggestions);

        // Add the TextField to the center of the BorderPane
        this.parent.setCenter(textField);

    }

    @Override
    public void start(Stage stage) throws Exception {

        // Setup and display the stage
        this.setupStage(stage);

    }

    private void setupStage(Stage stage) {

        // Create a scene with the BorderPane as the root
        Scene scene = new Scene(this.parent, 640, 480);

        // Set the scene for the stage
        stage.setScene(scene);

        // Set the stage title
        stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");

        // Center the stage on the screen
        stage.centerOnScreen();

        // Display the stage
        stage.show();

    }

}

Advanced Autocompletion with Custom Provider

ControlsFX also allows you to provide a custom suggestion provider using a callback. This is useful when you need to retrieve suggestions from a data source or perform custom filtering.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import org.controlsfx.control.textfield.TextFields;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class Main extends Application {

    private final BorderPane parent = new BorderPane();

    @Override
    public void init() throws Exception {
        super.init();

        // Build the user interface
        this.buildUI();

    }

    private void buildUI() {

        // Create the TextField
        TextField textField = new TextField();

        // Set the TextField width to 300.0 pixels
        textField.setMaxWidth(300.0);

        // A list of possible suggestions
        List<String> possibleSuggestions = Arrays.asList(
                "C", "C#", "C++", "F#", "GoLang",
                "Dart", "Java", "JavaScript", "Kotlin", "PHP",
                "Python", "R", "Swift", "Visual Basic .NET"
        );

        Callback<AutoCompletionBinding.ISuggestionRequest, Collection<String>> suggestionProvider =
                request -> possibleSuggestions.stream()
                        .filter(suggestion -> suggestion.toLowerCase().contains(request.getUserText().toLowerCase()))
                        .toList();

        // Bind autocompletion to the TextField using the custom suggestion provider
        TextFields.bindAutoCompletion(textField, suggestionProvider);

        // Add the TextField to the center of the BorderPane
        this.parent.setCenter(textField);

    }

    @Override
    public void start(Stage stage) throws Exception {

        // Setup and display the stage
        this.setupStage(stage);

    }

    private void setupStage(Stage stage) {

        // Create a scene with the BorderPane as the root
        Scene scene = new Scene(this.parent, 640, 480);

        // Set the scene for the stage
        stage.setScene(scene);

        // Set the stage title
        stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");

        // Center the stage on the screen
        stage.centerOnScreen();

        // Display the stage
        stage.show();

    }

}

In this example, we create a custom suggestion provider using a Callback. The provider filters suggestions based on the user’s input. This allows for more advanced autocompletion behavior, such as retrieving suggestions from a remote server or a database.

TextField Autocompletion in JavaFX using ControlsFX

Advanced Autocompletion with Custom Converter

A converter is essential when you want to display suggestions in a user-friendly manner while retaining the actual value associated with the suggestion.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import org.controlsfx.control.textfield.TextFields;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class Main extends Application {

    private final BorderPane parent = new BorderPane();

    @Override
    public void init() throws Exception {
        super.init();

        // Build the user interface
        this.buildUI();

    }

    private void buildUI() {

        // Create the TextField
        TextField textField = new TextField();

        // Set the TextField width to 300.0 pixels
        textField.setMaxWidth(300.0);

        // A list of possible suggestions
        List<Language> possibleSuggestions = Arrays.asList(
            new Language("C"), new Language("C#"), new Language("C++"),  new Language("F#"),
            new Language("GoLang"), new Language("Dart") , new Language("Java"),  new Language("R"),
            new Language("JavaScript"), new Language("Kotlin"), new Language("PHP"),
            new Language("Python"), new Language("Swift"), new Language("Visual Basic .NET")
        );

        Callback<AutoCompletionBinding.ISuggestionRequest, Collection<Language>> suggestionProvider =
                request -> possibleSuggestions.stream()
                        .filter(suggestion -> suggestion.name().toLowerCase().contains(request.getUserText().toLowerCase()))
                        .toList();

        StringConverter<Language> converter = new StringConverter<>() {

            @Override
            public String toString(Language language) {

                // Convert suggestion to display text
                return language.name();

            }

            @Override
            public Language fromString(String name) {

                // Convert selected display text back to suggestion
                return possibleSuggestions.stream()
                        .filter(suggestion -> suggestion.name().equalsIgnoreCase(name))
                        .findFirst().orElse(null);
                
            }

        };

        // Bind autocompletion to the TextField using the custom suggestion provider, and converter
        TextFields.bindAutoCompletion(textField, suggestionProvider, converter);

        // Add the TextField to the center of the BorderPane
        this.parent.setCenter(textField);

    }

    @Override
    public void start(Stage stage) throws Exception {

        // Setup and display the stage
        this.setupStage(stage);

    }

    private void setupStage(Stage stage) {

        // Create a scene with the BorderPane as the root
        Scene scene = new Scene(this.parent, 640, 480);

        // Set the scene for the stage
        stage.setScene(scene);

        // Set the stage title
        stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");

        // Center the stage on the screen
        stage.centerOnScreen();

        // Display the stage
        stage.show();

    }

    record Language(String name) {}

}

The toString method of the converter determines how the suggestions are displayed in the autocompletion popup. Customize it to format the suggestions as you desire. The fromString method converts the selected display text back to the actual suggestion value. This is particularly useful if the suggestions and their displayed forms are different.

TextField Autocompletion in JavaFX using ControlsFX

Conclusion

Adding autocompletion to TextField components in your JavaFX applications can greatly enhance the user experience by making data entry faster and more accurate. The ControlsFX library provides a simple and powerful way to implement autocompletion using various methods, including basic suggestions, custom providers, and string converters. By incorporating autocompletion, you can create more intuitive and user-friendly applications. Remember to check the ControlsFX TextFields documentation for more.

I hope you found this code informative and useful. If you would like to receive more content, please consider subscribing to our newsletter!

Leave a Reply