如何在richtextfx控件java代码区的行指示符处指示折叠展开图标



我只是想实现一些括号或插入符号之间的代码折叠像其他java ide: eclipse, netbeans, intelllij使用代码区控制richtextfx库。请给我一些代码提示?谢谢你。

诀窍是实现你自己的行号工厂,它向行号标签(例如标签的图形)添加一个控件,指示行可以折叠的位置,或者它们已经折叠了。

当点击图形时,您将调用:codeArea.foldParagraphs(startLine, endLine);折叠线条,或codeArea.unfoldParagraphs(line);展开线条。

如何确定一行是否可折叠以及要折叠多少行超出了StackOverflow答案的范围。这可以很简单,检查行("paragraph")是否以'{'结束,然后向前扫描到第一个'}'。但这在某些情况下会失败,比如";它是字符串或字符字面量或类似的东西的一部分。

下面是代码的框架:

public class FoldingLineNumberFactory implements IntFunction<Node> {
private IntFunction<Node> defaultFactory;
private CodeArea editor;
public FoldingLineNumberFactory(CodeArea editor) {
this.editor = editor;
defaultFactory = LineNumberFactory.get(editor);
}
@Override
public Node apply(int lineNum) {
Node n = defaultFactory.apply(lineNum);
if (n instanceof Label lab) {
lab.setContentDisplay(ContentDisplay.RIGHT);
lab.setGraphic(graphic(lineNum));
}
return label;
}
private Node graphic(int line) {
// Folding support should be factored out into another class
if (beginsFoldableRegion(line)) {
boolean folded = isLineFolded(line);
var g = getFoldableGraphic(folded);
g.setUserData(line);
g.addEventFilter(MouseEvent.MOUSE_CLICKED, this::mouseClicked);
g.setCursor(Cursor.DEFAULT);
return g;
}
return nullGraphic(); // takes the same space, but is invisible
}
private void mouseClicked(MouseEvent e) {
if (e.getSource() instanceof Node n) {
if (n.getUserData() instanceof Integer line) {
if (isFoldedAt(line)) {
unfold(e);
} else {
fold(e);
}
e.consume();
}
}
}
private void fold(int line) {
// TODO: record somewhere that this line is folded
int lastLine = endLineForRegionStartingAt(line);
editor.foldParagraphs(line, lastLine);
}
private void unfold(int line) {
// TODO: record that this line isn't folded anymore
editor.unfoldParagraphs(line);
if (editor.getParagraphGraphic(line) instanceof Label lab) {
lab.setGraphic(graphic(line));
} else {
System.out.println("paragraph graphic not a Label");
}
}
protected boolean isLineFolded(int line) {
return false; // You need to implement this
}
protected boolean beginsFoldableRegion(int line) {
return false; // You need to implement this
}

private int endLineForRegionStartingAt(int line) {
// TODO: implement this
return -1;
}
private Node getFoldableGraphic(boolean folded) {
if (folded) {
return getFoldGraphic(); // TODO
} else {
return getUnfoldGraphic(); // TODO
}
}
private Node nullGraphic() {
var r =  new Rectangle(10, 10, Color.TRANSPARENT); // just guessing at size
// setting stroke changes final size
r.setStroke(Color.TRANSPARENT);
return r;
}

如何填充其余部分取决于你如何确定哪些部分是可折叠的,以及你希望折叠控件看起来是什么样子。

最新更新