Стили CSS
Внешний вид элементов JavaFX задаётся каскадными таблицами стилей — тем же CSS, что и в вебе, но со своими именами свойств: все они начинаются с -fx-. Стандартная тема называется Modena; ваш файл стилей подключается поверх неё и меняет только то, что в нём написано. Так оформление отделено и от разметки, и от кода.
Файл стилей
Создайте файл рядом с FXML:
/* src/main/resources/com/example/notes/styles.css */
.root {
-fx-font-family: "Segoe UI", sans-serif;
-fx-font-size: 14px;
-fx-background-color: #f7f7fb;
}
.header {
-fx-font-size: 22px;
-fx-font-weight: bold;
-fx-text-fill: #2d3a8c;
}
.button {
-fx-background-color: #4f6bed;
-fx-text-fill: white;
-fx-background-radius: 6;
-fx-padding: 6 14;
}
.button:hover {
-fx-background-color: #3b55d1;
}
.button:disabled {
-fx-opacity: 0.5;
}
.danger {
-fx-background-color: #d9534f;
}
.danger:hover {
-fx-background-color: #c9302c;
}
#countLabel {
-fx-text-fill: #777777;
}.root — корень сцены: шрифт и фон, заданные здесь, наследуют все элементы. У каждого стандартного элемента есть свой класс: .button, .label, .text-field, .table-view. #countLabel выбирает узел по fx:id.
Подключение к сцене
Файл добавляют в список стилей сцены в App:
// src/main/java/com/example/notes/App.java — фрагмент start()
Scene scene = new Scene(loader.load(), 800, 480);
scene.getStylesheets().add(App.class.getResource("styles.css").toExternalForm());toExternalForm() превращает адрес ресурса в строку, которую понимает JavaFX. Другой способ — атрибут корневого тега FXML: stylesheets="@styles.css", где @ означает путь относительно файла FXML.
Свои классы
Заголовку и кнопке удаления добавим классы в разметке:
<!-- src/main/resources/com/example/notes/main-view.fxml — изменённые строки -->
<Label text="Мои заметки" styleClass="header">
<Button fx:id="deleteButton" text="Удалить" onAction="#deleteNote"
styleClass="danger"/>Атрибут styleClass добавляет класс к стандартному: у кнопки будут оба — button и danger. Правило .danger стоит в файле ниже .button, поэтому его цвет фона побеждает. В коде то же делает deleteButton.getStyleClass().add("danger").
Частые свойства
| Свойство | Что задаёт |
|---|---|
-fx-background-color | Цвет фона |
-fx-text-fill | Цвет текста у Label и Button |
-fx-font-size, -fx-font-weight | Размер и насыщенность шрифта |
-fx-padding | Внутренний отступ |
-fx-background-radius | Скругление углов фона |
-fx-border-color, -fx-border-width | Рамка |
-fx-opacity | Прозрачность |
Псевдоклассы: :hover — под курсором, :pressed — нажата, :focused — в фокусе, :disabled — недоступна, :selected — выбранная строка или отмеченный флажок.
Проверка
Запустите приложение. Фон окна стал светло-серым с голубым оттенком, «Мои заметки» — крупный жирный синий заголовок. «Добавить» — синяя кнопка со скруглёнными углами и белым текстом, «Удалить» — красная. Пока ничего не выбрано, «Удалить» полупрозрачная. «Заметок: 2» — серым цветом.
Частая ошибка
Если имя файла в getResource написано неверно, например style.css вместо styles.css, окно не откроется: java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because the return value of "java.lang.Class.getResource(String)" is null. А свойство без приставки, например background-color: red;, JavaFX молча пропускает — если стиль не применился, первым делом проверьте -fx-.