【问题标题】:JavaFx css for whole application整个应用程序的 JavaFx css
【发布时间】:2015-05-06 17:18:37
【问题描述】:

我们正在为我们的应用程序的自定义 CSS 问题而苦苦挣扎。到目前为止,我们使用解决方法来应用我们的自定义 css,但其余部分保留 modena 样式。

StyleManager.getInstance().addUserAgentStylesheet(css);

在 8u40 java 更新中,这种行为受到限制并且不再起作用。为所有场景分别设置样式表是疯狂的,通过

设置自定义样式表
Application.setUserAgentStylesheet(css);

工作,但不是我们想要的 - modena 样式表被自定义替换,所以很多控件根本没有样式。 我们找到了另一种解决方法:将整个 modena 文件夹复制到我们的项目中,将我们的自定义 css 样式添加到 modena.css 并(非常重要!)将 modena.css 重命名为其他名称,例如 modenaB.css。在 JavaFx 中比较源代码样式表,如果名称保持不变,即使提供了不同的 url,也会使用原始 modena。

我的问题是,有没有更好的方法在应用程序初始化时应用一个自定义样式表,这将在所有场景中的整个应用程序中使用,同时为所有未覆盖的控件保留默认的 modena 样式?

【问题讨论】:

    标签: java css javafx stylesheet


    【解决方案1】:

    最简单的方法是在用户代理样式表中添加您的 css 文件。

    @Override
    public void start(Stage primaryStage) {
        // ...
        Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA);
        StyleManager.getInstance().addUserAgentStylesheet("example.css");
        // ...
    }
    

    答案来自GuiGarage

    【讨论】:

      【解决方案2】:

      如何将与构建场景或控件(视图)相关的所有逻辑放在单独的类中,并使用它来构建和分配适当的样式表?

      例如,我创建了FXMLBuilder 类。它只是基于控制器类加载 FXML,然后遍历控制器的层次结构并应用与层次结构中相应控制器相关的样式表。在文件系统中,我有以下层次结构:

      |
      +- controllers
      |  |
      |  +- BaseController.java
      |  +- BaseController.fxml
      |  +- BaseController.css
      |
      ...
      |
      +- MyController.java (inherited from BaseController)
      +- MyController.fxml
      +- MyController.css
      

      所以,当我构建 MyController 的实例时,

      MyController myController = new MyController(...);
      Parent myControllerRootNode = FXMLBuilder.build(myController);
      ...
      

      它应用来自 MyController.css 和 BaseController.css 文件的样式表。

      这是我的FXMLBuilder

      public class FXMLBuilder {
      
          public static final String FXML_EXTENSION = "fxml";
          public static final String CSS_EXTENSION = "css";
      
          public static Parent build(Object controller) throws IOException {
              Class<?> controllerClass = controller.getClass();
      
              URL fxmlURL = getResourceURL(controllerClass, FXML_EXTENSION);
      
              FXMLLoader fxmlLoader = new FXMLLoader(fxmlURL);
              fxmlLoader.setControllerFactory(param -> controller);
      
              Parent rootNode = fxmlLoader.load();
      
              loadStylesheets(rootNode, controllerClass);
      
              return rootNode;
          }
      
          private static void loadStylesheets(Parent rootNode, Class<?> controllerClass) {
              Class<?> currentControllerClass = controllerClass;
              while (!currentControllerClass.equals(Object.class)) {
                  if (getResourceURL(currentControllerClass, CSS_EXTENSION) != null) {
                      rootNode.getStylesheets().add(getResourcePath(currentControllerClass, CSS_EXTENSION));
                  }
                  currentControllerClass = currentControllerClass.getSuperclass();
              }
          }
      
          public static String getResourcePath(Class<?> resourceClass, String extension) {
              return String.format("/%s.%s", resourceClass.getCanonicalName().replace(".", "/"), extension);
          }
      
          public static URL getResourceURL(Class<?> resourceClass, String extension) {
              return resourceClass.getResource(getResourcePath(resourceClass, extension));
          }
      
      }
      

      我认为您可以编写类似这样的内容来加载适用于所有视图的基本样式表,然后加载为视图指定的自定义样式表。

      附:从基础控制器开始遍历层次结构会更好。

      【讨论】:

      • 这似乎是一个非常有趣的解决方案,我会尝试使用它。谢谢。
      【解决方案3】:

      根据我的经验,最简单的方法是在顶部父节点中使用 SceneBuilder 设置 CSS。此节点的所有子节点都将继承此 CSS。然后对于单个案例,您可以加载另一个案例以覆盖您想要的视图。我不知道它在代码中是否以相同的方式工作,但它与 SceneBuilder 一起使用!

      【讨论】:

        【解决方案4】:

        如果您是相关 css 文件的作者,您始终可以在 CSS 文件的顶部添加导入。这样您就可以将其用作 userAgentStyleSheet 替代品。例如

        @import "com/sun/javafx/scene/control/skin/modena/modena.css";
        /* rest of CSS code */
        

        如果您无法控制有问题的 css 文件,您始终可以创建一个“包装器”css 文件,该文件会在彼此之后同时导入 modena 和附加 css 文件。例如

        @import "com/sun/javafx/scene/control/skin/modena/modena.css";
        @import "the/extra/file.css";
        

        在您的应用程序中,您可以使用以下方法设置 userAgentStyleSheet:

        Application.setUserAgentStylesheet(css);
        

        【讨论】:

          猜你喜欢
          • 2018-03-15
          • 2013-04-25
          • 2017-05-09
          • 1970-01-01
          • 1970-01-01
          • 2017-04-28
          • 2021-05-20
          • 1970-01-01
          • 2020-02-17
          相关资源
          最近更新 更多