Javafx stylesheets внутри обшивки Osgi
Вопрос
Я поместил «styles.css» в корне моего пакета, и теперь пытаюсь выяснить, как связать это в коде.Проблема в том, что @ .getStyleshetsheates (). Добавить (_) принимает строку, а не URL, поэтому все подходы, которые я знаю, не в состоянии:
scene.getStylesheets().add("styles.css");
.
→
Nov 15, 2013 2:04:47 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "styles.css" not found.
.
scene.getStylesheets().add(this.getClass().getResource("styles.css").toExternalForm());
.
→
NullPointerException
.
scene.getStylesheets().add(this.getClass().getClassLoader().getResource("styles.css").toExternalForm());
.
→
Nov 15, 2013 2:27:31 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
INFO: Could not load stylesheet: bundle://5.0:1/styles.css
.
scene.getStylesheets().add(myBundle.getEntry("styles.css").toExternalForm());
.
→
Nov 15, 2013 1:31:35 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
INFO: Could not load stylesheet: bundle://5.0:0/styles.css
.
Я использую felix-4.2.1 , java-8 (build 1.8.0-b115) , javafx-8 (8,0.0-EA-B115) .
Решение
Я недавно бежал в той же ошибке / неприятностях, что и оригинальный постер этого вопроса, и мне удалось решить его, не внесенная никаких изменений в CSS / FXML, либо извлекать его в файл Temp. Я размещаю это здесь, так как я не нашел никакого хорошего ответа онлайн:
В моем случае установка была:
bundle0:
- .
- someview.fxml с относительным ссылкой на путь к файлу CSS
- somestyle.css с относительными ссылками на изображения
- emboughage.png
- resourceLoader.java (возвращает объекты URL из файлов CSS и FXML)
bundle1:
- .
- Основные файлы javaffx для загрузки fxml с загрузчиком fxml из bundle0.
Проблема:
Все изображения CSS и CSS и CSS, казалось, были проигнорированы FXML, даже если я устанавливаю классную загрузку на погрузчик FXML. Он работал только в том случае, если я использовал абсолютный путь к файлу для CSS, а изображения, на которые ссылаются в CSS. Это не то, что я хочу.
Решение:
Есть 2 ошибки / проектные проблемы в Javafx, которые запрещают эту настройку от работы с OSGI.
- .
- Загрузка CSS из fxml
- Привязка изображений из CSS
Чтобы исправить первую проблему, вы должны отключить файл двоичного CSS в Javafx, установив системный свойство Binare.css для false. В Javafx есть ошибка (может быть уже исправлено?) Где Javafx пытается быть умным и пытается найти файл BSS, даже если вы говорите CSS. Он переворачивает, потому что URL-адресов ресурсов OSGI имеет «Пакет: //» Схема, где она не ожидает схемы. Решение:
- .
- -dbinare.css= false
Чтобы исправить вторую проблему, вы должны установить CloseLoader Context Thread на классную загрузку пучка, где расположены изображения CSS, а затем восстанавливают классификатор контекста потока. Хитрость заключается в том, чтобы сделать это каждый раз, когда CSS интерпретируется Javafx, который не всегда, когда вы ожидаете, что это будет ...
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
final ClassLoader resourcesClassLoader = Resourceloader.class.getClassLoader();
//needed for css
Thread.currentThread().setContextClassLoader(resourcesClassLoader);
this.primaryStage.show();
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
.
К сожалению, это лучшее решение, с которым я мог придумать. Javafx не был сделан с учетом классов погрузчика или впрыска зависимости, хотя практически во всех корпоративных приложении используются эти функции в некоторой степени. : (
// редактировать Похоже, вам не нужно установить класс CloseSt Close Thread, чтобы получить доступ к изображениям из CSS!
Другие советы
Причина, по которой это не работает, не объясняется здесь: javafx jira rt-14177/ a>. Поскольку вы не можете использовать «внешнюю форму» Ressource, я скопировал его в файл TEMP, считывая входной поток напрямую.
InputStream inputStream = MainApp.class.getResourceAsStream("/styles/styles.css");
File tempStyleSheetDest = File.createTempFile("javafx_stylesheet", "");
tempStyleSheetDest.deleteOnExit();
Files.copy(inputStream, tempStyleSheetDest.toPath(), StandardCopyOption.REPLACE_EXISTING);
scene.getStylesheets().add(tempStyleSheetDest.toURI().toString());
.
- .
- Убедитесь, что вы используете классный класс класса, который имеет доступ к пакету, содержащую файл CSS
- Если вы используете относительный путь, убедитесь, что CSS расположен относительно этого класса Package
Вот образец, как я загрузил файл CSS в drombler fx ( Drombler FX - это модульная богатая клиентская платформа для Javafx на основе OSGI и Maven(POM-First) ):
Здесь: класс стилейных элементов в том же комплекте, что и файл CSS.
getClass (). GetClassLoader (). GetResource (). ToExternalform ()?