必须自动突出显示从文本字段到文本区域的特定字符串

时间:2019-11-18 17:43:52

标签: java javafx

我现在想知道如何在文本区域内自动突出显示文本。我进行了进一步研究,找到了一种执行此操作的方法,但是我不确定用户输入搜索后它如何仍可以自动突出显示String。

enter image description here

注意:忽略单选按钮

这是我在单击搜索按钮时在动作事件中尝试的方法

 @FXML
 private void searchButton(ActionEvent actionEvent){
    String key = keyField.getText();
    String field = textField.getText();
    System.out.println(key);
    System.out.println(field);

        textField.getText();
        if (textField.getText().equals(key)) {
            textField.setStyle("-fx-highlight-fill: yellow; -fx-highlight-text-fill: black; -fx-font-size: 12px; ");
            textField.setEditable(false);
            textField.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent t) {
                    t.consume();
                }
            });

            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    textField.selectRange(13, 18);
                }
            });
        }

    ToggleGroup group = new ToggleGroup();
    rabinKarpp.setToggleGroup(group);
    kmp.setToggleGroup(group);
    naive.setToggleGroup(group);

    ArrayList indexes = new ArrayList();
    if (rabinKarpp.isSelected()){
        indexes = RabinKarp.process(field, key);
    }
    else if (kmp.isSelected()){
        indexes = KMPAlgo.process(field, key);
    }
    else if (naive.isSelected()){
        indexes = NaiveAlgo.process(field, key);
    }
    else if(!naive.isSelected() && !kmp.isSelected() && !rabinKarpp.isSelected()) {
        Alert alert = new Alert(Alert.AlertType.WARNING, "Select an algorithm first before proceeding.",ButtonType.OK);
        alert.showAndWait();
    }

}

期望的输出应该是“大家好”中的“你好”,但我仍然对如何做到这一点感到困惑。

编辑:

现在代码看起来像这样,但是高亮显示仍然不会令人遗憾。

@FXML     受保护的void searchButton(ActionEvent actionEvent){

    String key = keyField.getText();
    String field = textField.getText();
    System.out.println(key);
    System.out.println(field);

    ToggleGroup group = new ToggleGroup();
    rabinKarpp.setToggleGroup(group);
    kmp.setToggleGroup(group);
    naive.setToggleGroup(group);

    ArrayList indexes = new ArrayList();
    if (rabinKarpp.isSelected()){
        indexes = RabinKarp.process(field, key);
    }
    else if (kmp.isSelected()){
        indexes = KMPAlgo.process(field, key);
    }
    else if (naive.isSelected()){
        indexes = NaiveAlgo.process(field, key);
    }
    else if(!naive.isSelected() && !kmp.isSelected() && !rabinKarpp.isSelected()) {
        Alert alert = new Alert(Alert.AlertType.WARNING, "Select an algorithm first before proceeding.",ButtonType.OK);
        alert.showAndWait();
    }
}

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    List<List<Integer>> locations = new ArrayList();
    keyField.textProperty().addListener((o, oldValue, newValue) -> {
        Pattern pattern = Pattern.compile(newValue);
        Matcher matcher = pattern.matcher(textField.getText());

        locations.clear();
        if (newValue.isEmpty()) {
            // no highlighting for the empty search string
            textField.deselect();
        } else {
            int index = textField.getText().indexOf(newValue);
            if (index < 0) {
                // text not found
                textField.deselect();
            } else {
                while(matcher.find())
                {
                    List<Integer> tempList = new ArrayList<>();
                    tempList.add(matcher.start());
                    tempList.add(matcher.end());

                    locations.add(tempList);
                }
            }
        }
    });
    AtomicInteger currentIndex = new AtomicInteger(-1);
    downButton.setOnAction((t) -> {
        if(currentIndex.get() >= -1 && currentIndex.get() < locations.size() - 1)
        {
            textField.selectRange(locations.get(currentIndex.incrementAndGet()).get(0), locations.get(currentIndex.get()).get(1));
        }
    });

    upButton.setOnAction((t) -> {
        if(currentIndex.get() > 0 && currentIndex.get() <= locations.size())
        {
            textField.selectRange(locations.get(currentIndex.decrementAndGet()).get(0), locations.get(currentIndex.get()).get(1));
        }
    });
}

2 个答案:

答案 0 :(得分:3)

为此,只需监听text的{​​{1}}属性。请注意,您只能使用TextField选择单个范围。如果您需要突出显示多个事件,则可以使用TextArea,它是@Slaw建议的TextFlow方法。

rangeShape

@Override public void start(Stage stage) throws IOException { TextArea textArea = new TextArea(); VBox.setVgrow(textArea, Priority.ALWAYS); Random random = new Random(); for (int l = 0; l < 10; l++) { for (int i = 0; i < 300; i++) { textArea.appendText(Character.toString('a' + random.nextInt('z'- 'a' + 1))); } textArea.appendText("\n"); } TextField textField = new TextField(); textField.textProperty().addListener((o, oldValue, newValue) -> { if (newValue.isEmpty()) { // no highlighting for the empty search string textArea.deselect(); } else { int index = textArea.getText().indexOf(newValue); if (index < 0) { // text not found textArea.deselect(); } else { // select first occurance textArea.selectRange(index, index + newValue.length()); } } }); Scene scene = new Scene(new VBox(textArea, textField)); stage.setScene(scene); stage.show(); } 方法中使用fxml像这样注册侦听器的合适位置。

答案 1 :(得分:2)

我想补充@fabian的答案。如果要一次查找多个匹配项,则可以在字符串中查找所有匹配项,并将其索引保存到列表中。该列表可用于逐步解决每次出现的情况。

我在fabian的原始字符串中添加了4次hello。您可以在TextField中打个招呼,然后上下按以达到每次出现的目的。

    TextArea textArea = new TextArea();
    VBox.setVgrow(textArea, Priority.ALWAYS);
    Random random = new Random();
    for (int l = 0; l < 10; l++) {
        for (int i = 0; i < 300; i++) {
            textArea.appendText(Character.toString('a' + random.nextInt('z'- 'a' + 1)));
        }
        textArea.appendText("\n");
    }

    textArea.replaceText(0, 5, "hello");
    textArea.replaceText(20, 25, "hello");
    textArea.replaceText(30, 35, "hello");
    textArea.replaceText(textArea.getText().length() - 6, textArea.getText().length() -1, "hello");

    TextField textField = new TextField();
    List<List<Integer>> locations = new ArrayList();

    textField.textProperty().addListener((o, oldValue, newValue) -> {
        Pattern pattern = Pattern.compile(newValue);
        Matcher matcher = pattern.matcher(textArea.getText());

        locations.clear();
        if (newValue.isEmpty()) {
            // no highlighting for the empty search string
            textArea.deselect();
        } else {                
            int index = textArea.getText().indexOf(newValue);
            if (index < 0) {
                // text not found
                textArea.deselect();
            } else {
                while(matcher.find())
                {
                    List<Integer> tempList = new ArrayList<>();
                    tempList.add(matcher.start());
                    tempList.add(matcher.end());

                    locations.add(tempList);
                }
            }
        }
    });

    AtomicInteger currentIndex = new AtomicInteger(-1);
    Button btnDown = new Button("Down");
    btnDown.setOnAction((t) -> {
        if(currentIndex.get() >= -1 && currentIndex.get() < locations.size() - 1)
        {
            textArea.selectRange(locations.get(currentIndex.incrementAndGet()).get(0), locations.get(currentIndex.get()).get(1));
        }
    });

    Button btnUp = new Button("Up");
    btnUp.setOnAction((t) -> {
        if(currentIndex.get() > 0 && currentIndex.get() <= locations.size())
        {
            textArea.selectRange(locations.get(currentIndex.decrementAndGet()).get(0), locations.get(currentIndex.get()).get(1));
        }
    });
    Scene scene = new Scene(new VBox(textArea, textField, new HBox(btnDown, btnUp)));

    stage.setScene(scene);
    stage.show();