我正在尝试根据场景背景为我的菜单栏设置不同的样式。
我所有的 Controller 都有一个面板来加载我的菜单栏。
HomePage.java
public class HomePage implements Initializable {
@FXML
private VBox menuPane;
@FXML
private GridPane gridPane;
@Override
public void initialize(URL location, ResourceBundle resources) {
Menu menu = new Menu();
menu.loadMenuBar(menuPane);
menu.setMenuBarColor("#000"); // PROBLEM HAPPENS HERE
}
还有我的Menu.Java 类
import javafx.scene.control.MenuBar;
public class Menu {
@FXML
private MenuBar menuBar;
public void loadMenuBar(Pane pane) {
try {
pane.getChildren().add(FXMLLoader.load((getClass().getResource("/ui/FXML/Menu.fxml"))));
} catch (Exception e) {
e.printStackTrace();
}
}
public void openHomepage() {
Stage stage = Main.getPrimaryStage();
try {
Parent root = FXMLLoader.load(getClass().getResource("/ui/FXML/HomePage.fxml"));
changeScene(root);
stage.setTitle("Some title");
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void setMenuBarColor(String color){
menuBar.setStyle("-fx-my-menu-color-highlighted: " + color + ";");
}
对于这个例子,我使用 HomePage.Java Controller ,但它运行良好,我的菜单显示在每个场景中。
我也有我的 Menu.css :
* {
-fx-my-menu-color: #FFFFFF;
-fx-my-menu-color-highlighted: #006886;
-fx-my-menu-font-color: #000;
-fx-my-menu-font-color-highlighted: #fff;
}
.menu-bar {
-fx-background-color: -fx-my-menu-color;
}
问题是,我想更改 MenuBar 的背景(通过更改 CSS 变量“-fx-my-menu-color”),但无论我尝试什么,它要么什么都不做,要么抛出 NullPointerException .
编辑:使用“setMenuBarColor()”和stacktrace的更清晰的示例:
javafx.fxml.LoadException:
/U:/Developpement/IntelliJ/Statistiques/out/production/Statistiques/ui/FXML/HomePage.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at main.Main.start(Main.java:35)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at main.Menu.setMenuBarColor(Menu.java:35)
at main.HomePage.initialize(HomePage.java:38)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 12 more
菜单.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.input.KeyCodeCombination?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="0.0" prefWidth="663.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.Menu">
<MenuBar fx:id="menuBar" layoutY="2.0" opacity="0.9" prefHeight="0.0" prefWidth="663.0" stylesheets="@../CSS/Menu.css">
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
<Menu mnemonicParsing="false" style="-fx-font-weight: bold;" styleClass="menu-title" text="STATISTIQUES">
<MenuItem accelerator="backspace" mnemonicParsing="false" onAction="#openHomepage" style="-fx-font-weight: normal;" text="Revenir à l'accueil " />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#openSettings" text="Paramètres" />
<MenuItem mnemonicParsing="false" onAction="#showPatchnote" style="-fx-font-weight: normal;" text="Patchnote" />
<MenuItem mnemonicParsing="false" onAction="#changeLogs" style="-fx-font-weight: normal;" text="Changelogs" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem accelerator="Shortcut+Q" mnemonicParsing="false" onAction="#closeButtonAction" style="-fx-font-weight: normal;" text="Quitter Statistiques" />
</Menu>
<Menu mnemonicParsing="false" text="Fichier">
<MenuItem mnemonicParsing="false" onAction="#print" text="Imprimer" />
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<MenuItem accelerator="Shortcut+Z" mnemonicParsing="false" text="Annuler" />
<MenuItem accelerator="Shortcut+Y" mnemonicParsing="false" text="Rétablir" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem disable="true" mnemonicParsing="false" text="Préférences" />
</Menu>
<Menu mnemonicParsing="false" text="Département AVJ">
<MenuItem mnemonicParsing="false" onAction="#openSelectAvj" text="Menu de sélection" />
<MenuItem mnemonicParsing="false" onAction="#openContingentPage" text="Contingent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#openASDB" text="ASDB Engine" />
</Menu>
<Menu mnemonicParsing="false" text="Département SI">
<MenuItem mnemonicParsing="false" onAction="#openSelectSi" text="Menu de sélection" />
<MenuItem mnemonicParsing="false" onAction="#openIndicateursPage" text="Indicateurs annuels" />
<MenuItem mnemonicParsing="false" onAction="#openComparaisonAnnees" text="Comparaison années" />
<MenuItem mnemonicParsing="false" onAction="#openComparaisonCentres" text="Comparaison centres" />
<MenuItem disable="true" mnemonicParsing="false" text="Comparaison régions" />
<Menu mnemonicParsing="false" onAction="#openSelectVisitesPatients" text="Comparaison Visites/Patients">
<MenuItem mnemonicParsing="false" onAction="#openVisitesCentres" text="Visites / Centres"/>
<MenuItem mnemonicParsing="false" onAction="#openVisitesLocalites" text="Visites / Localités"/>
<SeparatorMenuItem mnemonicParsing="false"/>
<MenuItem disable="true" mnemonicParsing="false" text="Patients / Centres"/>
<MenuItem disable="true" mnemonicParsing="false" text="Patients / Localités"/>
</Menu>
<SeparatorMenuItem mnemonicParsing="false" />
<Menu mnemonicParsing="false" text="Rapports">
<MenuItem mnemonicParsing="false" onAction="#pdfActivite" text="Rapport d'activité" />
<MenuItem mnemonicParsing="false" onAction="#pdfGestion" text="Rapport indicateurs de gestion" />
</Menu>
</Menu>
<Menu mnemonicParsing="false" text="Outils">
<MenuItem mnemonicParsing="false" onAction="#openASDB" text="ASDB Engine" />
<MenuItem mnemonicParsing="false" onAction="#detectJavaVersion" text="JAVA Version">
<accelerator>
<KeyCodeCombination alt="UP" code="J" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator></MenuItem>
<MenuItem mnemonicParsing="false" onAction="#openConnectionTest" text="Tester les connexions">
<accelerator>
<KeyCodeCombination alt="UP" code="T" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator></MenuItem>
</Menu>
<Menu mnemonicParsing="false" text="?">
<MenuItem disable="true" mnemonicParsing="false" text="Aide" />
<MenuItem disable="true" mnemonicParsing="false" text="Signaler un bug" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#openAboutWindow" text="À propos de Statistiques" />
</Menu>
</MenuBar>
</AnchorPane>
最佳答案
我在查看您的代码和 oracle 的其他 javafx 示例后发现了这个问题。问题归结为您无法从 setStyle 更改自定义 css 变量。在 setStyle 方法中,您只能覆盖 caspian.css 上可用的 css 属性这是java默认的css。 (第 802 行用于菜单属性,然后是菜单栏)。
这里最简单的解决方法是从 setStyle 中调用正确的属性:
问题:
public void setMenuBarColor(String color){
menuBar.setStyle("-fx-my-menu-color-highlighted: " + color + ";");
}
修复:
public void setMenuBarColor(String color){
menuBar.setStyle("-fx-background-color: " + color + ";");
}
您可以结合使用 setStyle 和 css 文件,但要确保您没有为同一个选择器设置属性。
下面是一个简单的例子: MenuExample.java
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MenuExample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("JavaFX App");
Menu menu1 = new Menu("Menu 1");
MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(menu1);
//menuBar.setStyle("-fx-background-color: #6601C6;"); //uncomment to use this instead of css
//menu1.setStyle("-fx-background-color: #FF7F11;");
VBox vBox = new VBox(menuBar);
Scene scene = new Scene(vBox, 960, 600);
scene.getStylesheets().add("sample/sample-menu.css"); // comment here if using setStyle
primaryStage.setScene(scene);
primaryStage.show();
}
}
sample-menu.css
/* VARIABLE DEFINITIONS: Only these 4 variables have to be adjusted, the rest is copy-paste */
* {
-fx-my-menu-color: #00ff00; /* Change according to your needs */
-fx-my-menu-color-highlighted: #FF7F11; /* Change according to your needs */
-fx-my-menu-font-color: #FFFFFF; /* Change according to your needs */
-fx-my-menu-font-color-highlighted: #FFFFFF; /* Change according to your needs */
}
/* Try this: Comment .menu below and use menu1.setStyle from MenuExample.java */
.menu {
-fx-background-color: #FF7F11;
}
/* MENU BAR + Top-level MENU BUTTONS */
/*** The menu bar itself ***/
.menu-bar {
-fx-background-color: -fx-my-menu-color;
}
/* CONTEXT MENU */
/*** The context menu that contains a menu's menu items ***/
.context-menu {
-fx-background-color: -fx-my-menu-color;
}
有一种方法可以使用伪类来设置 CSS 变量,但我认为您在这里所做的只是更改该方法才有意义。我从未使用过 peudoclass,所以我无法说明一旦 CSS 在运行时加载后它会如何工作。
引用资料:
关于java - 无法在其他类中设置 JavaFX MenuBar 的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850516/