Создание простого приложения javafx

Пример: фрейм чата

import javax.swing.*;
import java.awt.*;
class Example {
    public static void main(String args[]) {

      
        JFrame frame = new JFrame("Chat Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);

        JMenuBar ob = new JMenuBar();
        JMenu ob1 = new JMenu("FILE");
        JMenu ob2 = new JMenu("Help");
        ob.add(ob1);
        ob.add(ob2);
        JMenuItem m11 = new JMenuItem("Open");
        JMenuItem m22 = new JMenuItem("Save as");
        ob1.add(m11);
        ob1.add(m22);

        
        JPanel panel = new JPanel(); // the panel is not visible in output
        JLabel label = new JLabel("Enter Text");
        JTextField tf = new JTextField(10); // accepts upto 10 characters
        JButton send = new JButton("Send");
        JButton reset = new JButton("Reset");
        panel.add(label); // Components Added using Flow Layout
        panel.add(label); // Components Added using Flow Layout
        panel.add(tf);
        panel.add(send);
        panel.add(reset);
        JTextArea ta = new JTextArea();

        frame.getContentPane().add(BorderLayout.SOUTH, panel);
        frame.getContentPane().add(BorderLayout.NORTH, tf);
        frame.getContentPane().add(BorderLayout.CENTER, ta);
        frame.setVisible(true);
    }
}

Это простой пример создания GUI с использованием Swing в Java.


Оцени статью

Оценить

Средняя оценка / 5. Количество голосов:

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

Спасибо за ваши отзыв!

Создание объектов

FXML может создавать как объект GUI, так и объекты не-JavaFX.

Создание объектов с помощью элементов FXML и конструкторов без аргументов

Самый простой способ создания объектов – это использование элемента FXML в файле. Имена элементов совпадают с именами классов Java без имен пакетов. После того, как вы импортировали класс с помощью оператора импорта, можете использовать его имя в качестве имени элемента.

В следующем примере имена элементов VBox и Label действительны, потому что эти два класса объявлены с инструкциями импорта ранее в файле:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.VBox?><?import javafx.scene.control.Label?>
    

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

Создание объектов с помощью метода valueOf()

Способ создания объектов с помощью метода valueOf() заключается в вставке атрибута значения в элемент FXML. Вот пример:

<?xml version="1.0" encoding="UTF-8"?><?import com.jenkov.javafx.MyClass?>

Вот как должен выглядеть соответствующий MyClass для работы:

public MyClass {
    public static MyClass valueOf(String value) {
        return new MyClass(value);
    }

    private String value = null;

    public MyClass(String value) {
        this.value = value;
    }
}

Имейте в виду, что любой объект, возвращаемый методом valueOf(), будет использоваться в графе объектов (составленном GUI). Если возвращаемый объект не является экземпляром класса, содержащего метод valueOf(), а является экземпляром какого-то другого класса, то этот объект все равно будет использоваться в графе объектов. Имя элемента используется только для поиска класса, содержащего метод valueOf() (когда элемент FXML содержит атрибут value).

Создание объектов с помощью factory методов

В некотором смысле метод valueOf() также является factory методом, который создает объекты на основе параметра String. Но вы также можете заставить FXMLLoader вызывать другие методы.

Для этого вам нужно вставить атрибут fx: factory. Значением атрибута fx: factory должно быть имя factory метода для вызова. Вот пример:

<?xml version="1.0" encoding="UTF-8"?><?import com.jenkov.javafx.MyClass?>

Класс MyClass должен выглядеть так, чтобы работал приведенный выше пример FXML:

public MyClass {
    public static MyClass instance() {
        return new MyClass();
    }
}

Стилизация с помощью CSS

В JavaFX с помощью каскадных таблиц стилей (CSS) можно стилизировать интерфейс пользователя. Это просто здорово! Ещё никогда не было так легко настроить внешний вид приложения Java.


В этом учебнике мы создадим тему DarkTheme, вдохновленную Метро-дизайном из Windows 8. Принятые стили для кнопок заимствованы из статьи JMetro — Windows 8 Metro controls on Java, написанной Pedro Duque Vieira.

Знакомство с CSS

Если вы хотите приукрасить внешний вид своего приложение JavaFX, то надо иметь хотя бы начальное представление о том, что такое CSS. Хорошее место для старта — этот учебник по CSS.

Для получения специфической информации об использовании CSS в JavaFX доступны следующие ресурсы:

  • Skinning JavaFX Applications with CSS — учебник от Oracle
  • JavaFX CSS Reference — официальный справочник

Стиль, используемый в JavaFX по умолчанию

Стиль, который используется в JavaFX по умолчанию хранится в файле . Его можно найти в файле , который, в свою очередь, располагается в директории Java .

Разархивируйте его и вы найдете в папке .

Этот стиль всегда применяется по умолчанию для всех приложений JavaFX. Добавляя пользовательские стили мы переопределяем стили из файла .

Подсказка: Для того, чтобы знать какие стили следует переопределить, просмотрите этот файл.

Подключение пользовательских CSS-стилей

Добавьте файл в пакет .

DarkTheme.css

Теперь надо подключить эти стили к нашей сцене. Мы можем сделать это программно, в коде Java, но в этом уроке, чтобы добавить стили в наши fxml-файлы, мы будем использовать Scene Builder:

Подключаем таблицы стилей к файлу RootLayout.fxml

  1. В приложении Scene Builder откройте файл .

  2. Во вкладке Hierarchy выберите корневой контейнер , перейдите на вкладку Properties и укажите файл в роли таблиц стилей.

Подключаем таблицы стилей к файлу PersonEditDialog.fxml

  1. В приложении Scene Builder откройте файл . Во вкладке Hierarchy выберите корневой контейнер , перейдите на вкладку Properties и укажите файл в роли таблиц стилей.

  2. Фон всё ещё белый, поэтому укажите для корневого компонента в классе стиля значение .

  3. Выберите кнопку OK и отметьте свойство Default Button в вкладке Properties. В результате изменится цвет кнопки и она будет использоваться по умолчанию когда пользователь, находясь в окне, будет нажимать клавишу Enter.

Подключаем таблицы стилей к файлу PersonOverview.fxml

  1. В приложении Scene Builder откройте файл . Во вкладке Hierarchy выберите корневой контейнер , перейдите на вкладку Properties и укажите файл в роли таблиц стилей.

  2. Вы сражу должны увидеть некоторые изменения: цвет таблицы и кнопок поменялся на чёрный. Все классы стилей и из файла были применены к таблице и кнопкам. С того момента, как мы переопределили некоторые из стилей в нашем css-файле, новые стили применяются автоматически.

  3. Возможно, вам потребуется изменить размер кнопок для того, чтобы отображался весь текст.


  4. Выберите правый компонент внутри компонента .

  5. Перейдите на вкладку Properties и укажите в классе стиля значение . Теперь фон станет чёрного цвета.

Текстовые метки с другими стилями

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

  1. Выберите метку Person Details и добавьте в качестве класса стиля значение .

  2. Для каждой метки в правой колонке (где отображаются фактические данные об адресатах) добавьте в качестве класса стиля значение .

JComboBox Class

Он наследует класс JComponent и используется для отображения всплывающего меню выбора.

import javax.swing.*;
public class Example{
JFrame a;
Example(){
a = new JFrame("example");
string courses[] = { "core java","advance java", "java servlet"};
JComboBox c = new JComboBox(courses);
c.setBounds(40,40,90,20);
a.add(c);
a.setSize(400,400);
a.setLayout(null);
a.setVisible(true);
}
public static void main(String args[])
{
new Example();
}
}  

Вывод:

Для размещения компонентов внутри контейнера мы используем менеджер макета. Ниже приведены несколько менеджеров макетов:

Загрузка файла

Чтобы загрузить файл FXML и создать компоненты графического интерфейса JavaFX, которые файл объявляют, вы используете класс FXMLLoader(javafx.fxml.FXMLLoader).

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.net.URL;

public class FXMLExample extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(new URL("file:///C:/data/hello-world.fxml"));
        VBox vbox = loader.load();

        Scene scene = new Scene(vbox);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Чтобы этот пример работал, файл FXML должен быть расположен в C: \ data \ hello-world.fxml. Как видите, местоположение файла задается с помощью метода setLocation(). Корневой компонент GUI (объект VBox) получается с помощью метода load().

Свойства

Некоторые объекты JavaFX имеют свойства. Вы можете установить их значения двумя способами.

  1. использовать атрибут XML для установки значения свойства;
  2. использовать вложенный элемент XML для установки значения свойства.

Чтобы понять, как лучше установить свойства в элементах, давайте рассмотрим пример:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.VBox?><?import javafx.scene.control.Label?>
        
    

Этот пример показывает 3 примера свойств.

  1. атрибут spacing в элементе VBox. Значение, установленное в атрибуте spacing, передается в качестве параметра методу setSpacing() объекта VBox, созданного на основе элемента VBox;
  2. дочерний элемент, вложенный в элемент VBox. Этот элемент соответствует методу getChildren() класса VBox. Элементы, вложенные в дочерний элемент, будут преобразованы в компоненты JavaFX, которые добавляются в коллекцию, полученную из метода getChildren() объекта VBox, представленного родительским элементом VBox;
  3. текстовые атрибуты двух элементов Label, вложенных в дочерние элементы. Значения текстовых атрибутов будут переданы в качестве параметров свойству setText() объектов Label, созданных элементами Label.

Соответствие имени свойства

FXML рассматривает «свойства» как переменные-члены, доступ к которым осуществляется через методы получения и установки. Например, getText() и setText().

Как видно из примера в предыдущем разделе, имена свойств классов JavaFX сопоставляются с именами атрибутов и элементов следующим образом:

  • Удалите все get / set в имени свойства.
  • Преобразуйте первый оставшийся символ имени свойства в нижний регистр.

Таким образом, метод getChildren будет сначала преобразован в Children, а затем в children. Аналогично, метод setText будет сокращен до Text, а затем до Text.

Свойства по умолчанию

Компонент JavaFX может иметь свойство по умолчанию. Это означает, что если элемент FXML содержит дочерние элементы, которые не вложены в элемент свойства, то предполагается, что дочерние элементы принадлежат свойству по умолчанию.

Давайте посмотрим на пример. Класс VBox имеет свойство children в качестве свойства по умолчанию. Это означает, что мы можем опустить элемент детей. Таким образом, этот FXML:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.VBox?><?import javafx.scene.control.Label?>
        
    

можно сократить до:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.VBox?><?import javafx.scene.control.Label?>
    

Предполагается, что два элемента Label принадлежат свойству VBox по умолчанию, которое является дочерним свойством.

Свойство по умолчанию помечается аннотацией JavaFX @DefaultProperty(value = “propertyName”), где значением является имя свойства, которое должно быть свойством по умолчанию. Например, объявление @DefaultProperty(value = “children”) сделало бы свойство children свойством по умолчанию.

Кнопка Delete

В нашем пользовательским интерфейсе есть кнопка Delete, но пока она не работает. В приложении Scene Builder мы можем задать действие, которое будет выполняться при нажатии на эту кнопку. Любой метод внутри класса-контроллера, помеченный аннотацией @FXML (или публичный), доступен Scene Builder. Поэтому, давайте сперва добавим в конец класса метод удаления адресата, а уже потом назначим его обработчиком кнопки Delete.

PersonOverviewController.java
/**
 * Вызывается, когда пользователь кликает по кнопке удаления.
 */
@FXML
private void handleDeletePerson() {
    int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
    personTable.getItems().remove(selectedIndex);
}

Теперь в приложении Scene Builder откройте файл . Выберите кнопку Delete, откройте вкладку Code и укажите метод в значение пункта On Action.

Помните: После изменения FXML-файла в Scene Builder, для того, чтобы изменения вступили в силу, вам может понадобится обновить проект в Eclipse.

Обработка ошибок

Если вы сейчас запустите приложение, то уже сможете удалять выбранных адресатов из таблицы. Но что произойдёт, если не будет выбран ни один адресат, а вы нажмёте кнопку Delete,?

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

Естественно, игнорировать эту ошибку будет некрасиво. Мы должны сообщать пользователю о том, что он, перед тем как нажимать кнопку Delete, должен выбрать запись в таблице. (Ещё лучше совсем деактивировать кнопку, чтобы у пользователя не было соблазна сделать что-то не так).

Добавим в метод некоторые изменения. Теперь, когда пользователь нажимает на кнопку Delete, а в таблице ничего не выбрано, он увидит простое диалоговое окно:

PersonOverviewController.java
/**
 * Вызывается, когда пользователь кликает по кнопке удаления.
 */
@FXML
private void handleDeletePerson() {
    int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
    if (selectedIndex >= 0) {
        personTable.getItems().remove(selectedIndex);
    } else {
        // Ничего не выбрано.
        Alert alert = new Alert(AlertType.WARNING);
        alert.initOwner(mainApp.getPrimaryStage());
        alert.setTitle("No Selection");
        alert.setHeaderText("No Person Selected");
        alert.setContentText("Please select a person in the table.");

        alert.showAndWait();
    }
}

Чтобы посмотреть другие примеры использования диалогов, откройте статью в блоге автора учебника Диалоги JavaFX.

Обработчики событий

Можно установить обработчики событий для объектов из файла FXML, который определяет объекты. Вы можете предпочесть устанавливать расширенные обработчики событий из кода Java, но для простых обработчиков событий установка их из FXML может подойти. Чтобы определить обработчик события, вам нужно использовать элемент script:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.VBox?><?import javafx.scene.control.Button?><?import javafx.scene.control.Label?>
    

    

В этом примере показаны две интересные концепции:

  1. Добавление прослушивателя событий в компонент из FXML. Элемент Button объявляет прослушиватель событий через его атрибут onAction. Значение атрибута объявляет вызов функцииactToClick(), который определен в элементе script далее в файле FXML.
  2. Ссылка на компонент через его идентификатор из файла FXML. Внутри метода reactToClick(), объявленного в элементе script, на элемент Label ссылается его идентификатор label1, с помощью этого оператора:
label1.setText("Button clicked");

Атрибут слушателя события onAction соответствует событию onAction компонента Button. Вы также можете установить прослушиватель событий через Java-код, с помощью метода Button setOnAction(). Вы также можете установить прослушиватели для других событий в FXML, сопоставив их методы прослушивателя событий из соответствующего компонента JavaFX с атрибутом FXML, используя те же правила сопоставления имен, что и для других свойств.


С этим читают