Skip to content

Commit

Permalink
Add DemoLauncher from afester (#1151)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jugen committed Nov 11, 2022
1 parent c5f1818 commit 4fe9636
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 74 deletions.
2 changes: 1 addition & 1 deletion richtextfx-demos/README.md
Expand Up @@ -17,7 +17,7 @@ Note: This page does not show all the demos in the package. Follow the instructi
### Instructions for running demos

1. Clone the repository: `git clone https://www.github.com/FXMisc/RichTextFX.git`
2. Checkout the latest release version: `git checkout v0.9.0`
2. Checkout the latest release version: `git checkout tagName` where tagName is the latest release tag (use `git tag` to get a list of available tags, and use the last one)
3. See the list of demos using a gradle task `./gradlew demos`
4. Run a demo using a gradle task: `./gradlew [Demo Name]`

Expand Down
215 changes: 144 additions & 71 deletions richtextfx-demos/build.gradle
@@ -1,5 +1,19 @@
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
}

javafx {
version = '11'
modules = [ 'javafx.controls']
}

// Common application JVM options - currently required to fix module dependency
// issues. This sets the required JVM options for all demo tasks specified below.
application {
applicationDefaultJvmArgs = ["--add-opens", "javafx.graphics/javafx.scene.text=ALL-UNNAMED",
"--add-exports", "javafx.graphics/com.sun.javafx.text=ALL-UNNAMED",
"--add-exports", "javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED"]
}

dependencies {
Expand All @@ -22,6 +36,12 @@ task fatJar(type: Jar, dependsOn: classes) {
dependsOn ":richtextfx:jar"

archiveAppendix = 'fat'
excludes = ['module-info.class']

manifest {
attributes(
'Main-Class': 'org.fxmisc.richtext.demo.DemoLauncher')
}

from sourceSets.main.output
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
Expand All @@ -33,7 +53,7 @@ task demos(description: "Lists the names and the descriptions of the demos that
doLast {
// sort the demos first, so they can be added in the build file in any order
def list = []
tasks.withType(JavaExec) {
tasks.each {
if (it.name.endsWith("Demo")) {
list.add(it)
}
Expand All @@ -45,108 +65,161 @@ task demos(description: "Lists the names and the descriptions of the demos that
}
}

// To add a task for a demo, use the following template:
// To add a task for a demo, use the following template (and, also add the new
// demo class to org.fxmisc.richtext.demo.DemoLauncher so that it can be launched
// from the demo fat jar file):
/*
task ClassNameDemo(type: JavaExec, dependsOn: classes,
description: "A description of what the demo does") {
mainClass = 'org.fxmisc.richtext.demo.ClassNameDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task ClassNameDemo(description: "A description of what the demo does") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.ClassNameDemo'
}
}
}
ClassNameDemo.finalizedBy run
*/

task JavaKeywordsDemo(type: JavaExec, dependsOn: classes,
description: "A CodeArea with Java syntax highlighting that is computed on the JavaFX Application Thread") {
mainClass = 'org.fxmisc.richtext.demo.JavaKeywordsDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task JavaKeywordsDemo(description: "A CodeArea with Java syntax highlighting that is computed on the JavaFX Application Thread") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.JavaKeywordsDemo'
}
}
}
JavaKeywordsDemo.finalizedBy run

task JavaKeywordsAsyncDemo(type: JavaExec, dependsOn: classes,
description: "A CodeArea with Java syntax highlighting that is computed on a background thread") {
mainClass = 'org.fxmisc.richtext.demo.JavaKeywordsAsyncDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task JavaKeywordsAsyncDemo(description: "A CodeArea with Java syntax highlighting that is computed on a background thread") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.JavaKeywordsAsyncDemo'
}
}
}
JavaKeywordsAsyncDemo.finalizedBy run

task XMLEditorDemo(type: JavaExec, dependsOn: classes,
description: "An area with XML syntax highlighting") {
mainClass = 'org.fxmisc.richtext.demo.XMLEditorDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task XMLEditorDemo(description: "An area with XML syntax highlighting") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.XMLEditorDemo'
}
}
}
XMLEditorDemo.finalizedBy run

task ManualHighlightingDemo(type: JavaExec, dependsOn: classes,
description: "Manually highlight various parts of the text in an area via buttons") {
mainClass = 'org.fxmisc.richtext.demo.ManualHighlightingDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task ManualHighlightingDemo(description: "Manually highlight various parts of the text in an area via buttons") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.ManualHighlightingDemo'
}
}
}
ManualHighlightingDemo.finalizedBy run

task RichTextDemo(type: JavaExec, dependsOn: classes,
description: "An area showing a large number of RichTextFX's features: " +
task RichTextDemo(description: "An area showing a large number of RichTextFX's features: " +
"inlined images, rich text (e.g. text alignment and background colors, etc.), and save/load capabilities") {
mainClass = 'org.fxmisc.richtext.demo.richtext.RichTextDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.richtext.RichTextDemo'
}
}
}
RichTextDemo.finalizedBy run

task PopupDemo(type: JavaExec, dependsOn: classes,
description: "A popup that follows the caret and selection when they move") {
mainClass = 'org.fxmisc.richtext.demo.PopupDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task PopupDemo(description: "A popup that follows the caret and selection when they move") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.PopupDemo'
}
}
}
PopupDemo.finalizedBy run

task TooltipDemo(type: JavaExec, dependsOn: classes,
description: "Tells you the letter over which the mouse is hovering") {
mainClass = 'org.fxmisc.richtext.demo.TooltipDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task TooltipDemo(description: "Tells you the letter over which the mouse is hovering") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.TooltipDemo'
}
}
}
TooltipDemo.finalizedBy run

task HyperlinkAreaDemo(type: JavaExec, dependsOn: classes,
description: "An area with hyperlinks that open to their corresponding link") {
mainClass = 'org.fxmisc.richtext.demo.hyperlink.HyperlinkDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task HyperlinkAreaDemo(description: "An area with hyperlinks that open to their corresponding link") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.hyperlink.HyperlinkDemo'
}
}
}
HyperlinkAreaDemo.finalizedBy run

task LineIndicatorDemo(type: JavaExec, dependsOn: classes,
description: "Line numbers appear to left of each paragraph and a triangle appears on the same paragraph as the caret") {
mainClass = 'org.fxmisc.richtext.demo.lineindicator.LineIndicatorDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task LineIndicatorDemo(description: "Line numbers appear to left of each paragraph and a triangle appears on the same paragraph as the caret") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.lineindicator.LineIndicatorDemo'
}
}
}
LineIndicatorDemo.finalizedBy run

task CloneDemo(type: JavaExec, dependsOn: classes,
description: "Two areas that can modify and show the same underlying document") {
mainClass = 'org.fxmisc.richtext.demo.CloneDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task CloneDemo( description: "Two areas that can modify and show the same underlying document") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.CloneDemo'
}
}
}
CloneDemo.finalizedBy run

task FontSizeSwitcherDemo(type: JavaExec, dependsOn: classes,
description: "Change the font size of the entire area.") {
mainClass = 'org.fxmisc.richtext.demo.FontSizeSwitcherDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task FontSizeSwitcherDemo(description: "Change the font size of the entire area.") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.FontSizeSwitcherDemo'
}
}
}
FontSizeSwitcherDemo.finalizedBy run

task MultiCaretAndSelectionNameDemo(type: JavaExec, dependsOn: classes,
description: "Add and display multiple carets and selections with different style classes in the same area") {
mainClass = 'org.fxmisc.richtext.demo.MultiCaretAndSelectionDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task MultiCaretAndSelectionNameDemo(description: "Add and display multiple carets and selections with different style classes in the same area") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.MultiCaretAndSelectionDemo'
}
}
}
MultiCaretAndSelectionNameDemo.finalizedBy run

task OverrideBehaviorDemo(type: JavaExec, dependsOn: classes,
description: "Overrides the area's default behavior and demonstrates some things of which to be aware") {
mainClass = 'org.fxmisc.richtext.demo.OverrideBehaviorDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task OverrideBehaviorDemo(description: "Overrides the area's default behavior and demonstrates some things of which to be aware") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.OverrideBehaviorDemo'
}
}
}
OverrideBehaviorDemo.finalizedBy run

task ShowLineDemo(type: JavaExec, dependsOn: classes,
description: "Force a specific part of the underlying document to be rendered to the screen.") {
mainClass = 'org.fxmisc.richtext.demo.ShowLineDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task ShowLineDemo(description: "Force a specific part of the underlying document to be rendered to the screen.") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.ShowLineDemo'
}
}
}
ShowLineDemo.finalizedBy run

task SpellCheckingDemo(type: JavaExec, dependsOn: classes,
description: "Shows how to add a red squiggle underneath misspelled words") {
mainClass = 'org.fxmisc.richtext.demo.SpellCheckingDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task SpellCheckingDemo(description: "Shows how to add a red squiggle underneath misspelled words") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.SpellCheckingDemo'
}
}
}
SpellCheckingDemo.finalizedBy run

task BracketHighlighterDemo(type: JavaExec, dependsOn: classes,
description: "Shows how to highlight matching brackets") {
mainClass = 'org.fxmisc.richtext.demo.brackethighlighter.BracketHighlighterDemo'
classpath = files(sourceSets.main.output, configurations.runtimeClasspath)
task BracketHighlighterDemo(description: "Shows how to highlight matching brackets") {
doLast() {
application {
mainClass = 'org.fxmisc.richtext.demo.brackethighlighter.BracketHighlighterDemo'
}
}
}
BracketHighlighterDemo.finalizedBy run
@@ -0,0 +1,74 @@
package org.fxmisc.richtext.demo;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

import org.reactfx.util.Tuple2;
import static org.reactfx.util.Tuples.*;

/**
* This class serves as the entry point for launching the various demos.
* It is primarily used when creating a FAT jar (or executable jar) for the
* demos.
*/
public class DemoLauncher {

@SuppressWarnings("serial")
private static final Map<String, Tuple2<String, Consumer<String[]>>> demoMap = new HashMap<>() {{
/**
* When launched from the JVM launcher directly, all the Demo classes would not necessarily require a
* main() method - the JVM launcher would take care of it. However, since we use our own launcher
* class here, the main() method in each individual class *is* required - simply calling the
* launch() method does NOT work!
*/
put("JavaKeywordsDemo", t("A CodeArea with Java syntax highlighting that is computed on the JavaFX Application Thread",
org.fxmisc.richtext.demo.JavaKeywordsDemo::main));
put("JavaKeywordsAsyncDemo", t("A CodeArea with Java syntax highlighting that is computed on a background thread",
org.fxmisc.richtext.demo.JavaKeywordsAsyncDemo::main));
put("XMLEditorDemo", t("An area with XML syntax highlighting",
org.fxmisc.richtext.demo.XMLEditorDemo::main));
put("ManualHighlightingDemo", t("Manually highlight various parts of the text in an area via buttons",
org.fxmisc.richtext.demo.ManualHighlightingDemo::main));
put("RichTextDemo", t("An area showing a large number of RichTextFX's features: inlined images, rich text (e.g. text alignment and background colors, etc.), and save/load capabilities",
org.fxmisc.richtext.demo.richtext.RichTextDemo::main));
put("PopupDemo", t("A popup that follows the caret and selection when they move",
org.fxmisc.richtext.demo.PopupDemo::main));
put("TooltipDemo", t("Tells you the letter over which the mouse is hovering",
org.fxmisc.richtext.demo.TooltipDemo::main));
put("HyperlinkAreaDemo", t("An area with hyperlinks that open to their corresponding link",
org.fxmisc.richtext.demo.hyperlink.HyperlinkDemo::main));
put("LineIndicatorDemo", t("Line numbers appear to left of each paragraph and a triangle appears on the same paragraph as the caret",
org.fxmisc.richtext.demo.lineindicator.LineIndicatorDemo::main));
put("CloneDemo", t("Two areas that can modify and show the same underlying document",
org.fxmisc.richtext.demo.CloneDemo::main));
put("FontSizeSwitcherDemo", t("Change the font size of the entire area.",
org.fxmisc.richtext.demo.FontSizeSwitcherDemo::main));
put("MultiCaretAndSelectionNameDemo", t("Add and display multiple carets and selections with different style classes in the same area",
org.fxmisc.richtext.demo.MultiCaretAndSelectionDemo::main));
put("OverrideBehaviorDemo", t("Overrides the area's default behavior and demonstrates some things of which to be aware",
org.fxmisc.richtext.demo.OverrideBehaviorDemo::main));
put("ShowLineDemo", t("Force a specific part of the underlying document to be rendered to the screen.",
org.fxmisc.richtext.demo.ShowLineDemo::main));
put("SpellCheckingDemo", t("Shows how to add a red squiggle underneath misspelled words",
org.fxmisc.richtext.demo.SpellCheckingDemo::main));
put("BracketHighlighterDemo", t("Shows how to highlight matching brackets",
org.fxmisc.richtext.demo.brackethighlighter.BracketHighlighterDemo::main));
}};

private final static String[] noArgs = new String[0];

public static void main(String[] args) {
if (args.length == 0) {
demoMap.entrySet().forEach(e -> System.out.printf("%s - %s\n", e.getKey(), e.getValue().get1()));
} else {
final Tuple2<String, Consumer<String[]>> demoData = demoMap.get(args[0]);
if (demoData == null) {
System.err.printf("No such demo: %s", args[0]);
} else {
Consumer<String[]> mainMethod = demoData.get2();
mainMethod.accept(noArgs);
}
}
}
}
Expand Up @@ -14,6 +14,10 @@ public class MultiCaretAndSelectionDemo extends Application {

private InlineCssTextArea area;

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

@Override
public void start(Stage primaryStage) {
// initialize area with some lines of text
Expand Down
Expand Up @@ -53,6 +53,10 @@ public int getTextAsInt() {
field.setPromptText("Input a number to indicate which line you want to show");
}

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

@Override
public void start(Stage primaryStage) throws Exception {
StringBuilder sb = new StringBuilder();
Expand Down
Expand Up @@ -20,7 +20,6 @@
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.reactfx.Subscription;

public class SpellCheckingDemo extends Application {

Expand All @@ -35,7 +34,7 @@ public void start(Stage primaryStage) {
StyleClassedTextArea textArea = new StyleClassedTextArea();
textArea.setWrapText(true);

Subscription cleanupWhenFinished = textArea.multiPlainChanges()
textArea.multiPlainChanges()
.successionEnds(Duration.ofMillis(500))
.subscribe(change -> {
textArea.setStyleSpans(0, computeHighlighting(textArea.getText()));
Expand Down

0 comments on commit 4fe9636

Please sign in to comment.