Hi looking if a library exists that pretty has a control that is a “textarea” that has a built in spell checker like that on front page of languagetool.
I looked into trying to code me own using RichTextFX, as javaFX TextArea does not support multiple styles.
RichTextFx doesn’t really have a forum so i thought I bring it up here.
Code so far:
package application;
import java.io.IOException;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.StyleClassedTextArea;
import org.fxmisc.richtext.model.StyleSpans;
import org.fxmisc.richtext.model.StyleSpansBuilder;
import org.languagetool.JLanguageTool;
import org.languagetool.language.AmericanEnglish;
import org.languagetool.rules.RuleMatch;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class SpellChecking extends Application {
static List<String> misspells = new ArrayList<>();
static List<RuleMatch> matches = new ArrayList<>();
StyleClassedTextArea textArea = new StyleClassedTextArea();
JLanguageTool langTool = new JLanguageTool(new AmericanEnglish());
String input = "this is a sentence with soeme errors";
@Override
public void start(Stage primaryStage) throws IOException {
textArea.setWrapText(true);
textArea.insertText(0, input);
Scene scene = new Scene(new VirtualizedScrollPane<>(textArea), 600, 400);
scene.getStylesheets().add(getClass().getResource("spellchecking.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("Spell Checking Demo");
primaryStage.show();
checkSpelling();
}
private void checkSpelling() throws IOException {
matches = langTool.check(input);
matches.forEach(match -> {
int start = match.getFromPos();
int end = match.getToPos();
misspells.add(input.substring(start, end));
});
textArea.setStyleSpans(0, computeHighlighting(textArea.getText()));
}
private static StyleSpans<Collection<String>> computeHighlighting(String text) {
StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
int lastIndex = wb.first();
int lastKwEnd = 0;
while(lastIndex != BreakIterator.DONE) {
int firstIndex = lastIndex;
lastIndex = wb.next();
if (lastIndex != BreakIterator.DONE && Character.isLetterOrDigit(text.charAt(firstIndex))) {
String word = text.substring(firstIndex, lastIndex).toLowerCase();
if (misspells.contains(word)) {
spansBuilder.add(Collections.emptyList(), firstIndex - lastKwEnd);
spansBuilder.add(Collections.singleton("underlined"), lastIndex - firstIndex);
lastKwEnd = lastIndex;
}
}
}
spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
return spansBuilder.create();
}
public static void main(String[] args) {
launch(args);
}
}
spellchecking.css
.underlined {
-rtfx-background-color: #f0f0f0;
-rtfx-underline-color: red;
-rtfx-underline-dash-array: 2 2;
-rtfx-underline-width: 1;
-rtfx-underline-cap: butt;
}