Reputation: 51
I wish to find a method to get the Text node of a TextArea without using the CSS properties. The Text node of JavaFX exposes the method setUnderline(boolean) through which I can set the underline property of a TextArea; the TextArea, instead, doesn't expose the same method. In addition, the TextArea.getText() method returns a String instead of a Text object. So, I solved the problem as follow: In the code,
// Fields..
private final PseudoClass pseudoClass = PseudoClass.getPseudoClass("underlined");
private final SimpleBooleanProperty underlinedProperty = new SimpleBooleanProperty(false);
private final TextArea textArea = new TextArea();
[...]
// In a method (ex. in the constructor)..
{
textArea.setId("textArea");
underlinedProperty.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
Node node = textArea.getScene().lookup("#textArea .text");
node.pseudoClassStateChanged(pseudoClass, newValue);
}
});
}
[...]
// The class exposes the getter method for the underlinedProperty
public SimpleBooleanProperty getUnderlinedProperty() {
return underlinedProperty;
}
Now, I've create a CSS sheet with this code:
#textArea .text {
/* some styles */
-fx-underline: false;
}
#textArea .text:underlined {
-fx-underline: true;
}
Finally, the above class is called in some other classes:
{
'handleOfClassInPoint1'.getUnderlineProperty().set(true); // or false
}
The problem is the lookup() method: this method returns a not null value only if all the fx nodes were created, i.e. only after some graphical result. I wish to find a procedure to set the underline property of a TextArea without using CSS (ex. a toggle button manages the underline property: the text of a TextArea is underlined if the toggle is selected). Anyone can help me? Thank you so much!
Upvotes: 2
Views: 711
Reputation: 45806
Based on your description in the question comments, I would recommend the following.
Create a custom TextArea
that looks something like this:
public class CustomTextArea extends TextArea {
private static final PseudoClass UNDERLINED = PseudoClass.getPseudoClass("underlined");
private final BooleanProperty underlined = new SimpleBooleanProperty(this, "underlined") {
@Override
protected void invalidated() {
pseudoClassStateChanged(UNDERLINED, get()); // update PseudoClass state to match
// the current value of the property
}
};
// property access methods
public final void setUnderlined(boolean underlined) {
this.underlined.set(underlined);
}
public final boolean isUnderlined() {
return underlined.get();
}
public final BooleanProperty underlinedProperty() {
return underlined;
}
// constructor
public CustomTextArea(String text, boolean underlined) {
super(text);
setUnderlined(underlined);
getStyleClass().add("custom-text-area"); // to allow specific CSS styling
}
}
Then in your CSS you would do:
.custom-text-area .text {
-fx-underline: false;
}
.custom-text-area:underlined .text {
-fx-underline: true;
}
The CSS is set on any Text
node that is a descendant of aCustomTextArea
.
The first CSS rule (the one without ":underlined") may not even be necessary since the default of -fx-underline
for a Text
node is false
.
Then to query whether or not the text is underlined is a simple matter of calling area.isUnderlined()
where area
is an instance of CustomTextArea
.
To maintain the correct visual state you could bind the underlined
property of the CustomTextArea
bidirectionally to the selected
property of a ToggleButton
. When one changes the other will reflect that change.
If you want to style only a specific CustomTextArea
then you can still give it an ID and reference it in the CSS with #ID
.
Upvotes: 1