0

I've got a problem where the :hover CSS option is not working properly. This is the CSS:

.body:hover {
    -fx-background-color: #b8fffd;
}

.exitIcon:hover {
    -fx-fill: gray;
}

The body hover works fine but .exitIcon does not. In case I misspelled the className I also tried to use the FontAwesomeIconView selector but it still didn't work.

Here is the FXML code:

<AnchorPane prefHeight="800.0" prefWidth="1000.0" styleClass="body" stylesheets="@styles/lightSignalsStyles.css" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.main.captainscompass.controllers.LightSignalsController">
   <HBox alignment="CENTER_LEFT" prefHeight="200.0" stylesheets="@styles/lightSignalsStyles.css" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <FontAwesomeIconView glyphName="ARROW_LEFT" size="50" styleClass="exitIcon">
         <cursor>
            <Cursor fx:constant="HAND" />
         </cursor>
      </FontAwesomeIconView>
   </HBox>
   <HBox alignment="CENTER" prefHeight="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <Label text="Light Signals Quiz" textAlignment="CENTER">
         <font>
            <Font size="30.0" />
         </font>
      </Label>
   </HBox>
   <HBox alig`nment="CENTER_RIGHT" layoutX="10.0" layoutY="10.0" prefHeight="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
         <Image url="@assets/sailboaticon.png" />
      </ImageView>
   </HBox>
</AnchorPane>

So I definitely didn't misspell the class name nor the file name since .body is actually working. And if I remove ":hover" the style is applied as expected. I really don't have a clue what's going on here as for every single other usage of :hover it works.

NOTE: This is not my main scene. I changed it using this logic:

FXMLLoader loader = new FXMLLoader(App.class.getResource(LIGHT_SIGNALS_FXML));
        stage = (Stage)((Node)event.getSource()).getScene().getWindow();
        Scene scene = new Scene(loader.load(), 1000, 800);

And in this scene NO events work not even something like onKeyPressed. But I still don't know what caused it.

Tymo Tymo
  • 93
  • 1
  • 6
  • Your logic for changing a scene does not change a scene, it just creates a new scene and does not set it on a stage. If you want debugging help, you should provide a [mcve]. – jewelsea Aug 22 '23 at 16:33
  • FontAwesome hasn't been updated in five years. You are probably better off using a maintained modern alternative such as Ikonli. – jewelsea Aug 22 '23 at 18:40

1 Answers1

1

I can't reproduce this (JavaFX 20.0.2).

fx-fill is not an inherited style. You can't set it on a parent and expect it to apply to the descendants of the parent. (This statement is just a FYI, you aren't doing that in your question).

Looking at the font awesome code (because I don't know where the documentation for it is), the FontAwesomeIconView is a child of Text, so -fx-fill can apply to it. The font awesome code also sets a style class on the icons of glyph-icon. Also, :hover is a generic psuedoclass that can apply to any node.

If you want to set the color on hover of all of the font awesome icons in a container you can use this:

.container .glyph-icon:hover {
    -fx-fill: red;
}

To have different hover colors for individual glyphs, then you can instead set it on the individual glyphs, using !important to override previous fill styling if necessary.

.gear-icon:hover {
    -fx-fill: green !important;
}

Example output on hovering over some icons using a modified version of the code from this answer.

hover gear

fonts.css

.container .glyph-icon:hover {
    -fx-fill: red;
}

.gear-icon:hover {
    -fx-fill: green !important;
}

fonts.fxml

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

<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.HBox?>

<HBox styleClass="container" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <FontAwesomeIconView glyphName="MUSIC" size="1.5em" />
        <FontAwesomeIconView glyphName="GEAR" size="1.5em" styleClass="gear-icon" />
        <FontAwesomeIconView glyphName="FILE" size="1.5em" />
        <FontAwesomeIconView glyphName="DASHBOARD" size="1.5em" />
        <FontAwesomeIconView glyphName="HEART" size="1.5em" />
    </children>
    <padding>
        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
    </padding>
</HBox>

FontApplication.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.Objects;

public class FontApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(FontApplication.class.getResource("fonts.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        scene.getStylesheets().add(Objects.requireNonNull(FontApplication.class.getResource("fonts.css")).toExternalForm());
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406