Setting Background of TextArea - css

I would like to provide for user possiblity to select color of TextArea:
private void updateTextArea(){
textArea.setStyle("-fx-text-fill: #" + textColor + "; -fx-background-color: #" + backgroundColor);
}
however this doesnt change color of whole background. Ive found on the Internet that to change backgroud of text Area I need to do something like this in external CSS file.
.text-area .content {
-fx-background-color: black ;
}
how Can I do this with setStyle()?

You can do this by fetching the content node out of the TextArea and applying the style to it. But it works only after the TextArea is shown on the stage.
Usage :
Node node = textArea.lookup(".content");
node.setStyle("-fx-background-color: black;");

Related

Different behavior of Text and Labeled controls in combination with css

I am working on a Javafx application and I tried to add some Labels, Buttons and Texts, which resizes when the user resizing the Scene. All Nodes are inside a VBox, which itself is inside a StackPane.
My test application:
public class Test extends Application
{
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(final Stage primaryStage)
{
StackPane pane = new StackPane();
VBox box = new VBox();
box.setAlignment(Pos.CENTER);
Label l = new Label("Label");
Text t = new Text("Text");
t.getStyleClass().add("test");
Button b = new Button("Button");
pane.heightProperty().addListener(listener ->
{
double h = pane.getHeight()/5;
l.setFont(Font.font(l.getFont().getFamily(), h));
t.setFont(Font.font(t.getFont().getFamily(), h));
b.setFont(Font.font(b.getFont().getFamily(), h));
});
box.getChildren().addAll(l, t, b);
pane.getChildren().add(box);
primaryStage.setScene(new Scene(pane));
primaryStage.getScene().getStylesheets().add(Path.of("test.css").toUri().toString());
primaryStage.show();
}
}
If I resize the Stage it works as expected. But unfortunately only with pure Java code.
Because after adding my css file, the Labeled controls behave different. While the Text elements continue to change in size, the Labels and Buttons does not change their size anymore.
My css file, which does not work:
.label
{
-fx-text-fill: red;
-fx-font-family: impact;
}
.test
{
-fx-fill: red;
-fx-font-family: impact;
-fx-font-size: 2em;
}
.button
{
-fx-text-fill: red;
-fx-font-size: 2em;
}
I asked myself what I did wrong and have tested different css states. I found out, when I omit font values in css it works, otherwise it does not. Therewhile it does not matter which font value occurs, only one font value is required to miss the behavior.
My css file, which works:
.label
{
-fx-text-fill: red;
//-fx-font-family: impact;
}
.test
{
-fx-fill: red;
-fx-font-family: impact;
-fx-font-size: 2em;
}
.button
{
-fx-text-fill: red;
//-fx-font-size: 2em;
}
1. Question: -has changed, see below-
Do I missunderstand something about css and Javafx, or did I something wrong in my css file or is there a bug?
2. Question: -solved-
Have I to put the font values with java code or is there an other way to add the font?
Thank You for helping!
Update
As recommended I have studying the follow guide:
https://openjfx.io/javadoc/14/javafx.graphics/javafx/scene/doc-files/cssref.html
The JavaFX CSS implementation applies the following order of precedence:
The implementation allows designers to style an application by using style sheets to override property values set from code. For example, a call to rectangle.setFill(Color.YELLOW) can be overridden by an inline‑style or a style from an author stylesheet. This has implications for the cascade; particularly, when does a style from a style sheet override a value set from code? The JavaFX CSS implementation applies the following order of precedence: a style from a user agent style sheet has lower priority than a value set from code, which has lower priority than a Scene or Parent style sheet. Inline styles have highest precedence. Style sheets from a Parent instance are considered to be more specific than those styles from Scene style sheets.
In my case this means, I will use the inline style to make it proper.
thus the 2. Question is solved
But, because of Parent style sheet > value set from code, it also means, all Nodes are not allowed to change theire size, even the Text Node.
Therefore I changed my 1. Question to:
Why does the JavaFX CSS order of precedence differ between Text and Controls
Question 1:
It's not a bug, it's a conflict of priorities. .setFont() has a lower priority than that CSS. Just replace .setFont() to .setStyle() and sample will work as you planned:
l.setStyle("-fx-font-size:" + h + ";");
t.setStyle("-fx-font-size:" + h + ";");
b.setStyle("-fx-font-size:" + h + ";");
Question 2:
Try to keep all about styles in CSS. It's the best practice.

JavaFX - Set different hover colors on toggle button based on toggle state

I have a toggle button in my program that starts/stops a script. I would like for this button to be green and say "START" when the button is not selected, and red and say "STOP" when it is selected. More importantly, I would like the unselected hover color to be a slightly darker version of the original green, and the selected hover color to be a slightly darker version of the red color. My current CSS for this button looks like this:
#startStopButton {
-fx-border-color:#d4d4d4;
-fx-background-color:#85eca5;
-fx-background-image: url("startButton.png");
-fx-background-size: 50px;
-fx-background-repeat: no-repeat;
-fx-background-position: 80% 50%;
-fx-alignment: CENTER_LEFT;
-fx-effect: dropshadow(three-pass-box, #e7e7e7, 15, 0, 0, 0);
}
#startStopButton:hover {
-fx-background-color:#80dc9c;
}
#startStopButton:selected{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
#startStopButton:selected:focused{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
Currently, this will work fine, except for when the button turns red. In this case, there is no hover effect. Within my FXML controller, there is a function that is activated every time this button is clicked:
private void startStopClick()
{
if(startStopButton.isSelected())
{
startStopButton.setText(" STOP");
// startStopButton.setStyle()
}
else {
startStopButton.setText(" START");
}
}
Is there any way to 1) set the button text within CSS so that I can leave that out of my controller?
2) Get the current toggle button state in CSS, so that I can have multiple hover effects. For example, something like this:
#startStopButton:unselected{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
If there is no way to do this in CSS, can I set the hover styles in the Java code in the FXML controller?
CSS properties are only available for the look of nodes. With a few exceptions the basic JavaFX nodes don't allow you to specify content via CSS. The text property of buttons is no exception; it cannot be set using CSS.
As for the colors: The rules occuring last override values assigned by rules with the same precedence occuring before them. This means the background color assigned by the rules for #startStopButton:selected and #startStopButton:selected:focused always override the color #startStopButton:hover assigns.
Since in both cases you want a darker color when hovering, the derive function and a lookedup color may work for you.
Example
#Override
public void start(Stage primaryStage) {
ToggleButton btn = new ToggleButton();
btn.getStyleClass().add("start-stop");
btn.textProperty().bind(Bindings.when(btn.selectedProperty()).then(" STOP").otherwise(" START"));
Pane p = new Pane(btn);
Scene scene = new Scene(p);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
style.css
.start-stop.toggle-button {
base-color: #85eca5;
-fx-background-color: base-color;
}
.start-stop.toggle-button:selected {
base-color: #ff6060;
}
.start-stop.toggle-button:hover {
-fx-background-color: derive(base-color, -20%);
}
If you cannot use derive since you need to specify different colors for all 4 states you could still rely on looked-up colors to avoid relying on the rule ordering:
.start-stop.toggle-button {
unselected-color: blue;
selected-color: yellow;
-fx-background-color: unselected-color;
}
.start-stop.toggle-button:hover {
unselected-color: red;
selected-color: green;
}
.start-stop.toggle-button:selected {
-fx-background-color: selected-color;
}

Set a button of custom color to a disabled style

I have a class that inherits QWidget. Under certain circumstances, I wish to set it disabled.
The widget has some color buttons, that are set from a list of colors:
void MyWidget::colorUpdate(QString color)
{
if(!color.isEmpty())
{
QString foreground = (QColor(color).lightness() < 125 ? "white" : "black");
m_colorButton->setStyleSheet("color: " + foreground + "; background-color: " + color);
}
}
Calling myWidget.setEnabled(enabledOption); disables the widget, grays out all text and every other items in the widget - except for these color buttons.
So I am thinking of making my own action:
void MyWidget::setWidgetEnabled(bool enabled)
{
this->setEnabled(enabled);
// what else ?
}
How can I make my buttons - of a background color and text color that I don't know, but the button does - have that "disabled look" ?
(Note - the color update works on disabled items too - that is not really complicated though - whatever style sheet I apply on setting widget disabled can be applied in the colorUpdate function).
I just don't know how to apply a stylesheet with that gray shade - or possibly have a "disabled" option in the stylesheet even...
What do colors look like in "disabled" ?
To set your own style for the disable state.
You can set a special style for disabled state in the stylesheet :
m_colorButton->setStyleSheet(":enabled { color: " + foreground
+ "; background-color: " + color
+ " } :disabled { color: " + disabledForeground
+ "; background-color: " + disabledColor + " }");
edit: changed code for the widget instead of a global stylesheet.
To keep the default disabled style. You can set your custom style only for the enabled state, then when the widget is disabled the style does not apply :
m_colorButton->setStyleSheet(":enabled { color: " + foreground
+ "; background-color: " + color + "}");

How to wrap text of a javafx chart legend

Can anyone please help me with wrapping the text in a legend of a javafx chart. I have pie charts and bar charts. All the legends are placed at bottom. I tried the following but couldn't get it working.
for (Node node : pie.lookupAll(".chart-legend")) {
if (node instanceof Text) {
System.out.println("Text instance");
((Text) node).setWrappingWidth(380);
((Text) node).setManaged(true);
}
if (node instanceof Label) {
System.out.println("Label instance");
((Label) node).setWrapText(true);
((Label) node).setManaged(true);
((Label) node).setPrefWidth(380);
}
}
EDIT:
See the highlighted part. Still some text is not visible.
I finally got it. Trying to wrap text in css didn't work as label width cannot be controlled there. So the following code can be used to wrap the text programmatically.
for (Node node : pie.lookupAll(".chart-legend-item")) {
if (node instanceof Label) {
System.out.println("Label instance");
((Label) node).setWrapText(true);
((Label) node).setManaged(true);
((Label) node).setPrefWidth(380);
}
}
Did you have a look at the CSS documentation?
This link is refering to the chart legend section:
JavaFX CSS Reference
As mentioned, it's of the type Label, so we can have a look here as well.
-fx-wrap-text possibly does the trick. Of course you would need to write and attach your own CSS file to your program...
For a more detailed example, please refer to your JDKs jfxrt.jar, unzip it and look for the modena.css, which is the default CSS file.
Regards.
Daniel
Edit: I got the following snipped to actually have an impact on or application after all:
.chart-legend {
-fx-background-color: transparent;
-fx-padding: 20px;
}
.chart-legend-item-symbol {
-fx-background-radius: 0;
}
.chart-legend-item {
-fx-text-fill: #191970;
}
But it is important, where you place it in your CSS. In my first attempt, I placed it above the CSS rule, which set the default label text color.
When I noticed this, I put it at the end of my CSS file: et vóila - it worked.
So please have a second look, that your placed accordingly in your own CSS.

CSS Selectors is JavaFX setStyle() method

There is an option to bind CSS files to add style to JavaFX components.
But I want to change some properties dynamically in code.
There is a setStyle() method but there is not enough documentation available on using it.
I want to change the hover color from the setStyle() method instead of the .css file.
Here is the code for the .css file
.list-cell:filled:hover
{
-fx-background-color: #0093ff;
-fx-text-fill: white;
}
and I want to change the hover color from the setStyle() method dynamically like this:
noteListView.setStyle(
":filled:hover{" +
"-fx-background-color: #65ffb0;" +
"-fx-text-fill: white;" +
"}");
But this does not work. Any help is appreciated. Thanks.
Why don't you try something like that, I used it to change the color of a specific serie on a chart which be selected from a tableview.
table.getSelectionModel().selectedIndexProperty().addListener( (observable, oldValue, newValue) -> changeId(oldValue, newValue));
public void changeId(Number oldV, Number newV){
if(oldV.intValue() != -1){
lineChart.getData().get(oldV.intValue()).getNode().setId("serie-unselect");
}
if(newV.intValue() != -1){
lineChart.getData().get(newV.intValue()).getNode().setId("serie-select");
}
}
Then in the css file, you add #serie-select{} and #serie-unselect{} with good options.

Resources