Reputation: 339
I'm playing around with JavaFx and seem to have a problem getting the menu-bar to look exactly how I want using css.
The main menu bar seems to be okay. When I hover or select the background becomes darker and the font becomes blue ("Edit" in the example). The same with the menu-item below ("Delete" in the example) but it seems that the other non-hovered, non-selected menu-items also get blue text instead of remaining white.
I've tried looking at https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html and other StackOverflow articles, and just a bunch of trial and error, but nothing seems to do it. Any tips?
Source code is at https://github.com/pnogas/TornadoTest, but I'll have snippets below in case I ever delete it from github for future people reading this.
FXML generated from scene builder then auto-formatted from intelliJ IDE
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.paulnogas.log.analyzer.MainView">
<MenuBar stylesheets="@test.css" VBox.vgrow="NEVER">
<Menu mnemonicParsing="false" text="Edit">
<MenuItem mnemonicParsing="false" text="Undo"/>
<MenuItem mnemonicParsing="false" text="Redo"/>
<SeparatorMenuItem mnemonicParsing="false"/>
<MenuItem mnemonicParsing="false" text="Cut"/>
<MenuItem mnemonicParsing="false" text="Copy"/>
<MenuItem mnemonicParsing="false" text="Paste"/>
<MenuItem mnemonicParsing="false" text="Delete"/>
<SeparatorMenuItem mnemonicParsing="false"/>
<MenuItem mnemonicParsing="false" text="Select All"/>
<MenuItem mnemonicParsing="false" text="Unselect All"/>
</Menu>
and here's the relevant parts of test.css
.menu-bar,
.menu,
.menu-item {
-fx-background-color: #222222;
}
.menu-bar .label,
.menu .label,
.menu-item .label {
-fx-text-fill: white;
}
.menu:hover,
.menu:showing,
.menu-item:hover {
-fx-background-color: #111111;
}
.menu:hover .label,
.menu:showing .label,
.menu-item:hover .label {
-fx-text-fill: #80CBC4;
}
(I know TornadoFX prefers type-safe CSS in Kotlin to a normal *.css file, but I think I want to do it in *.css for now. I want to use Scene Builder occasionally. I also like the strict forcing of separation of concerns. When working in Kotlin only I tend to lose discipline and end up with spaghetti code mixing structure, style, functionality in one ugly Kotlin class. Maybe I'll move it over to pure Kotlin later).
Upvotes: 0
Views: 352
Reputation: 209418
The selector (as an example)
.menu:showing .label
will select all labels that are descendants of a showing menu. So this includes labels which are child nodes of a menu item which is a child node of a showing menu, etc. Here you want to only select labels which are immediate children of a showing menu. The correct selector syntax for that is
.menu:showing > .label
The CSS you need is
.menu-bar,
.menu,
.menu-item {
-fx-background-color: #222222;
}
.menu-bar > .label,
.menu > .label,
.menu-item > .label {
-fx-text-fill: white;
}
.menu:hover,
.menu:showing,
.menu-item:hover {
-fx-background-color: #111111;
}
.menu:hover > .label,
.menu:showing > .label,
.menu-item:hover > .label {
-fx-text-fill: #80CBC4;
}
Another solution would be to explicitly set the text color of labels in menu items in showing menus with and without the :hover
psuedoclass:
.menu-bar,
.menu,
.menu-item {
-fx-background-color: #222222;
}
/* Note added .menu:showing .menu-item .label selector */
.menu-bar .label,
.menu .label,
.menu-item .label,
.menu:showing .menu-item .label {
-fx-text-fill: white;
}
.menu:hover,
.menu:showing,
.menu-item:hover {
-fx-background-color: #111111;
}
.menu:hover .label,
.menu:showing .label,
.menu:showing .menu-item:hover .label {
-fx-text-fill: #80CBC4;
}
Upvotes: 3