Improper Cascading of CSS Styles for JavaFX Label

I have created an FXML class using SceneBuilder, loaded via FXMLLoader with an associated controller. The parent panel of the widget has a style class with a pseudo-class applied to it. Interestingly, while the ToggleButton is styled correctly, the two labels are not reflecting the styles.

To test this issue, I directly assigned one of the labels a CSS class. The result was that it initially picked up the changes but did not update the text color when the pseudo-class changed.

Below is a snippet of code from my production setup for reference:

CustomButton.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="70.0" styleClass="custom-button" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="CustomButtonController">
   <children>
      <ToggleButton fx:id="selectionToggle" mnemonicParsing="false" prefHeight="70.0" prefWidth="70.0" />
      <Label fx:id="dateLabel" alignment="TOP_LEFT" contentDisplay="TOP" layoutX="5.0" layoutY="5.0" mouseTransparent="true" prefHeight="25.0" prefWidth="60.0" styleClass="custom-button" text="Date" wrapText="true" />
      <Label fx:id="eventLabel" alignment="BOTTOM_LEFT" contentDisplay="BOTTOM" layoutX="5.0" layoutY="40.0" mouseTransparent="true" prefHeight="25.0" prefWidth="60.0" text="Event" wrapText="true" />
   </children>
</Pane>

CustomButtonController.java:

/**
 * Sample Skeleton for 'CustomButton.fxml' Controller Class
 */

import java.net.URL;
import java.util.ResourceBundle;

import javafx.css.PseudoClass;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;

public class CustomButtonController {
    @FXML 
    private ResourceBundle resources;
    @FXML 
    private URL location;
    @FXML 
    private Label dateLabel; 
    @FXML 
    private ToggleButton selectionToggle; 
    @FXML 
    private Label eventLabel; 


    private Parent m_parent;


    @FXML 
    void initialize() {
        assert dateLabel != null : "fx:id=\"dateLabel\" was not injected: check your FXML file 'CustomButton.fxml'.";
        assert selectionToggle != null : "fx:id=\"selectionToggle\" was not injected: check your FXML file 'CustomButton.fxml'.";
        assert eventLabel != null : "fx:id=\"eventLabel\" was not injected: check your FXML file 'CustomButton.fxml'.";
    }

    public void setParent(Parent parent) {
        m_parent = parent;

        selectionToggle.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                m_parent.pseudoClassStateChanged(PseudoClass.getPseudoClass("state2"), selectionToggle.isSelected());
                m_parent.applyCss();
            }
        });
    }
}

Main.java:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main implements Runnable {

    @Override
    public void run() {
        JFrame frame = new JFrame("Test Frame");
        frame.setSize(800, 600);

        JPanel panel = new JPanel();
        frame.setContentPane(panel);

        FXMLLoader loader = new FXMLLoader(getClass().getResource("/CustomButton.fxml"));
        Parent parent = loader.load();

        String cssString = getClass().getResource("/CustomButton.css").toExternalForm();
        parent.getStylesheets().add(cssString);

        CustomButtonController cont = loader.<CustomButtonController>getController();
        cont.setParent(parent);

        JFXPanel jfxPanel = new JFXPanel();
        jfxPanel.setScene(new Scene(parent));

        panel.add(jfxPanel);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JFXPanel();
                Platform.runLater(new Main());
            }
        });
    }
}

CustomButton.css:

.custom-button:state2 { 
  -fx-base: cyan;
  -fx-text-fill: red;
  -fx-fill: yellow;
  -fx-stroke: purple;
}

.custom-button { 
  -fx-base: green;
  -fx-text-fill: blue;
}

Result (top is unselected, bottom is selected):

https://i.sstatic.net/ln7zt.png

Note that the ToggleButton follows -fx-base property, the date Label updates its initial color when given a CSS class directly, but does not reflect changes on toggling, and the event Label does not apply any styles from the CSS file.

Answer №1

Your FXML file applies the style class custom-button to the root pane and the dateLabel. This creates a hierarchy for CSS styling:

state2 pseudoclass is set on the root pane. In this state, the hierarchy looks like:

dateLabel has a blue text fill because of the custom-button style class with -fx-text-fill: blue;. It does not change to red when the button is selected because it does not have the state2 pseudoclass. Looked-up color values apply to the root node and propagate down the scene graph.

To achieve the desired effect, you can try the following CSS:

.custom-button {
    -fx-base: green ;
}
.custom-button:state2 {
    -fx-base: cyan ;
}
.custom-button .labeled {
    -fx-text-fill: blue ;
}
.custom-button:state2 .labeled {
    -fx-text-fill: red ;
}

Answer №2

To make sure that my labels in the custom parent class displayed the correct color, I decided to use the "inherit" attribute. The CSS code I ended up with is shown below:

CustomButton.css:

.custom-button:state2 { 
  -fx-base: white;
  -fx-text-fill: red;
}

.custom-button { 
  -fx-base: black;
  -fx-text-fill: cyan;
}

.label {
    -fx-text-fill: inherit;
}

Another option would be to set a look-up color.

CustomButton.css:

.custom-button:state2 { 
  -fx-base: white;
  -labelColor: red;
}

.custom-button { 
  -fx-base: black;
  -labelColor: cyan;
}

.label {
    -fx-text-fill: -labelColor;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Designing a Stylish Notification Bar using HTML and CSS

Take a look at the code I'm currently working on: <div style="width:100%; position:absolute; border:0px; background-color:#232323; color:#ffffff; padding-top:5px; padding-bottom:5px; font-size:12px" align="center"> TEST TEST TEST TEST TEST Th ...

What is the best way to apply the background color from a parent div to a span element?

Is there a way to make the background color of the Reset Password section span the full width of the outer div and header section? html: <div class="forgot-inner"> <!--Forgot-header--> <div class="forgot-hea ...

showing <li> elements on both the left and right sides based on the specified condition

I am struggling to show messages one by one using the 'li' tag, with the intention of having our messages appear on the right side and others on the left side in a react Chat app. However, the issue arises when I attempt to use float left or floa ...

Prevent Bootstrap 5 input fields from automatically adjusting to the height of a CSS grid cell

Below is some Bootstrap 5 markup that I need help with. The first example is incorrect. I don't want the Bootstrap input to be the same height as the grid cell. The second example is right, but I want to achieve the same result without using a wrapp ...

How can I prevent this image from expanding within the section?

I am currently utilizing Bootstrap 4.6 and WordPress along with the ACF Plugin, and I find myself in need of assistance. I am facing an issue where the height of a row in a section needs to adjust according to the content within a column, but the image wit ...

Is there a way to eliminate the bottom padding in a textarea field?

Need help removing the bottom padding in a textarea? Check out this code snippet: $('textarea').css("height", $("textarea").prop("scrollHeight")) textarea { width: 300px; resize: none; margin: 0; padding: 0; } <script src="https://a ...

The CSS click event is not triggering

I can't seem to trigger the click event in CSS This is my code: <input name="btn" type="button" onclick="~/Default22.aspx" value="Home" class="classname" style="position:absolute; left: 286px; top: 160px; margin-bottom: 0px;"/> and I've ...

`Modified regions determined by cursor location`

I am working with a split layout featuring two columns, and I need the ability to make each column separately scrollable. Due to using a specialized scroll-to function, I cannot use overflow-y: scroll; or overflow: auto;. I am looking for alternative solut ...

Change the border color when summernote is in focus状态

My goal is to change the border color of the summernote div to a light blue when it is focused, and then set it back to neutral when it loses focus. To remove the shadow around the div, I used the following CSS code: div.note-editor.panel.panel-default { ...

Guide on changing the CSS of MUI parent components to set the display of buttons to 'block' in React

I'm facing a challenge with my modal design for mobile view. I need the buttons to display in a stacked format, one above the other, taking up the full width of the modal. I've been exploring ways to override the existing CSS within the component ...

Enhancing the appearance of CSS Tables

I need help with applying a gradient line below each row of data that I am fetching from my database and displaying in a <table>. I've been able to achieve the design using an <hr> element, as shown here: http://jsfiddle.net/ghrw3k8e/. Ho ...

Activate a horizontal accordion when the button is clicked

I am looking to implement a dynamic horizontal accordion feature triggered by a button click. I came across this example for creating a horizontal accordion. It works well, but it is limited to only 8 accordions. I want the flexibility for users to add as ...

Encountered an issue when attempting to transmit a byte array to a JAX-WS web service

Greetings! I have created a small example to demonstrate my issue. Below is the code for my web-service: package service; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public class BytesService { @WebMethod public String redire ...

I am encountering issues with setting a background image in Bootstrap 3.1.1 while trying to achieve a par

I'm struggling to add a background image to my bootstrap site. I'm attempting to create a parallax site using stellar.js, and while the site is functional with text on each slide and correct scrolling links, the images just won't load. Despi ...

Integrate a new function into several Java classes simultaneously using IntelliJ

Looking for a way to quickly add a new method to multiple Java classes within the test definition layer in Intellij IDE. The method should be added to all classes within a specific package. Any suggestions on how to achieve this efficiently? ...

Can you explain the mechanics behind Angular Component CSS encapsulation?

Is it possible to avoid CSS conflicts when using multiple style sheets? Consider Style 1: .heading { color: green; } And Style 2: .heading { color: blue; } If these two styles are applied in different views and rendered on a layout as a Partial Vi ...

Hovering over the top menu items in AngularJS will reveal dropdown submenus that will remain visible even when moving the cursor

I am facing an issue where my top menu has links that display a dropdown of additional menu items upon hovering. I have attempted to use onmouseover and onmouseleave events to control the visibility of the sub menu. However, I have encountered a problem ...

Creating a personalized gradient using Tailwind CSS and Daisy UI framework

I’m attempting to incorporate a unique gradient into my next.js application with the help of Tailwind CSS and Daisy UI. Below is the specific code snippet I plan on using: background: linear-gradient(180deg, rgba(192, 192, 192, 0.04) 0%, rgba(201, 180, ...

Cosmos DB causing SocketException in Spring Boot application

In my Spring Boot application, I am connecting to a remote Cosmos DB on Azure using the Mongo DB API. The connection is made with the spring-boot-starter-data-mongodb dependency using default settings. Periodically, I encounter a SocketException error, ca ...

The anchor tag causes the tooltip to display outside of the td element

One of my requirements is to display the click percentage for each link in an HTML template that is dynamically fetched from a database. I attempted to show the click percentage for each anchor link by adding them to the `data-title` attribute using jQuery ...