Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set default text color with word highlighting of CodeArea? #442

Closed
KnightPL opened this issue Feb 9, 2017 · 20 comments
Closed

How to set default text color with word highlighting of CodeArea? #442

KnightPL opened this issue Feb 9, 2017 · 20 comments
Labels

Comments

@KnightPL
Copy link

KnightPL commented Feb 9, 2017

I want to color the words which have not yet been colored with word highlightning (patterns etc.)
I tried:

CodeArea codeArea = new CodeArea();
codeArea.setId("codearea");

and in .css file

#codearea .text {
    -fx-fill: whitesmoke;
}

but it colors all text in CodeArea
Any ideas or help ?
Sorry about my bad english :)
Thanks

@JordanMartinez
Copy link
Contributor

JordanMartinez commented Feb 10, 2017

If I'm understanding you correctly, you want to do the following, right?

  1. Create a CodeArea
  2. Make all of that area's text styled to a "regular text" style at its starting state.
  3. As time goes on, calculate what text in the area (according some some pattern) should now be styled to "highlight text"
  4. As time goes on, any "highlight text"-styled text should not be restyled back to "regular text" style if it no longer adheres to some pattern.

@KnightPL
Copy link
Author

KnightPL commented Feb 10, 2017

So, first i create CodeArea object, set id (style from css file), then I add highlightning

        codeArea = new CodeArea();
        codeArea.setId("codearea");
        codeArea.richChanges()
                .filter(ch -> !ch.getInserted().equals(ch.getRemoved()))
                .subscribe(change -> {
                    codeArea.setStyleSpans(0, computeHighlighting(codeArea.getText().toLowerCase()));
                });

But still all text is colored :( Maybe Im doing something wrong

obraz

Here highlightning (without style & dark background):

obraz

I need to color rest of text, i dont have already any ideas how to do that :(
Thanks :)

@JordanMartinez
Copy link
Contributor

What happens if you don't set the area's ID? Does the highlighting work then?

And what does your computeHighlighting method's innards look like?

@KnightPL
Copy link
Author

KnightPL commented Feb 10, 2017

What happens if you don't set the area's ID? Does the highlighting work then?

It works, but default text color is black and dark background need white text or something. (I need dark background so...)

computeHighlighting is method from here:
https://github.com/TomasMikula/RichTextFX/blob/master/richtextfx-demos/src/main/java/org/fxmisc/richtext/demo/JavaKeywords.java

private static StyleSpans<Collection<String>> computeHighlighting(String text) {
        Matcher matcher = PATTERN.matcher(text);
        int lastKwEnd = 0;
        StyleSpansBuilder<Collection<String>> spansBuilder
                = new StyleSpansBuilder<>();
        while(matcher.find()) {
            String styleClass =
                    matcher.group("KEYWORD") != null ? "keyword" :
                    matcher.group("PAREN") != null ? "paren" :
                    matcher.group("BRACE") != null ? "brace" :
                    matcher.group("BRACKET") != null ? "bracket" :
                    matcher.group("SEMICOLON") != null ? "semicolon" :
                    matcher.group("STRING") != null ? "string" :
                    matcher.group("COMMENT") != null ? "comment" :
                    null; /* never happens */ assert styleClass != null;
            spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
            spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());
            lastKwEnd = matcher.end();
        }
        spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
        return spansBuilder.create();
}

@JordanMartinez
Copy link
Contributor

Wait, so you're using the computeHighlighting method from the JavaKeywords demo? Have you modified its implementation at all?

@KnightPL
Copy link
Author

KnightPL commented Feb 10, 2017

Only patterns for matcher:

private static StyleSpans<Collection<String>> computeHighlighting(String text) {
        Matcher matcher = PATTERN.matcher(text);
        int lastKwEnd = 0;
        StyleSpansBuilder<Collection<String>> spansBuilder
                = new StyleSpansBuilder<>();
        while(matcher.find()) {
            String styleClass =
                    matcher.group("MNEMONIC") != null ? "mnemonic" :
                    matcher.group("REGISTRY") != null ? "registry" :
                    matcher.group("DIRECTIVE") != null ? "directive" :
                    matcher.group("COMMENT") != null ? "comment" :
                    matcher.group("LABEL") != null ? "label_j" :
                             null; /* never happens */ assert styleClass != null;
            spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
            spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());
            lastKwEnd = matcher.end();
        }
        spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
        return spansBuilder.create();
    }

@JordanMartinez
Copy link
Contributor

It doesn't seem like you're doing anything wrong. Have you debugged it via ScenicView yet? It does seem clear that the initial CSS overrides the highlighting CSS.

You will probably need to subclass StyledTextArea in the same way that StyleClassedTextArea does, but modify the applyStyle to account for ID-specific CSS.

@KnightPL
Copy link
Author

Ok, thanks for help, I will try ;)

@liz3
Copy link

liz3 commented Feb 19, 2017

Same here i think, im trying to set the default text color, the highlighting works fine.
btw. im not even setting an id.
But the property: -fx-fill: white does not change anything, but it is working, trough if i set the property:
-fx-background-color: black just works fine.

@JordanMartinez
Copy link
Contributor

After looking at this further, I wonder if the issue is the same thing arising from #303, part of which was fixed in #398.

@liz3
Copy link

liz3 commented Feb 27, 2017

Yeah, but not the text-color, is there maybe a work around for that issue?

@JordanMartinez
Copy link
Contributor

@liz3 After looking at it a bit more, I got the default color to work by using the following CSS file:

.styled-text-area {
    -fx-background-color: black;
}
.paragraph-box > .paragraph-text > .text {
    -fx-fill: white;
}

Technically, the CSS should be .styled-text-area > .virtual-flow > .paragraph-box > .paragraph-text > .text { /* CSS */ } However, this doesn't work. Everything from paragraph-box forward works, so I'm not sure why the virtual-flow selector screws things up.

@JordanMartinez
Copy link
Contributor

I've updated the CSS Reference Guide to properly demonstrate the three selector usage to style the default text.

@JordanMartinez
Copy link
Contributor

Update: I found that if I replaced the > to denote immediate children with to denote within its children, then this CSS string works:

.styled-text-area {
    -fx-background-color: black;
}
.styled-text-area .virtual-flow .paragraph-box .paragraph-text .text {
    -fx-fill: white;
}

Thus, @KnightPL, you can achieve your goal without subclassing the area by using this CSS:

#codearea .virtual-flow .paragraph-box .paragraph-text .text {
    -fx-fill: whitesmoke;
}

@JordanMartinez
Copy link
Contributor

I've updated CSS Ref Guide to include the full selector string

@JordanMartinez
Copy link
Contributor

Actually... #codeArea .text { /* CSS */ } does the same thing as the full string above... I remembered this issue being different from what it actually was.

Forget what I said in my previous comment, @KnightPL. Instead, I found that this will work:
Given a CSS file like:

.styled-text-area {
    -fx-background-color: black;
}
#someArea .text {
    -fx-fill: white;
}

#someArea .red {
    -fx-fill: red;
}

and an application like so:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;

import java.util.Collections;

public class CssBug extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        CodeArea area = new CodeArea("initial text");
        VirtualizedScrollPane<CodeArea> vsPane = new VirtualizedScrollPane<>(area);
        area.setId("someArea");
        area.setStyle(6, area.getLength(), Collections.singleton("red"));

        Scene scene = new Scene(vsPane, 500, 200);
        scene.getStylesheets().addAll(CssBug.class.getResource("css-bug.css").toExternalForm());


        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

I can override the default whitesmoke fill with a red fill.

@JordanMartinez
Copy link
Contributor

@KnightPL, is this issue resolved?

@shadychan
Copy link

shadychan commented Apr 3, 2017

@JordanMartinez
I check out all above your answers, but sadly I didn't solve my problem in the end...

I run the XMLEditor Demo. Actually, I just want to do one thing :

make the background black and the non-highlight text white

So I modified the xml-highlighting.css like :

.text {
    -fx-fill: white;
}

.tagmark {
    -fx-fill: gray;
}
.anytag {
    -fx-fill: orangered;
}
.paren {
    -fx-fill: firebrick;
    -fx-font-weight: bold;
}
.attribute {
    -fx-fill: green;
}
.avalue {
    -fx-fill: green;
}

.comment {
	-fx-fill: mediumpurple;
}

.styled-text-area {
    -fx-background-color: black;
}

It worked, BUT the line numbers became white, too
Now I cant see them because its background is grey
image

How can I solve this problem ? Thanks~

@JordanMartinez
Copy link
Contributor

Add a lineno styleclass entry to your CSS file:

.lineno {
 -fx-background-color: black;
}

The CSS Reference Guide explains that one can style the LineNumberFactory's returning Node by using that styleclass.

@shadychan
Copy link

@JordanMartinez
It works , thank you very much !
BTW, it's a wonderful JavaFX lib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants