0

I would like to have entity (control or property) which has different states, which are possible to be colored by CSS.

For example, regard TextField, which can contain two sort of values, normal and erroneous. Once it contain erroneous value, it should be displayed "red". But the actual color should be definable from CSS.

Is this possible to implement?

I found plenty of Styleable* interfaces or classes, but they are looked like able to accept any style.

Can I write and entity, which derives it's style from the value?

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385

2 Answers2

3

You can use Node.pseudoClassStateChanged:

TextField tf = new TextField();
final PseudoClass shortText = PseudoClass.getPseudoClass("short");
final PseudoClass longText = PseudoClass.getPseudoClass("long");
tf.textProperty().addListener((observable, oldValue, newValue) -> {
    tf.pseudoClassStateChanged(shortText, false);
    tf.pseudoClassStateChanged(longText, false);
    if (newValue!=null && !newValue.isEmpty()) {
        if (newValue.length() < 5) {
            tf.pseudoClassStateChanged(shortText, true);
        } else {
            tf.pseudoClassStateChanged(longText, true);
        }
    }
});

With a css like this:

.text-field:short {
 -fx-background-color: #ffaaaa;
}
.text-field:long {
 -fx-background-color: #aaffaa;
}

Although to be honest I'm not entirely sure what are the pros and cons of Style Class vs. Pseudo Class.

fabian
  • 80,457
  • 12
  • 86
  • 114
Itai
  • 6,641
  • 6
  • 27
  • 51
  • 1
    `PseudoClass` is much easier to manage for a boolean state, as it is either set or not set. Regular CSS classes are stored as a `List` of `String`s associated with each node. Since it's a `List` it can contain duplicates. So while you can add and remove style classes from that list, you have to be careful not to add multiple copies of a given style class (unless that's really what you want, for some reason). Consequently, for use cases like this, using `PseudoClass`es tends to result in cleaner code. – James_D Apr 27 '16 at 11:44
  • Thanks for the explanation! Is there a specified behavior when a style class is present more than once for a node (either for JavaFX or plain CSS)? I'm not sure I can think of a reasonable behavior besides treating it as appearing only once. – Itai Apr 27 '16 at 12:26
  • The CSS matching rules just look to see if the style class is present on a node or not. So if it's added multiple times in the list, then it matches the class. Problems can arise when you try to remove it, though: `myNode.getStyleClass().remove("some-style");` removes the first occurrence, so if you've inadvertently added it multiple times, this (probably) won't have the effect you're looking for... It can be really tricky, e.g. in custom cell implementations where you don't have much control over when `updateItem()` is invoked. – James_D Apr 27 '16 at 12:32
  • 1
    Personally I'd prefer not changing the pseudo class state multiple times, if it can be avoided, which could easily be achieved using 2 `boolean` variables... – fabian Apr 27 '16 at 15:13
0

On change event of particular property, you can change style class of that entity(control or property) in order to apply multiple colors.
For this, you need to add multiple color styles in CSS and then you can change the Style Class by using below code.

 textfield.getStyleClass().add("red");  

For example, on action event of TextField, you can check which value user have entered in TextField and if entered value is "erroneous" then get the object of text field and set the style class name to it using above code.

PrashantP
  • 182
  • 1
  • 12