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

时间:2019-04-25 13:32:39

标签: java css javafx

根据场景背景,我正在尝试为菜单栏设置其他样式。

我所有的控制器都有一个窗格,可以在其中加载我的MenuBar。

HomePage.java

JButton btnNewButton = new JButton("ENTER");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String id = textField.getText();
                String name = textField_1.getText();
                String day1 = textField_2.getText();
                String month1 = textField_7.getText();
                String year1 = textField_8.getText();
                int day = Integer.valueOf(day1);
                int month = Integer.valueOf(month1);
                int year = Integer.valueOf(year1);
                Time bday = new Time(day,month,year);
                String email = textField_3.getText();
                String acc = textField_4.getText();
                String pass = textField_5.getText();
                String course1 = textField_6.getText();
                int coursen = Integer.valueOf(course1);

            }
        });

还有我的 Menu.Java类

package com.preferences.interfaces;

import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;

import aQute.bnd.annotation.metatype.Meta;

@ExtendedObjectClassDefinition(
    category = "preferences",
    scope = ExtendedObjectClassDefinition.Scope.GROUP
)
@Meta.OCD(
    id = "com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration",
    name = "UnsupportedBrowser.group.service.configuration.name"
)
public interface UnsupportedBrowserGroupServiceConfiguration {

    @Meta.AD(deflt = "", required = false)
    public String displayStyle();

    @Meta.AD(deflt = "0", required = false)
    public long displayStyleGroupId(long defaultDisplayStyleGroupId);

}

在此示例中,我使用HomePage.Java控制器,但效果很好,并且菜单显示在每个场景上。

我也有我的 Menu.css

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
}

问题是,我想更改MenuBar的背景(通过更改CSS变量“ -fx-my-menu-color”),但是无论我如何尝试,它要么不执行任何操作,要么抛出NullPointerException

编辑:使用“ setMenuBarColor()”和 stacktrace 的更清晰示例:

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 + ";");
}

Menu.fxml

* {
-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;
}

1 个答案:

答案 0 :(得分:0)

在查看您的代码以及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