java - 无法在其他类中设置 JavaFX MenuBar 的样式

标签 java css javafx

我正在尝试根据场景背景为我的菜单栏设置不同的样式。

我所有的 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 在运行时加载后它会如何工作。

引用资料:

SO: How to set styles

SO: PseudoClass

关于java - 无法在其他类中设置 JavaFX MenuBar 的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850516/

相关文章:

java - Tomcat 过滤器对请求输入流产生不利影响(输入流为空)

php - Html - 更改 slider 的宽度和高度

JavaFX 3D 着色面...再次

java - TestFX和Gradle-NoNodeFoundException

java - 更改多边形的边框颜色

java - ValidationException : Call to TraversableResolver. isReachable() 抛出异常

java - 如何将Spring-boot服务注入(inject)aspectj类?

java - 如何创建 json 文件,然后在 get 请求中将其返回给 React 应用程序

html - 背景图片属性

javascript - jQuery 或 Javascript - 根据环境动态更改链接(相对/站点相对/绝对)