2015-03-05 4 views
3

Мы боремся за проблему с пользовательским css для нашего приложения. До сих пор мы использовали обходной путь для применения нашего пользовательского css, но сохранили стиль modena для остальных.JavaFx css для всего приложения

StyleManager.getInstance().addUserAgentStylesheet(css); 

В обновленном juuuuuuuuuuu это поведение было ограничено и больше не работает. Настройка таблиц стилей для всех сцен отдельно безумие, установка пользовательских стилей с помощью

Application.setUserAgentStylesheet(css); 

работ, но не как мы хотели - модены стилей заменяется на заказ так много элементов управления не оформлены вообще. Мы нашли другое обходное решение: скопируйте всю папку modena в наш проект, добавьте наши пользовательские стили CSS в modena.css и (очень важно!) Переименуйте modena.css на что-то другое, например modenaB.css. В таблице стилей исходного кода JavaFx сравнивается, и если имя остается неизменным, используется оригинальная modena, хотя был предоставлен другой URL-адрес.

Мой вопрос в том, есть ли какой-нибудь лучший способ применить одну пользовательскую таблицу стилей во время инициализации приложения, которая будет использоваться всем приложением во всех сценах, сохраняя стили по умолчанию для всех не переопределяющих элементов управления?

ответ

0

Как разместить всю логику, связанную с сценой здания или элементом управления (просмотреть), чтобы разделить класс и использовать его для создания и назначения соответствующих таблиц стилей?

Например, в моем случае я создал 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); 
... 

это appliy таблиц стилей из 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)); 
    } 

} 

Я думаю, что можно написать что-то подобное, что будет загружать ваши базовые таблицы стилей применяются для всех представлений, а затем загрузить пользовательские таблицы стилей, указанные для просмотра.

P.S. Будет лучше итерации через иерархию, начиная с базового контроллера.

+0

Это, кажется, очень интересное решение, я постараюсь поиграть с ним. Благодарю. – user3886894

0

Из моего опыта проще всего установить CSS с помощью SceneBuilder в верхнем родительском узле. Все дочерние элементы этого узла наследуют этот CSS. Затем для отдельных случаев вы можете загрузить другой, чтобы перезаписать его для требуемого вида. Я не знаю, работает ли он так же, как в коде, но с SceneBuilder!

1

Самый простой способ - добавить свой файл css в таблицу стилей User Agent.

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

Ответ вдохновлен GuiGarage.

Смежные вопросы