Skip to content

Question: Multiple styles in code area #62

@ghost

Description

Hi Tomas, I was looking at the code highlighting example. I have a question.
How do get multiple colors per keyword.
I did this:

private static final String[] GOLD = new String[]{
    "abstract", "assert", "boolean", "break", "byte",
    "case", "catch", "char", "class", "const",
    "continue", "default", "double", "else",
    "enum", "extends", "final", "finally", "float",
    "goto", "if", "implements", "import",
    "instanceof", "int", "interface", "long", "native",
    "new", "package", "private", "protected", "public",
    "return", "short", "static", "strictfp", "super",
    "switch", "synchronized", "this", "throw", "throws",
    "transient", "try", "void", "volatile",};

private static final String[] GREEN = new String[]{
    "for", "while", "do"
};

private static final Pattern GOlD_PATTERN = Pattern.compile("\\b(" + String.join("|", GOLD) + ")\\b");
private static final Pattern GREEN_PATTERN = Pattern.compile("\\b(" + String.join("|", GREEN) + ")\\b");

private static final String sampleCode = String.join("\n", new String[]{
    "package com.example;",
    "",
    "import java.util.*;",
    "",
    "public class Foo extends Bar implements Baz {",
    "",
    "   public static void main(String[] args) {",
    "       for(String arg: args) {",
    "           if(arg.length() != 0)",
    "               System.out.println(arg);",
    "           else",
    "               System.err.println(\"Warning: empty string as argument\");",
    "       }",
    "   }",
    "",
    "}"
});

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

@Override
public void start(Stage primaryStage) {
    CodeArea codeArea = new CodeArea();
    codeArea.textProperty().addListener((obs, oldText, newText) -> {
        codeArea.setStyleSpans(0, computeHighlighting(newText));
    });
    codeArea.replaceText(0, 0, sampleCode);

    Scene scene = new Scene(new StackPane(codeArea), 600, 400);
    scene.getStylesheets().add(Keywords.class.getResource("java-keywords.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.show();
}

private static StyleSpans<Collection<String>> computeHighlighting(String text) {
    Matcher goldMatcher = GOlD_PATTERN.matcher(text);
    Matcher greenMatcher = GREEN_PATTERN.matcher(text);

    int lastKwEnd = 0;
    StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
    while (goldMatcher.find()) {
        spansBuilder.add(Collections.emptyList(), goldMatcher.start() - lastKwEnd);
        spansBuilder.add(Collections.singleton("gold"), goldMatcher.end() - goldMatcher.start());
        lastKwEnd = goldMatcher.end();
    }

    while (greenMatcher.find()) {
        spansBuilder.add(Collections.emptyList(), greenMatcher.start() - lastKwEnd);
        spansBuilder.add(Collections.singleton("green"), greenMatcher.end() - greenMatcher.start());
        lastKwEnd = greenMatcher.end();
    }
    spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
    return spansBuilder.create();
}

but this of course is giving me an error at the copmuteHighlighting method. My understanding is that you build a collection of styleSpans based on the matches founds. so I just went and made another loop to look for words that match another pattern. What is the right way to get it to work? I must be extremely wrong somewhere :) Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions