当前位置: 首页 > 知识库问答 >
问题:

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

燕宜修
2023-03-14

我现在想知道如何自动突出显示文本区域内的文本。我已经做了进一步的研究,找到了一种方法来实现这一点,但是我不确定它如何在用户进入搜索后仍然能够自动突出显示字符串。

注意:忽略单选按钮

下面是我在单击搜索按钮时在操作事件中尝试的方法

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

}

预期的输出应该是要突出显示的“hello everyone”中的“hello”,但我仍然不知道如何做到这一点。

编辑:

代码现在看起来是这样的,但是亮点仍然不会出现。

@FXML受保护的无效搜索按钮(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个答案

汪阳辉
2023-03-14

我想补充一下@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();
汪栋
2023-03-14

为此,只需收听TextFieldtext属性。请注意,您只能使用TextArea选择单个范围。如果需要突出显示多个事件,可能需要使用@Slaw建议的TextFlowrangeShape方法。

@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注册这样的侦听器的正确位置是initialize方法。

 类似资料:
  • 我有一个如下的文本区域, 我需要突出显示或选择所有文本“Highlight me”。我没有找到任何方法来突出显示文本区域中的文本。此外,我在JavaFX中找不到任何其他API可以突出显示特定文本或字母的出现,例如Swing中的JTextArea。有人可以建议我如何在文本区域突出显示字符串吗?或者除了JavaFX中的这个文本区域之外,还有其他API可用吗? 我的代码: 预期输出: 线条应以以下任何颜

  • 问题内容: 我可以高亮显示一些文本,使其从一个值开始,然后从另一个值结束,如下所示,但颜色为黄色吗? “” JTextPane 高亮显示 文本“” 谢谢。 问题答案: 通常,有几种可能性,具体取决于您对“突出显示”的真正含义:-) 通过在文档级别更改任意文本部分的样式属性来突出显示,例如 通过textPane级别上的荧光笔突出显示:

  • JSONException:JSONObject文本必须以字符6处的{开头。

  • 有没有简单的库来获取gui功能,比如文本字段、处理中的文本区域。我在processing中编写了一个乒乓球游戏,我希望文本字段能够获得玩家的名字。在下面的代码中,我想要一个文本字段来获取玩家的名字。这里是我的代码

  • 您好,我是Swift新手,在我的项目中使用SwiftUI,我下载了一些天气数据,并将其显示在ContentView()中。 我想突出显示文本的某一部分,如果它包含一些特定的单词,但我不知道如何开始。 在ContentView()中,我尝试设置一个函数,该函数接收从web下载的字符串并返回一个字符串。我认为这是错误的,因为SwiftUI根本不为文本应用修饰符。 例如,在我的ContentView()