Spell checker

This documents shows how to configure languages for spell checking, add or remove words from a custom dictionary, disable spell checking, and more.

By default, spell checking is enabled. The spell checker analyzes text and highlights all misspelled words. Spell checkers are associated with the profiles. To access and configure the spell checker for the specific Profile use the SpellChecker class:

SpellChecker spellChecker = profile.spellChecker();
val spellChecker = profile.spellChecker()

Another option is to use the Engine.spellChecker() method which returns the instance of the SpellChecker class associated with the default profile.

Unlike Windows and Linux, on macOS, Chromium uses spell checking settings and dictionaries provided by the OS. Hence, SpellChecker service behaves differently on macOS as you will see further in this guide.

Adding languages

The spell checker can check texts in different languages on a single web page. On Windows and Linux, one can configure the languages by the SpellChecker.addLanguage(Language) method. Chromium downloads the dictionary files automatically from its servers and stores them in the user data directory.

On macOS, this method only checks if the necessary dictionaries are available in the operating system.

Regardless of the OS, this method throws LanguageNotAvailableException if Chromium can’t find the necessary dictionary.

For example:

spellChecker.addLanguage(Language.GERMAN);
spellChecker.addLanguage(Language.of("en", "au"));
spellChecker.addLanguage(Language.GERMAN)
spellChecker.addLanguage(Language.of("en", "au"))

The spelling languages configuration and dictionaries are stored in the user data. So, if you configure Engine to use a specific User Data directory, then the Engine will remember the language settings and restore them the next time you create it and automatically load corresponding dictionaries.

Removing languages

On Windows and Linux, use the SpellChecker.removeLanguage(Language) method to stop spell checking for a particular language:

spellChecker.removeLanguage(Language.GERMAN);
spellChecker.removeLanguage(Language.GERMAN)

On macOS, this method does nothing.

Custom dictionary

The spell checker supports the custom dictionary. You can access a custom dictionary using the SpellChecker.getCustomDictionary() method.

For example:

Dictionary dictionary = spellChecker.customDictionary();
val dictionary = spellChecker.customDictionary()

Adding a word

You can add words to the custom dictionary using the add(String) method:

boolean success = dictionary.add("John");
val success = dictionary.add("John")

The word must be UTF-8, between 1 and 99 bytes long, and without leading or trailing ASCII whitespace.

Removing a word

To remove a word from the custom dictionary please use the remove(String) method:

boolean success = dictionary.remove("John");
val success = dictionary.remove("John")

Disabling spell checking

By default, spell checking is enabled. To disable it use the following code:

spellChecker.disable();
spellChecker.disable()

Context menu

You can display a context menu with suggestions when a user right clicks the highlighted misspelled word on the loaded web page. Use the ShowContextMenuCallback callback to display a context menu with suggestions and a menu item that allows adding the misspelled word to the custom dictionary.

Swing

The following example demonstrates how to create and display Swing context menu with suggestions and the Add to Dictionary menu item. Using this context menu, you can replace the misspelled word with one of the suggestions or add it to the custom dictionary.

browser.set(ShowContextMenuCallback.class, (params, tell) ->
        SwingUtilities.invokeLater(() -> {
            JPopupMenu popupMenu = new JPopupMenu();
            popupMenu.addPopupMenuListener(new PopupMenuListener() {
                ...
                @Override
                public void popupMenuCanceled(PopupMenuEvent e) {
                    tell.close();
                }
            });

            // Add the suggestions menu items.
            SpellCheckMenu spellCheckMenu = params.spellCheckMenu();
            List<String> suggestions = spellCheckMenu.dictionarySuggestions();
            suggestions.forEach(suggestion -> {
                JMenuItem menuItem = new JMenuItem(suggestion);
                menuItem.addActionListener(e -> {
                    browser.replaceMisspelledWord(suggestion);
                    tell.close();
                });
                popupMenu.add(menuItem);
            });

            // Add menu separator if necessary.
            if (!suggestions.isEmpty()) {
                popupMenu.addSeparator();
            }

            // Add the "Add to Dictionary" menu item.
            JMenuItem addToDictionary = new JMenuItem(
                    spellCheckMenu.addToDictionaryMenuItemText());
            addToDictionary.addActionListener(e -> {
                Dictionary dictionary =
                        engine.spellChecker().customDictionary();
                dictionary.add(spellCheckMenu.misspelledWord());
                tell.close();
            });
            popupMenu.add(addToDictionary);

            // Display context menu at specified location.
            Point location = params.location();
            popupMenu.show(view, location.x(), location.y());
        }));
browser.set(ShowContextMenuCallback::class.java, ShowContextMenuCallback { params, tell ->
    SwingUtilities.invokeLater {
        val popupMenu = JPopupMenu()
        popupMenu.addPopupMenuListener(object: PopupMenuListener {
            ...
            override fun popupMenuCanceled(e: PopupMenuEvent) {
                tell.close()
            }
        })

        // Add the suggestions menu items.
        val spellCheckMenu = params.spellCheckMenu()
        val suggestions = spellCheckMenu.dictionarySuggestions()
        suggestions.forEach { suggestion ->
            val menuItem = JMenuItem(suggestion)
            menuItem.addActionListener {
                browser.replaceMisspelledWord(suggestion)
                tell.close()
            }
            popupMenu.add(menuItem)
        }

        // Add menu separator if necessary.
        if (!suggestions.isEmpty()) {
            popupMenu.addSeparator()
        }

        // Add the "Add to Dictionary" menu item.
        val addToDictionary = JMenuItem(spellCheckMenu.addToDictionaryMenuItemText())
        addToDictionary.addActionListener {
            val dictionary = engine.spellChecker().customDictionary()
            dictionary.add(spellCheckMenu.misspelledWord())
            tell.close()
        }
        popupMenu.add(addToDictionary)

        // Display context menu at specified location.
        val location = params.location()
        popupMenu.show(view, location.x(), location.y())
    }
})

If you right-click on a misspelled word, the following context menu will be displayed: Swing Spell Checker Context Menu

JavaFX

The following example demonstrates how to create and display a JavaFX context menu with suggestions and the Add to Dictionary menu item. Using this context menu, you can replace the misspelled word with one of the suggestions or add it to the custom dictionary.

browser.set(ShowContextMenuCallback.class, (params, tell) ->
        Platform.runLater(() -> {
            ContextMenu contextMenu = new ContextMenu();
            contextMenu.setAutoHide(true);
            contextMenu.setOnHidden(event -> {
                if (!tell.isClosed()) {
                    tell.close();
                }
            });
            view.setOnMousePressed(event -> {
                if (contextMenu.isShowing()) {
                    contextMenu.hide();
                }
            });
            // Add the suggestions menu items.
            SpellCheckMenu spellCheckMenu = params.spellCheckMenu();
            List<String> suggestions = spellCheckMenu.dictionarySuggestions();
            suggestions.forEach(suggestion -> {
                MenuItem item = new MenuItem(suggestion);
                item.setOnAction(event -> {
                    browser.replaceMisspelledWord(suggestion);
                    tell.close();
                });
                contextMenu.getItems().add(item);
            });

            // Add menu separator if necessary.
            if (!suggestions.isEmpty()) {
                contextMenu.getItems().add(new SeparatorMenuItem());
            }

            // Add the "Add to Dictionary" menu item.
            MenuItem addToDictionary = new MenuItem(
                    spellCheckMenu.addToDictionaryMenuItemText());
            addToDictionary.setOnAction(event -> {
                SpellChecker spellChecker = engine.spellChecker();
                Dictionary dictionary = spellChecker.customDictionary();
                dictionary.add(spellCheckMenu.misspelledWord());
                tell.close();
            });
            contextMenu.getItems().add(addToDictionary);

            // Display context menu at specified location on screen.
            Point location = params.location();
            Point2D locationOnScreen = 
                    view.localToScreen(location.x(), location.y());
            contextMenu.show(view, locationOnScreen.getX(), 
                    locationOnScreen.getY());
        }));
browser.set(ShowContextMenuCallback::class.java, ShowContextMenuCallback { params, tell ->
    Platform.runLater {
        val contextMenu = ContextMenu()
        contextMenu.isAutoHide = true
        contextMenu.setOnHidden {
            if (!tell.isClosed) {
                tell.close()
            }
        })
        view.setOnMousePressed {
            if (contextMenu.isShowing) {
                contextMenu.hide()
            }
        }
        // Add the suggestions menu items.
        val spellCheckMenu = params.spellCheckMenu()
        val suggestions = spellCheckMenu.dictionarySuggestions()
        suggestions.forEach { suggestion ->
            val item = MenuItem(suggestion)
            item.setOnAction {
                browser.replaceMisspelledWord(suggestion)
                tell.close()
            }
            contextMenu.items.add(item)
        }

        // Add menu separator if necessary.
        if (!suggestions.isEmpty()) {
            contextMenu.items.add(SeparatorMenuItem())
        }

        // Add the "Add to Dictionary" menu item.
        val addToDictionary = MenuItem(spellCheckMenu.addToDictionaryMenuItemText())
        addToDictionary.setOnAction {
            val spellChecker = engine.spellChecker()
            val dictionary = spellChecker.customDictionary()
            dictionary.add(spellCheckMenu.misspelledWord())
            tell.close()
        }
        contextMenu.items.add(addToDictionary)

        // Display context menu at specified location on screen.
        val location = params.location()
        val locationOnScreen = view.localToScreen(location.x(), location.y())
        contextMenu.show(view, locationOnScreen.getX(), locationOnScreen.getY())
    }
})

If you right click on a misspelled word, the following context menu will be displayed: JavaFX Spell Checker Context Menu

Spell checker events

When a text field or text area on the loaded web page receives focus, the spell checker automatically checks the text and highlights the misspelled words. To get notifications when the text has been checked please use the SpellCheckCompleted event.

For example:

browser.on(SpellCheckCompleted.class, event -> {
    // The text that has been checked.
    String text = event.checkedText();
    // The list of the spell checking results.
    event.results().forEach(spellCheckingResult -> {
        // The location of the first symbol in the mis-spelled word 
        // in the checked text that is considered as mis-spelled 
        // by the spell checker.
        int location = spellCheckingResult.location();
        // The length of the mis-spelled word in the checked text
        int length = spellCheckingResult.length();
    });
});
browser.on(SpellCheckCompleted::class.java) { event -> 
    // The text that has been checked.
    val text = event.checkedText()
    // The list of the spell checking results.
    event.results().forEach { spellCheckingResult -> 
        // The location of the first symbol in the mis-spelled word 
        // in the checked text that is considered as mis-spelled 
        // by the spell checker.
        val location = spellCheckingResult.location()
        // The length of the mis-spelled word in the checked text
        val length = spellCheckingResult.length()
    }
}
Go Top