Javafx 8 替换 textarea 中的文本并保持格式

Posted

技术标签:

【中文标题】Javafx 8 替换 textarea 中的文本并保持格式【英文标题】:Javafx 8 replace text in textarea and maintain formatting 【发布时间】:2020-03-23 09:15:25 【问题描述】:

我们正在尝试替换 TextArea 中拼写错误的单词,当单词位于文本行的末尾并且有回车时,进程失败,其他拼写错误的单词将按预期替换

示例文本 好了,我们准备好生产拼写测试了吗? 但我担心字典是限制因素?

这是上面 lin 中的回车测试

连字符测试慢动作,不要忘记日期

就在拼写错误的单词 abov 之后,我们在 ArrayList 中有一个回车,文本看起来像这样

in, the, lin, 以上

因为这个拼写错误的单词后面没有逗号,所以替换代码也去掉了拼写错误的单词 Hypenated,因为替换代码将 "abov & Hypenated" 视为在同一个索引中

运行替换代码的结果

这里是上面 lin 中的回车测试 test

如果这行代码strArray = line.split(" "); 更改为此 strArray = line.split("\\s"); 问题消失了,但 TextArea 中的格式也会删除所有回车符,这不是预期的结果

问题是如何处理格式问题并仍然替换拼写错误的单词? 旁注仅当拼写错误的单词位于句子的末尾时才会发生这种情况,例如拼写错误的单词 "lin" 将根据需要替换 该项目的代码行数过多,因此我们仅发布导致结果不理想的代码 我们尝试仅使用 String[ ] 数组,但几乎没有成功

@FXML
private void onReplace()

    if(txtReplacementWord.getText().isEmpty())
        txtMessage.setText("No Replacement Word");
        return;
    

    cboMisspelledWord.getItems().remove(txtWordToReplace.getText());
    // Line Above Removes misspelled word from cboMisspelledWord 
    // ==========================================================
    String line = txaDiaryEntry.getText();
    strArray = line.split(" ");
    List<String> list = new ArrayList<>(Arrays.asList(strArray));
    for (int R = 0; R < list.size(); R++) 
        if(list.get(R).contains(txtWordToReplace.getText()))
            theIndex = R;
            System.out.println("## dex "+theIndex);//For testing
        
    
    System.out.println("list "+list);//For testing

    list.remove(theIndex);
    list.add(theIndex,txtReplacementWord.getText());

    sb = new StringBuilder(); 
for (String addWord : list) 
    sb.append(addWord);
    sb.append(" ");


    txaDiaryEntry.setText(sb.toString()); 
    txtMessage.setText("");
    txtReplacementWord.setText("");
    txtWordToReplace.setText("");
    cboCorrectSpelling.getItems().clear(); 
    cboMisspelledWord.requestFocus();

    // Code above replaces misspelled word with correct spelling in TextArea
    // =====================================================================
if(cboMisspelledWord.getItems().isEmpty())
    onCheckSpelling();
 

【问题讨论】:

我们在我发布的代码中看到了您的评论,并试图解决此问题,但这超出了我的专业水平!将在我的拼字游戏应用程序中使用它 f*** 生成了一些很棒的代码,是的,在这种情况下,=非空白序列来自新的搜索引擎的地方 【参考方案1】:

不要使用split。这样,您就可以丢失有关单词之间内容的信息。而是创建一个Pattern 匹配的单词,并确保在匹配之间也复制子字符串。这样您就不会在那里丢失任何信息。

为简单起见,以下示例将替换逻辑替换为简单地在 Map 中查找替换,但应该足以演示该方法:

public void start(Stage primaryStage) throws Exception 
    TextArea textArea = new TextArea(
            "Well are we reddy for production the spell test is here but I fear the dictionary is the limiting factor ?\n"
                    + "\n" + "Here is the carriage return test in the lin abov\n" + "\n"
                    + "Hypenated words test slow-motion and lets not forget the date");

    Map<String, String> replacements = new HashMap<>();
    replacements.put("lin", "line");
    replacements.put("abov", "above");

    Pattern pattern = Pattern.compile("\\S+"); // pattern matching words (=non-whitespace sequences in this case)
    Button button = new Button("Replace");
    button.setOnAction(evt -> 
        String text = textArea.getText();
        StringBuilder sb = new StringBuilder();
        Matcher matcher = pattern.matcher(text);
        int lastEnd = 0;
        while (matcher.find()) 
            int startIndex = matcher.start();
            if (startIndex > lastEnd) 
                // add missing whitespace chars
                sb.append(text.substring(lastEnd, startIndex));
            

            // replace text, if necessary
            String group = matcher.group();
            String result = replacements.get(group);
            sb.append(result == null ? group : result);

            lastEnd = matcher.end();
        
        sb.append(text.substring(lastEnd));
        textArea.setText(sb.toString());
    );

    final Scene scene = new Scene(new VBox(textArea, button));

    primaryStage.setScene(scene);
    primaryStage.show();

【讨论】:

效果很好删除了按钮部分和 OnActionEvent 中的代码我仍在尝试围绕 Pattern.compile)"\\S+") 行代码猜测我需要阅读关于否空格匹配你的答案对我来说意义重大谢谢 字符类在 Pattern 的 javadoc 中定义:docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…(\S\s 的补码,+ 仅表示“其中的正数”在这种情况下有效,因为匹配器是贪婪的)。

以上是关于Javafx 8 替换 textarea 中的文本并保持格式的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 TextArea (JavaFX) 中的文本选择?

“textarea”中的 JavaFX 8 计数行

Javafx 不接受文本字段的 textArea 中的其他字体或语言

JavaFX:TextArea 光标移回新文本的第一行

JavaFX - TextArea 的掩码文本

如何知道用户在 JavaFX TextArea 中选择了哪个文本字符串