JavaFX използва CSS (Cascading Style Sheets) за отделяне на визуалното оформление (цветове, шрифтове, разстояния) от структурата и логиката на приложението, аналогично на подходите в уеб разработката. JavaFX CSS се базира на спецификацията CSS 2.1.

Специфики на JavaFX CSS

  • Префикс -fx-: Всички специфични за JavaFX свойства задължително започват с префикса -fx- (напр. -fx-background-color вместо само background-color).
  • Стил по подразбиране (Default Style): Стандартният стилов файл за JavaFX приложения е modena.css, който се намира вграден в ядрото на библиотеката (в JAR файла на модула javafx.controls). Този стилов файл дефинира базовите стилове за кореновия възел и всички потребителски UI контроли. Например класа .root, който добавя по подразбиране на кореновия елемент на fxml файла.
  • Включване в FXML: За прилагане на външен CSS файл към съответния изглед е необходимо добавянето на атрибут stylesheets към кореновия (root) елемент:
    <HBox stylesheets="@styles.css" xmlns:fx="http://javafx.com/fxml/1">
        ...
    </HBox>
    

1. Създаване на CSS файл

Преди да бъдат приложени стиловете, трябва да се създаде CSS файл. Процесът включва:

1.1. Създаване на файл

  • Създава се файл с разширение .css, например styles.css.
  • За по-добра организация CSS файловете могат да се съхраняват в поддиректории като css/ или global_styles/.

1.2. Включване в FXML

1.2.1. Свързване на FXML с CSS

След дефинирането на селекторите и стиловите свойства следва тяхното прилагане върху изгледа, описан чрез FXML. За целта се използва атрибутът stylesheets, чрез който FXMLLoader се уведомява кои CSS файлове следва да бъдат заредени и приложени към кореновия елемент и неговите деца.

При дефинирането на пътя в JavaFX съществуват специфични правила, зависещи от йерархичната структура на проекта, като всички ресурси по подразбиране се разполагат в директория src/main/resources. В този контекст е важно да се отбележи, че FXML описва структурната организация на потребителския интерфейс, докато CSS определя неговото визуално оформление. Връзката между структурата и стила се осъществява чрез правилно указване на пътя до CSS файла, който може да бъде зададен като относителен спрямо FXML файла или като абсолютен спрямо корена на ресурсите на проекта.

Следва да се представят различните варианти за указване на път към CSS файл и правилата, прилагани от JavaFX при зареждане на ресурсите.

1.2.2. Използване на символа @ като указател за ресурс

В FXML дефинициите пътищата до външни файлове (като CSS или изображения) задължително започват със символа @. Той указва на компонента FXMLLoader, че следващият низ представлява път към ресурс, който трябва да бъде локализиран в рамките на проекта.

1.2.3. Указване на относителен път (Relative Path)

Относителният път определя локацията на CSS файла спрямо местоположението на самия FXML файл. Този подход е подходящ, когато стиловете са строго специфични за даден изглед. В случаите, когато CSS файлът се намира в поддиректория или наддиректория спрямо FXML файла, се използва специалният символ ../ за връщане една стъпка назад в йерархията на папките. Това позволява да се навигира в структурата на ресурсите без необходимост от абсолютен път, като се запазва относителната връзка между FXML и CSS файла.

Вариант А: При разположение на FXML и CSS файловете в обща директория

src/
└─ main/
   └─ resources/
      └─ bg/tu_varna/sit/ps/lab7/
         ├─ team-view.fxml        <-- Работен изглед
         └─ styles.css            <-- CSS файл

Ако изгледът team-view.fxml изисква зареждане на styles.css от същата директория, пътят се дефинира само чрез името на файла:

<HBox stylesheets="@styles.css" xmlns:fx="http://javafx.com/fxml/1">
    <!-- Съдържание -->
</HBox>

Вариант Б: При разположение на CSS файла в поддиректория спрямо FXML файла

src/
└─ main/
   └─ resources/
      └─ bg/tu_varna/sit/ps/lab7/
         ├─ team-view.fxml        <-- Работен изглед
         └─ css/                  <-- Поддиректория за стилове
            └─ styles.css         <-- CSS файл

Ако изгледът team-view.fxml изисква зареждане на styles.css от поддиректорията css/, пътят се задава по следния начин:

<HBox stylesheets="@css/styles.css" xmlns:fx="http://javafx.com/fxml/1">
    <!-- Съдържание -->
</HBox>

Вариант В: При разположение на CSS файла в поддиректория спрямо директорията на FXML файла

src/
└─ main/
   └─ resources/
      └─ bg/tu_varna/sit/ps/lab7/
         ├─ view                  <-- Поддиректория за изгледа
         |  └─team-view.fxml      <-- Работен изглед
         └─ css/                  <-- Поддиректория за стилове
            └─ styles.css         <-- CSS файл

Ако изгледът team-view.fxml изисква зареждане на styles.css от поддиректорията css/, пътят се задава по следния начин:

<HBox stylesheets="@../css/styles.css" xmlns:fx="http://javafx.com/fxml/1">
    <!-- Съдържание -->
</HBox>

1.2.4. Указване на абсолютен път (Absolute Path)

Абсолютният път (дефиниран спрямо корена на ресурсите) представлява по-надежден метод при мащабни проекти, където се използват глобални стилове за цялото приложение. Указването му се осъществява чрез добавяне на наклонена черта / непосредствено след символа @.

Знакът / реферира към началната директория за ресурси на проекта (src/main/resources/). По този начин местоположението на FXML файла няма значение – пътят винаги се изчислява от главната ресурсна директория.

src/
└─ main/
   └─ resources/
      ├─ global_styles/           <-- Главна директория за общи стилове
      │  └─ main.css              <-- Глобален CSS файл
      └─ bg/tu_varna/sit/ps/lab7/
         └─ team-view.fxml        <-- Работен изглед, намиращ се дълбоко в структурата

Зареждането на глобалния файл main.css в изгледа team-view.fxml изглежда по следния начин:

<HBox stylesheets="@/global_styles/main.css" xmlns:fx="http://javafx.com/fxml/1">
    <!-- Съдържание -->
</HBox>

1.2.5. Интегриране на множество CSS файлове

При необходимост от свързване на повече от един CSS файл към даден изглед, пътищата се изброяват в атрибута stylesheets, разделени със запетая (могат да се комбинират относителни и абсолютни пътища):

<HBox stylesheets="@/global_styles/main.css, @css/styles.css">
    <!-- Съдържание -->
</HBox>

2. Добавяне на стилове в CSS файла:

Стиловете се дефинират чрез селектори: типови, стилови класове, ID и псевдо-класове.

Селекторите служат за определяне на графичните елементи, към които ще бъде приложен съответният стил.

2.1. Типов селектор

Прилага се към всички елементи от даден тип. В CSS името на класа се изписва с малки букви.

Label {
    -fx-font-size: 16px;
    -fx-font-weight: bold;
}

2.2. Стилов клас (Style Class)

Позволява прилагане на стил към дефинирана група елементи. В CSS се използва символът . (точка). В FXML декларацията се задава чрез атрибута styleClass.

  • FXML:
<VBox styleClass="form-pane" />
  • CSS:
.form-pane {
  -fx-background-color: white;
  -fx-padding: 15;
  -fx-border-color: #e0e0e0;
  -fx-border-width: 1;
  -fx-border-radius: 8;
}

2.3. ID селектор

Прилага се към един конкретен елемент. В CSS се използва символът #. В FXML се задава чрез атрибута id (забележка: това свойство се различава от fx:id, макар често да споделят еднакви стойности).

  • FXML:
<Label text="Нов служител" id="form-title" />
  • CSS:
#form-title {
  -fx-font-size: 18px;
  -fx-font-weight: bold;
  -fx-text-fill: #2c3e50;
  -fx-padding: 0 0 10 0;
}

2.4. Псевдо-класове (Състояния)

Псевдо-класовете се прилагат за динамична промяна на стила при възникване на потребителска интеракция. Декларират се към селектора чрез добавяне на двоеточие :.

  • :hover - състояние при позициониране на курсора на мишката върху елемента.
  • :pressed - състояние по време на активно натискане (клик).
  • :focused - състояние при наличен фокус върху елемента (напр. активен текстов курсор).
  • :disabled - състояние при деактивирана контрола.

Пример за стилизиране на жизнен цикъл на бутон от примерната задача:

/* Стандартно състояние */
#add-btn {
  -fx-background-color: #3498db;
  -fx-text-fill: white;
  -fx-font-weight: bold;
  -fx-padding: 8;
  -fx-border-radius: 4;
}

/* Състояние при позициониран курсор (hover) */
#add-btn:hover {
  -fx-background-color: #2980b9;
}

/* Състояние при активиране (click) */
#add-btn:pressed {
  -fx-background-color: #1f618d;
}

2.5. Наследяване на стилове

Поддържат се съставни (комбинирани) селектори, които позволяват таргетиране на вложени елементи в рамките на даден UI компонент. Някои класове дефинират вътрешни структури (sub-nodes), които могат да бъдат стилизирани самостоятелно чрез т.нар. наследени (descendant) селектори.

Селекторът се състои от последователност от типови или класови селектори, разделени с интервал, като всеки следващ селектор реферира към наследен (вложен) елемент в йерархията на сцената.

Този механизъм позволява прилагане на стилове върху конкретни подкомпоненти, без да се засягат останалите части на контрола.

Пример

TableView ColumnHeader {
  -fx-background-color: #ecf0f1;
  -fx-font-weight: bold;
}

В примера се прилага стил върху елементите ColumnHeader, които са вложени в TableView.

3. Стилови свойства

По-долу е представен списък с най-често използваните стилови свойства в JavaFX, тяхното предназначение и поддържаните формати на стойности.

Фон (Background)

  • -fx-background-color
    • Предназначение: Дефинира цвета на фона на графичния елемент.
    • Параметри и стойности: Приема цветове в различни формати: текстови константи (напр. transparent, red), шестнадесетични HEX кодове (напр. #ffffff, #3498db), както и RGB/RGBA функции.
    • Пример:
      .form-pane {
        -fx-background-color: #f4f6f8;
      }
      

Граници и рамки (Borders)

  • -fx-border-color
    • Предназначение: Задава цвета на външната рамка на елемента.
    • Параметри и стойности: Приема стандартни цветови формати (HEX, RGB, константи). Може да приеме една стойност за всички страни или до четири отделни стойности (отговарящи съответно на горе, дясно, долу, ляво).
    • Пример:
      .text-field {
        -fx-border-color: #cccccc;
      }
      
  • -fx-border-width
    • Предназначение: Определя дебелината на рамката.
    • Параметри и стойности: Приема числови стойности (по подразбиране в пиксели). Може да се зададе единична стойност (напр. 2px за всички страни) или множество стойности (напр. 0 0 2px 0 за рамка само в долната част).
    • Пример:
      .text-field:focused {
        -fx-border-width: 2px;
      }
      
  • -fx-border-style
    • Предназначение: Дефинира стила на линията за рамката.
    • Параметри и стойности: Приема ключови думи за тип линия, като solid (плътна линия - по подразбиране), dashed (прекъсната) и dotted (пунктирана).
    • Пример:
      .drop-zone {
        -fx-border-style: dashed;
      }
      
  • -fx-border-radius
    • Предназначение: Определя степента на заобляне на ъглите на рамката.
    • Параметри и стойности: Приема числови стойности (по подразбиране в пиксели). Една стойност прилага еднакво заобляне на четирите ъгъла.
    • Пример:
      .text-field {
        -fx-border-radius: 4px;
      }
      

Текст и шрифтове (Text & Fonts)

  • -fx-text-fill
    • Предназначение: Дефинира цвета на текста вътре в даден контрол (напр. Label, Button, TextField).
    • Параметри и стойности: Поддържа стандартни цветови формати (константи, HEX кодове и RGB/RGBA функции).
    • Пример:
      #form-title {
        -fx-text-fill: #2c3e50;
      }
      
  • -fx-font-family
    • Предназначение: Задава името на шрифта, който ще се използва за визуализиране на текста.
    • Параметри и стойности: Приема текстови низове с имената на шрифтовете (напр. 'Arial'). Имената, съдържащи интервали, се поставят в кавички.
    • Пример:
      .root {
        -fx-font-family: 'Segoe UI', sans-serif;
      }
      
  • -fx-font-size
    • Предназначение: Определя размера на шрифта.
    • Параметри и стойности: Приема положителни числови стойности, придружени от мерна единица (напр. 14px, 1.2em).
    • Пример:
      #form-title {
        -fx-font-size: 18px;
      }
      
  • -fx-font-weight
    • Предназначение: Дефинира плътността (дебелината) на символите в шрифта.
    • Параметри и стойности: Приема ключови думи като normal и bold. Поддържа и числови стойности със стъпка 100 в диапазона от 100 до 900.
    • Пример:
      #add-btn {
        -fx-font-weight: bold;
      }
      

Размери, позициониране и отстояния

  • -fx-alignment
    • Предназначение: Определя подравняването на съдържанието вътре в даден контейнер или контрол спрямо неговите граници.
    • Параметри и стойности: Приема комбинирани ключови думи за вертикално и хоризонтално позициониране. Възможни стойности са: top-left, top-center, top-right, center-left, center, center-right, bottom-left, bottom-center, bottom-right и съответните варианти с baseline.
    • Пример:
      .vbox-container {
        -fx-alignment: center;
      }
      
  • -fx-padding
    • Предназначение: Дефинира вътрешното отстояние (празното пространство) между границата на елемента и неговото съдържание.
    • Параметри и стойности: Приема числови стойности (по подразбиране в пиксели). Може да се задава чрез:
      • 1 стойност: прилага се еднакво за четирите страни (напр. 15).
      • 2 стойности: първата отговаря за горе и долу, втората – за ляво и дясно (напр. 10 20).
      • 3 стойности: отговарят съответно за горе, ляво/дясно, долу (напр. 10 20 15).
      • 4 стойности: прилагат се по часовниковата стрелка: горе, дясно, долу, ляво (напр. 10 15 20 15).
    • Пример:

      .form-pane {
        /* 15px отстояние от всички вътрешни стени */
        -fx-padding: 15;
      }
      
      #add-btn {
        /* 8px отгоре/отдолу и 12px отляво/отдясно */
        -fx-padding: 8 12;
      }
      

5. Вградени стилове (Inline Styles)

При необходимост от прилагане на специфичен стил към единичен елемент без създаване на външен CSS файл, се използва атрибутът style директно в FXML дефиницията (аналогично на извикването на метода setStyle() в програмната логика). Тези стилове са с най-висок приоритет на изпълнение.

Пример:

<Label text="Успешно добавен!" style="-fx-text-fill: green; -fx-font-weight: bold;" />

(Забележка: При реализацията на мащабни проекти се препоръчва използването на външни CSS файлове с цел оптимизация на поддръжката).


This site uses Just the Docs, a documentation theme for Jekyll.