如何使用RichTextFx的CodeArea高亮自定义词典中的指定词汇
别担心,这个需求完全能实现!RichTextFx的CodeArea本身就支持自定义高亮规则,刚好能满足你用自定义词典给特定词汇上色的需求,我给你一步步拆解实现方法:
核心思路
RichTextFx的CodeArea继承自StyleClassedTextArea,它允许你通过正则匹配+样式绑定的方式给文本片段添加自定义样式。我们只需要把你的自定义词典转换成一个能匹配所有目标词汇的正则表达式,再把这个正则和你想要的颜色样式关联起来就行。
具体实现步骤
1. 准备自定义词典和样式
首先,你需要定义目标词汇列表,还有对应的CSS样式(用来设置红色)。
比如在Java代码里:
// 你的自定义词汇列表 ArrayList<String> customWords = new ArrayList<>(Arrays.asList("hello", "world", "javafx", "richtextfx")); // 给CodeArea加载CSS样式(也可以写在单独的.css文件里) codeArea.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
然后在styles.css里定义高亮样式:
.red-highlight { -fx-fill: red; -fx-font-weight: bold; /* 可选,加粗突出显示 */ }
2. 把词典转换成匹配正则
为了精准匹配整个词汇(避免把"helloworld"里的"hello"也错误高亮),我们需要用单词边界构建正则。同时要转义词汇里的特殊正则字符(比如.、*这些),避免正则语法出错。
// 转义每个词汇里的特殊正则字符 List<String> escapedWords = customWords.stream() .map(Pattern::quote) .collect(Collectors.toList()); // 构建匹配所有词汇的正则,用\b确保匹配完整单词 String regex = "\\b(" + String.join("|", escapedWords) + ")\\b"; Pattern highlightPattern = Pattern.compile(regex);
3. 给CodeArea绑定高亮规则
最后把这个正则和我们定义的样式类绑定到CodeArea的高亮规则里:
// 添加高亮规则:匹配正则的文本应用red-highlight样式 codeArea.getHighlightingPatterns().add( new HighlightingPattern(highlightPattern, "red-highlight") );
注意事项
- 如果你的词汇里包含非单词字符(比如
user-name、my_var),\b单词边界可能不生效,这时候可以把正则改成(?<!\\w)和(?!\\w)来匹配非单词前后缀:String regex = "(?<!\\w)(" + String.join("|", escapedWords) + ")(?!\\w)"; - 如果你的词典是动态更新的(比如用户可以添加/删除词汇),你可以监听词典的变化,然后重新生成正则并更新高亮规则:
// 假设customWords是ObservableList customWords.addListener((ListChangeListener.Change<? extends String> change) -> { // 清除旧的高亮规则 codeArea.getHighlightingPatterns().removeIf(p -> p.getStyleClass().equals("red-highlight")); // 重新生成正则并添加新规则 List<String> escapedWords = customWords.stream().map(Pattern::quote).collect(Collectors.toList()); String regex = "\\b(" + String.join("|", escapedWords) + ")\\b"; codeArea.getHighlightingPatterns().add(new HighlightingPattern(Pattern.compile(regex), "red-highlight")); // 触发重新高亮 codeArea.requestHighlighting(); });
这样就能实现你想要的效果,把ArrayList里的所有词汇都设置成红色显示在CodeArea里~
内容的提问来源于stack exchange,提问作者SkyCrafter




