Javafx 8 replace text in textarea and maintain formatting

我怕爱的太早我们不能终老 提交于 2019-12-11 16:24:54

问题


We are trying to replace misspelled words in the TextArea and when the word is at the end of a line of text and has a carriage return the process is failing other misspelled words are replace as expected

Example Text
Well are we reddy for production the spell test is here but I fear the dictionary is the limiting factor ?

Here is the carriage return test in the lin abov

Hypenated words test slow-motion and lets not forget the date

Just after the misspelled word abov we have a carriage return in the ArrayList the text looks like this

in, the, lin, abov

Because this misspelled word has no comma after it the replacement code also takes out the misspelled word Hypenated because the replacement code sees "abov & Hypenated" as being at the same Index

Result of running the replacement code

Here is the carriage return test in the lin above words test

If this line of code strArray = line.split(" ");
is changed to this strArray = line.split("\\s"); the issue goes away but so does the formatting in the TextArea all the carriage returns are deleted which is not a desired outcome

The question is how to deal with the formatting issue and still replace the misspelled words?
Side note this only happens when the misspelled word is at the end of a sentences for example the misspelled word "lin" will be replaced as desired
We have an excessive number of lines of code for this project so we are only posting the code that is causing the unsatisfactory results
We tried using just a String[ ] array with little or no success

@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();
} 
}

回答1:


Don't use split. This way you loose the info about the content between the words. Instead create a Pattern matching words and make sure to also copy the substrings between matches. This way you don't loose any info there.

The following example replaces the replacement logic with simply looking for replacements in a Map for simplicity, but it should be sufficient to demonstrate the approach:

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();
}


来源:https://stackoverflow.com/questions/59076572/javafx-8-replace-text-in-textarea-and-maintain-formatting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!