jede Grafik Um zu zeigen, vor der Linie, müssen Sie die „Absatz grafische Fabrik“, um des CodeArea. Diese Grafik-Factory ist nur eine Funktion int -> Node
: angesichts der Zeilennummer, gibt es eine Node
, die vor der Zeile angezeigt wird.
Hier ist eine grafische Fabrik, die ein grünes Dreieck zeigt, das auf die Linie zeigt. Es wird nur angezeigt, wenn die Zeile gleich der angegebenen Ganzzahleigenschaft shownLine
ist.
class ArrowFactory implements IntFunction<Node> {
private final ObservableValue<Integer> shownLine;
ArrowFactory(ObservableValue<Integer> shownLine) {
this.shownLine = shownLine;
}
@Override
public Node apply(int lineNumber) {
Polygon triangle = new Polygon(0.0, 0.0, 10.0, 5.0, 0.0, 10.0);
triangle.setFill(Color.GREEN);
ObservableValue<Boolean> visible = Val.map(
shownLine,
sl -> sl == lineNumber);
triangle.visibleProperty().bind(visible.conditionOnShowing(triangle));
return triangle;
}
}
Jede Grafik (das heißt kleine grüne Dreieck) Sie erstellen, wird die gegebene shownLine
Eigenschaft werden zu beobachten, um zu entscheiden, ob sie sichtbar sein sollen. Da Linien und somit Liniengrafiken kommen und gehen, ist es wichtig, den Listener von shownLine
zu entfernen, wenn die Grafik nicht mehr verwendet wird. visible.conditionOnShowing(triangle)
ist eine neue Eigenschaft, die die visible
-Eigenschaft (und automatisch auch die shownLine
-Eigenschaft, dank ReactFX Lazy Binding Semantik) zu beobachten und auf false
immer dann zurückgesetzt wird, wenn das Dreieck nicht Teil eines angezeigten Fensters ist. Wir verursachen also keine Speicher- oder CPU-Lecks aufgrund unsauberer Zuhörer.
Hier ist eine vollständige runnable Demo, die diese ArrowFactory
kombiniert mit der LineNumberFactory
von RichTextFX verwendet, um beide Zeilennummern und ein kleines Dreieck anzuzeigen. In dieser Demo wird die aktuelle Zeile der CodeArea als shownLine
-Eigenschaft verwendet. Sie möchten es durch eine Eigenschaft ersetzen, die die aktuelle Ausführungszeile enthält.
import java.util.function.IntFunction;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;
import org.reactfx.value.Val;
public class CodeAreaWithLineIndicator extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
CodeArea codeArea = new CodeArea();
IntFunction<Node> numberFactory = LineNumberFactory.get(codeArea);
IntFunction<Node> arrowFactory = new ArrowFactory(codeArea.currentParagraphProperty());
IntFunction<Node> graphicFactory = line -> {
HBox hbox = new HBox(
numberFactory.apply(line),
arrowFactory.apply(line));
hbox.setAlignment(Pos.CENTER_LEFT);
return hbox;
};
codeArea.setParagraphGraphicFactory(graphicFactory);
primaryStage.setScene(new Scene(new StackPane(codeArea), 600, 400));
primaryStage.show();
}
}
class ArrowFactory implements IntFunction<Node> {
private final ObservableValue<Integer> shownLine;
ArrowFactory(ObservableValue<Integer> shownLine) {
this.shownLine = shownLine;
}
@Override
public Node apply(int lineNumber) {
Polygon triangle = new Polygon(0.0, 0.0, 10.0, 5.0, 0.0, 10.0);
triangle.setFill(Color.GREEN);
ObservableValue<Boolean> visible = Val.map(
shownLine,
sl -> sl == lineNumber);
triangle.visibleProperty().bind(visible.conditionOnShowing(triangle));
return triangle;
}
}
Und das ist das Ergebnis:
Ich denke, es wäre einfacher, Val.conditionOnShowing (Knoten) zu verstehen, mit: 'triangle.visibleProperty() binden (visible.conditionOnShowing (. Dreieck)); 'oder habe ich etwas Wichtiges vermisst? – Adrodoc55
Sie haben absolut Recht. Der einzige Grund ist, dass diese Antwort der Existenz von "conditionOnShowing" vorausgeht. Ich werde die Antwort aktualisieren. Vielen Dank! –