Dieser Artikel ist der 14. Tag von JavaFX Adventskalender 2016. Gestern war @ sk44_s "Natives Symbol mit javafx-maven-plugin festlegen". Morgen ist @ khasunumas "Hinweise zum Aufrufen der Payara Micro API von JavaFX".
Haben Sie sich bei der Implementierung eines Editors in JavaFX jemals mit der Ausdruckskraft und den Feinheiten der Standard-TextArea unzufrieden gefühlt?
In diesem Artikel stelle ich die Bibliothek "RichTextFX" vor, die ich all jenen empfehlen möchte, die Tools mit Editorfunktion mit JavaFX erstellen möchten oder diese erstellt haben.
Eine von Tomas Mikula entwickelte Bibliothek, die Rich-Text-Bearbeitungskomponenten bereitstellt. Sie finden den Demo-Code und die Verwendung im GitHub-Repository.
BSD 2-Klausel-Lizenz und GPLv2-Klassenpfadausnahme-Doppellizenz.
JDK 8 oder höher, weil es [javafx.scene.text.TextFlow] verwendet (https://docs.oracle.com/javase/jp/8/javafx/api/javafx/scene/text/TextFlow.html) Wird benötigt.
Die in dieser Einführung verwendete Umgebung ist wie folgt.
Java SE | 1.8.0_102 |
---|---|
OS | Windows 10 |
Gradle | 3.0 |
Verwenden Sie Groovys FizzBuzz als sehr einfachen Code.
FizzBuzz.groovy
(1..100)
.collect{it % 15 == 0 ? "FizzBuzz" : it % 3 ==0 ? "Fizz" : it % 5 == 0 ? "Buzz" : it}
.forEach{print it + ", "}
Fügen Sie Abhängigkeiten die folgende Zeile hinzu.
build.gradle
dependencies {
+ compile 'org.fxmisc.richtext:richtextfx:0.7-M2'
......
}
Es wird als völlig separate Einheit von der Standard-TextArea implementiert und ist nicht kompatibel. Achtung.
<?import org.fxmisc.richtext.CodeArea?>
Bitte beachten Sie, dass der Tooltip nicht verwendet werden kann.
- <TextArea fx:id="scripterInput" prefHeight="550.0" prefWidth="500.0">
- <tooltip><Tooltip text="input script." /></tooltip>
- </TextArea>
+ <CodeArea fx:id="scripterInput" prefHeight="550.0" prefWidth="500.0" />
Die Controller-Klasse muss ebenfalls geändert werden.
-import javafx.scene.control.TextArea;
+import org.fxmisc.richtext.CodeArea;
TextArea und CodeArea sind nicht kompatibel und müssen ersetzt werden.
@FXML
- public TextArea scripterInput;
+ public CodeArea scripterInput;
@FXML
- public TextArea scripterOutput;
+ public CodeArea scripterOutput;
Bitte beachten Sie, dass auch die Methodennamen unterschiedlich sind.
- scripterOutput.setText(result);
+ scripterOutput.replaceText(result);
Im ursprünglichen Zustand gibt es keine Code-Hervorhebung, keine Zeilennummernanzeige und keinen Umbruch.
Als nächstes zeigen wir die Zeilennummer an.
+import org.fxmisc.richtext.LineNumberFactory;
Geben Sie für jedes CodeArea-Objekt ParagraphGraphicFactory an, wie unten gezeigt.
Stellen Sie die Zeilennummernanzeige mit setParagraphGraphicFactory ein
scripterOutput.setParagraphGraphicFactory(LineNumberFactory.get(scripterInput));
Auf diese Weise wird die Zeilennummer angezeigt.
Wenn Sie versuchen, den Zeilenumbruch zu unterbrechen, wird die Anzahl der Zeilen genauso angezeigt wie der Zeilenumbruch.
Wenn mehr als 100 Zeilen vorhanden sind, wird es dreistellig angezeigt.
CodeArea erfordert eine kleine Implementierung, kann jedoch mit einem bestimmten Format / Schlüsselwort hervorgehoben werden. Eine Funktion dieser Bibliothek ist die asynchrone Hervorhebung. Sie können Ihre Änderungen in Echtzeit hervorheben. Die Implementierung verwendet ReactFX, eine Bibliothek reaktiver Streams, die von demselben Tomas Mikula entwickelt wurde.
Eine Beispielimplementierung in der Programmiersprache Java finden Sie unten.
https://github.com/TomasMikula/RichTextFX/blob/master/richtextfx-demos/src/main/java/org/fxmisc/richtext/demo/JavaKeywordsAsync.java
Lassen Sie uns dieses Mal ein Beispiel in Groovy implementieren.
Es scheint, dass es unten 57 Typen gibt. Wenn Sie ein Experte sind, weisen Sie bitte darauf hin, wenn Sie einen Fehler machen.
Groovy's keywords
abstract
as
assert
boolean
break
byte
case
catch
char
class
const
continue
def
default
do
double
else
enum
extends
false
final
finally
float
for
goto
if
implements
import
in
instanceof
int
interface
long
native
new
null
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
threadsafe
throw
throws
transient
true
try
void
volatile
while
Speichern Sie dies in einer Textdatei.
Diesmal ist [Offizielles Beispiel](https://github.com/TomasMikula/RichTextFX/blob/2b4ba4378cfe27facfd86051771946ed9c0dc691/richtextfx-demos/src/main/resources/org/fxmisc/richtext/demo verwendet). Ich werde es benutzen.
CSS für Schlüsselwörter
.keyword {
-fx-fill: purple;
-fx-font-weight: bold;
}
.semicolon {
-fx-font-weight: bold;
}
.paren {
-fx-fill: firebrick;
-fx-font-weight: bold;
}
.bracket {
-fx-fill: darkgreen;
-fx-font-weight: bold;
}
.brace {
-fx-fill: teal;
-fx-font-weight: bold;
}
.string {
-fx-fill: blue;
}
.comment {
-fx-fill: cadetblue;
}
.paragraph-box:has-caret {
-fx-background-color: #f2f9fc;
}
Sie können diese CSS-Datei überall ablegen, diesmal jedoch direkt unter src / main / resources.
Definieren Sie zunächst eine Klasse mit Methoden, die häufig zum Hervorheben von Implementierungen verwendet werden. Hoch vom Demo-Code JavaKeywordsAsync.java Extrahieren Sie nur den zu verarbeitenden Teil und definieren Sie nur die allgemeine Verarbeitung als abstrakte Klasse.
https://github.com/toastkidjp/javafx_advent2015/blob/v2016/src/main/java/jp/toastkid/highlight/Highlight.java
Eine Methode, die die asynchrone Verarbeitung ausführt. Rufen Sie diese Methode in Ihrer Anwendung auf.
Erben Sie die obige Highlight-Klasse, um eine Klasse zu erstellen, die die Syntax von Groovy hervorhebt.
https://github.com/toastkidjp/javafx_advent2015/blob/v2016/src/main/java/jp/toastkid/highlight/GroovyHighlight.java
Diese Methode liest Schlüsselwörter aus der zuvor erstellten Schlüsselwortdatei und erstellt einen regulären Ausdruck für die Codehervorhebung. Andere reguläre Ausdrücke als Schlüsselwörter sind vordefiniert. Sie können eine Highlight-Klasse für jede Sprache erstellen, indem Sie für jede Sprache Folgendes ändern.
Regulärer Ausdruck für die Code-Hervorhebung
private static final String PAREN_PATTERN = "\\(|\\)";
private static final String BRACE_PATTERN = "\\{|\\}";
private static final String BRACKET_PATTERN = "\\[|\\]";
private static final String SEMICOLON_PATTERN = "\\;";
private static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\"";
private static final String COMMENT_PATTERN = "//[^\n]*" + "|" + "/\\*(.|\\R)*?\\*/";
Eine Methode, die den Text von CodeArea in ein Format konvertiert, das das Hervorheben von Code ermöglicht.
Fügen Sie der letzten Zeile der Initialisierungsmethode Folgendes hinzu.
initialize()
new GroovyHighlight(scripterInput).highlight();
Fügen Sie außerdem den URI der CSS-Datei für die zuvor vorbereitete Keyword-Färbung zu den Stylesheets des Scene-Objekts hinzu.
src/main/Direkt unter Ressourcen"keywords.css"Zu Stylesheets
final ObservableList<String> stylesheets = thisStage.getScene().getStylesheets();
stylesheets.add(getClass().getClassLoader().getResource("keywords.css").toExternalForm());
Damit ist die Vorbereitung abgeschlossen.
Geben Sie unten den FizzBuzz-Code ein.
FizzBuzz
int i = 0
(1..100)
.collect{it % 15 == 0
? "FizzBuzz"
: it % 3 ==0
? "Fizz"
: it % 5 == 0
? "Buzz"
: it
}
.forEach{print it + ", "}
Wie Sie sehen können, ist int rötlich, Kommentare sind hellgrün und Zeichenfolgenliterale in "sind blau".
Weitere einfache Implementierungsbeispiele für Code-Highlights finden Sie im folgenden Repository, wenn Sie interessiert sind (die Anwendung selbst ist nicht enthalten).
https://github.com/toastkidjp/simple_highlight
Ich habe RichTextFX bisher empfohlen, aber ich habe diesen Artikel geschrieben, bevor ich ihn in die eigentliche Anwendung eingebettet habe. Später habe ich einen Fehler festgestellt, der nicht übersehen werden kann. Deshalb werde ich ihn hinzufügen.
Schauen Sie sich zunächst das Bild unten an. Ein Fenster mit drei aneinandergereihten Textbereichen wird angezeigt, und Conversion-Kandidaten werden angezeigt, indem Sie im Textbereich links "neben" eingeben (CodeArea von RichTextFX).
Haben Sie sich unwohl gefühlt? Ja, der eingegebene Text und die Conversion-Kandidaten werden oben links auf dem Bildschirm angezeigt. Es ist ein ziemlich dummer Zustand ... Dies ist die Textsteuerungsklasse von RichTextFX javafx.scene.control.TextInputControl. Es scheint, dass die Ursache darin besteht, dass control / TextInputControl.html) nicht implementiert ist. ~~ Ich frage mich, ob der Autor keine Mehrbyte-Zeichen eingeben musste …… ~~
Dies war natürlich nicht der Fall, und die Person, die auf Verbesserungsmaßnahmen hinwies und diese vorschlug, schuf das Problem.
How to insert text using an Input Method #146
Mit Blick auf das obige Problem wurde gesagt, dass "ich InputMethodRequests implementiert und gelöst habe", also dachte ich, ich würde versuchen, es zu verbessern, und ich implementierte es hier [EditorInputMethodRequests](https: // github. com / toastkidjp / RichTextFX_verification / blob / verification / src / main / java / jp / toastkid / rtfx_verification / EditorInputMethodRequests.java). Die Implementierung mit der in SNAPSHOT 1.0.0 hinzugefügten Methode getCaretBounds () war recht einfach.
codeArea.setInputMethodRequests(new EditorInputMethodRequests(improved));
Implementieren Sie stattdessen Inhalt von setOnInputMethodTextChanged Es war schwieriger, aber ...
codeArea.setOnInputMethodTextChanged(this::handleInputMethodEvent);
Im zentralen Textbereich werden diese Korrekturen angewendet. Dies
Der Eingabetext wird an der Position des Übertrags korrekt angezeigt, und Konvertierungskandidaten werden auch darunter angezeigt. Endlich ist es auf einer Ebene, die als Mindesteditor verwendet werden kann.
Ich dachte das wäre nicht der Fall.
Der Textbereich rechts ist der JavaFX-Standard TextArea. Der unsichere Teil des Eingabetextes ist unterstrichen und der Bereich der Konvertierungskandidaten wird mit einem blauen Hintergrund hervorgehoben. Es ist schwierig, es in die Praxis umzusetzen, wenn es dieses Niveau nicht erreicht, aber wir konnten die Funktionen bisher nicht implementieren. Wenn Sie interessiert sind, kann es interessant sein, es anhand des Codes der folgenden 3 Klassen zu versuchen.
Um RichTextFX 1.0.0-SNAPSHOT ab dem 6. Februar 2017 zu verwenden, fügen Sie `https: // oss.sonatype.org / content / repositories / snapshots /`
in die Repositorys von build.gradle ein. Es ist erforderlich, die Repository-Spezifikation von hinzuzufügen.
build.gradle
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
https://github.com/toastkidjp/RichTextFX_verification/tree/verification
Laut @ nodamushis Artikel "JavaFX 9 wird besser" des JavaFX-Adventskalenders 2016, JavaFX 9 Es scheint möglich zu sein, TextArea zu implementieren, das Zeilennummern nur mit der Standard-API anzeigen kann. Die Erwartungen steigen.
Wir haben gerade kurz RichTextFX vorgestellt, eine Bibliothek, mit der Sie Rich-Text-Bearbeitungsfunktionen in JavaFX implementieren können. Das offizielle Repository enthält verschiedene Demo-Codes, die diesmal nicht eingeführt werden konnten, z. B. den XML-Editor und die Größenänderung von Schriftarten. Wenn Sie einen Markdown-Editor oder einen HTML-Editor entwickeln oder Beispielcode in ein in JavaFX entwickeltes Präsentationstool einfügen möchten, sollten Sie diese Bibliothek einführen.
RichTextFX CSS Reference Guide https://github.com/TomasMikula/RichTextFX/wiki/RichTextFX-CSS-Reference-Guide