gpt4 book ai didi

java - 有没有办法防止光标点击某个字符串?

转载 作者:行者123 更新时间:2023-11-30 07:00:23 25 4
gpt4 key购买 nike

我正在尝试这样做,以便当我单击某个字符串时,闪烁的光标不会放置在那里。有点像命令行界面中显示的工作目录。我以为我可以

  • 首先获取文本的像素宽度和高度
  • 然后,我可以找到一种方法来阻止鼠标事件到达组件的该部分(例如激活玻璃 Pane )

问题是,文本位于 TextArea 中,因此我必须重写 TextAreas MouseEvent 监听器。

似乎有一个更好、更简单的解决方案。我更喜欢 JavaFX 中的答案,但如果不可能,Swing 答案也可以。

最佳答案

尝试以下解决方案并查看是否合适。它的作用是覆盖 TextArea 中的 positionCaret 方法,并在用户在阻止范围内单击时阻止它执行任何操作。在示例中,用户无法将插入符号放置在其中的被阻止文本是每行上的“Lorem Ipsum:”前缀。

sample

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class InputBlocker extends Application {
private static final String TEXT =
"Lorem ipsum: dolor sit amet, consectetur adipiscing elit. Nulla in nisi sed neque porttitor volutpat. \n" +
"\n" +
"Lorem ipsum: Maecenas non mauris scelerisque, egestas felis quis, venenatis risus. Etiam eu ornare justo, at pulvinar tortor. ";

private static final String FORBIDDEN_PREFIX = "Lorem ipsum: ";

@Override
public void start(final Stage stage) throws Exception {
TextArea textArea = new BlockingTextArea(TEXT, FORBIDDEN_PREFIX);
textArea.setWrapText(true);

stage.setScene(new Scene(textArea));
stage.show();
}

public static void main(String[] args) throws Exception {
launch(args);
}
}

class BlockingTextArea extends TextArea {
private final String forbiddenPrefix;
private List<Range> blockedRanges;

public BlockingTextArea(String text, String forbiddenPrefix) {
super(text);

this.forbiddenPrefix = forbiddenPrefix;
this.blockedRanges = findBlockedRanges(text);

textProperty().addListener((observable, oldValue, newValue) ->
blockedRanges = findBlockedRanges(newValue)
);
}

@Override
public void positionCaret(int pos) {
Optional<Range> blockedRange =
blockedRanges.stream()
.filter(range -> range.containsExclusive(pos))
.findFirst();

if (blockedRange.isPresent()) {
return;
}

super.positionCaret(pos);
}

private List<Range> findBlockedRanges(String text) {
List<Range> blocked = new ArrayList<>();

int idx = 0;
while (idx < text.length()) {
if (text.startsWith(forbiddenPrefix, idx)) {
blocked.add(new Range(idx, idx + forbiddenPrefix.length()));
idx += forbiddenPrefix.length();
}

int nextIdx = text.indexOf("\n", idx);
if (nextIdx == -1) {
break;
}

idx = nextIdx + 1;
}

return blocked;
}

private class Range {
private final int min;
private final int max;

Range(int min, int max) {
this.min = min;
this.max = max;
}

public int getMin() {
return min;
}

public int getMax() {
return max;
}

boolean containsExclusive(int pos) {
return min <= pos && pos < max;
}
}
}

上述解决方案存在一些可用性问题:

  • 用户仍然可以将字符定位在阻止的文本之后,然后退格以删除到阻止的文本区域。也许重写 replaceTextdeleteText 可能有助于解决这个问题。
  • 拖动并单击穿过被阻止的文本区域的选择有点不稳定,因为它们依赖于插入符定位。也许重写 selectPositionCaretselectRange 或其他一些方法可能有助于解决这个问题。

但无论如何,也许上面的代码可以为您提供一些示例,说明如何处理该问题并解决您的问题。

第三方而不是TextArea RichTextFX可能是用于此类应用程序的更好的候选控件,因为它允许对文本内容进行样式设置,从而可以提供更好的用户体验,其中插入符号无法定位的文本以与文本其余部分不同的方式设置样式。我还没有对如何为 RichTextFX 实现插入符号阻止功能进行任何调查。

关于java - 有没有办法防止光标点击某个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41029220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com