Диалоговое окно открытия и сохранения файла в JavaFX

👁 202 просмотров

Иногда в программе требуется реализовать диалоговое окно, которое будет открывать или сохранять файл и для таких целей в JavaFX есть отдельный класс FileChooser. Данный класс реализует данные диалоговые окна посредством вызова методов showOpenDialog() или showSaveDialog().

1. Открытие файла определенного расширения

Ниже покажем пример кода реализации диалогового окна открытия файла определенного расширения или списка расширений

@FXML
private void hndlOpenFile(ActionEvent event) {
        FileChooser fileChooser = new FileChooser();//Класс работы с диалогом выборки и сохранения
        fileChooser.setTitle("Open Document");//Заголовок диалога
        FileChooser.ExtensionFilter extFilter = 
        new FileChooser.ExtensionFilter("HTML files (*.html)", "*.html");//Расширение
        fileChooser.getExtensionFilters().add(extFilter);
        File file = fileChooser.showOpenDialog(CodeNote.mainStage);//Указываем текущую сцену CodeNote.mainStage
        if (file != null) {
            //Open
            System.out.println("Процесс открытия файла");
        }
}

2. Диалоговое окно сохранения файла определенного расширения

Ниже покажем пример кода реализации диалогового окна сохранения файла определенного расширения или списка расширений

@FXML
private void hndlOpenFile(ActionEvent event) {
    FileChooser fileChooser = new FileChooser();//Класс работы с диалогом выборки и сохранения
    fileChooser.setTitle("Save Document");//Заголовок диалога
    FileChooser.ExtensionFilter extFilter = 
    new FileChooser.ExtensionFilter("HTML files (*.html)", "*.html");//Расширение
    fileChooser.getExtensionFilters().add(extFilter);
    File file = fileChooser.showSaveDialog(CodeNote.mainStage);//Указываем текущую сцену CodeNote.mainStage
    if (file != null) {
        //Save
        System.out.println("Процесс открытия файла");
    }
}

3. Дополнительно

Для того, чтобы открывать или сохранять несколько видов расширений необходимо использовать мульти-фильтр

fileChooser.getExtensionFilters().addAll(
    new FileChooser.ExtensionFilter("All Images", "*.*"),
    new FileChooser.ExtensionFilter("HTML Documents", "*.html"),
    new FileChooser.ExtensionFilter("JPG", "*.jpg"),
    new FileChooser.ExtensionFilter("PNG", "*.png")
);

Для того, чтобы открывать несколько файлов необходимо использовать диалоговое окно мульти-выборки, который вызывается посредством метода showOpenMultipleDialog

List<File> list =
    fileChooser.showOpenMultipleDialog(CodeNote.mainStage);
    if (list != null) {
    for (File file : list) {
    openFile(file);
    }
}

Для того, чтобы узнать какое расширение выбрано в процессе сохранения или открытия используем getSelectedExtensionFilter(), а для того, чтобы сравнить существующие расширения используем метод getExtensionFilters().get(index), где index — порядковый номер регистрированного расширения

if(fileChooser.getSelectedExtensionFilter().equals(fileChooser.getExtensionFilters().get(0))){
    if (!file.getPath().endsWith(".html")) {
        file = new File(file.getPath() + ".html");
    }
        System.out.println("Процесс сохранения html файла");
    }else if(fileChooser.getSelectedExtensionFilter().equals(fileChooser.getExtensionFilters().get(1)))
    {
    if (!file.getPath().endsWith(".png")) {
        file = new File(file.getPath() + ".png");
    }
    System.out.println("Процесс сохранения png файла");
}

Класс Stage в JavaFX

👁 73 просмотров

В данной статье попытаемся разобраться с классом Stage в JavaFX. Понимание принципа работы данного класса очень важно, так как это один из главных классов, который вплотную работает с графами(контролами JavaFX). Публичный класс Stage расширяет класс Window. 

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

public class Stage extends Window

Класс Stage в JavaFX является верхнеуровневым контейнером.  Основной Stage конструирует платформу. В приложении могут быть сконструированы дополнительные платформы на основе Stage. Объект Stage должен быть сконструирован и модифицирован на основе потока JavaFX приложения. Большинство свойств данного класса предназначены только для чтения, потому что они могут быть изменены извне базовой платформы и, следовательно, не могут быть связанными.

Стили Stage

Stage платформа может иметь один из следующих стилей, которые являются статическими свойствами класса  StageStyle:

  • StageStyle.DECORATEDStage со сплошным белым задним фоном и стилизацией платформы;
  • StageStyle.UNDECORATED — Stage со сплошным белым задним фоном и без стилизацией платформы;
  • StageStyle.TRANSPARENT — Stage с прозрачным задним фоном и без стилизации платформы;
  • StageStyle.UTILITY — Stage со сплошным белым задним фоном и с минимальной стилизацией платформы;

Стили должны быть инициализированы перед тем, как платформа может быть выведена на экран с помощью метода show().  На некоторых платформах стилизации могут быть недоступны. К примеру, на некоторых мобильных или встраиваемых устройствах. В таких случаях запросы DECORATED или UTILITY окна могут быть установлены, но стили не будут показаны.

Родитель Stage

Платформа может дополнительно иметь собственные окна. Когда окно является владельцем платформ, то это как бы говорит, что оно является родителем для этих платформ. Когда закрыто родительское окно, то все его потомки будут также закрыты. Платформа должна всегда находиться поверх ее родительского окна. Владелец должен быть инициализирован перед платформой, которая выводиться.

Модальность

Платформа имеет один из следующих модальностей:

  • Modality.NONE — платформа, которая не блокируется никаким другим окном;
  • Modality.WINDOW_MODAL — платформа, которую блокируют входные события, распространяемые от источника ко всем окнам из его родителя к его корню. Этот корень является ближайшим предком окна без родителя;
  • Modality.APPLICATION_MODAL — платформа, которую блокируют входные события, распространяемые от того же приложения, исключая для тех которые исходят из его иерархии потомков;

Когда окно блокировано модальной платформой Stage его Z-порядок по отношению к потомкам сохраняется и он не получает никаких событий и никаких событий активации окна, но продолжает анимировать и нормально визуализировать. Необходимо заметить, что показываемая модальная платформа не обязательно блокирует его вызвавший родитель.  Метод show() возвращает вывод непосредственно и независимо от модальности платформы.  Если необходимо блокировать родитель, вызвавший платформу Stage до скрытия или закрытия платформы, то необходимо использовать showAndWait().  Модальное окно может быть инициализировано перед тем, как платформа может быть выведена(показана).

Пример использования Stage

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class HelloWorld extends Application {

    @Override public void start(Stage stage) {
        Text text = new Text(10, 40, "Hello World!");
        text.setFont(new Font(40));
        Scene scene = new Scene(new Group(text));

        stage.setTitle("Welcome to JavaFX!"); 
        stage.setScene(scene); 
        stage.sizeToScene(); 
        stage.show(); 
    }

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

 

Работа с обработчиками событий в JavaFX

👁 91 просмотров

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

Обработчики событий позволяют вам обрабатывать события на этапе восходящей фазы. Каждый узел может иметь один или более обработчиков для обрабатываемого события.  Простой обработчик может использовать один или более узлов и более одного типов событий. Если обработчик события для дочернего узла не использует событие, обработчик события для родительского узла позволяет родительскому узлу действовать на события после процесса дочернего узла, обрабатывать их и обеспечить общую обработку событий для нескольких дочерних узлов.

Регистрация и удаление обработчика события для узла

Для обработки события на этапе восходящей фазы узел должен зарегистрировать обработчик. Обработчик события наследует интерфейс EventHandler. Метод handle() данного интерфейса предоставляет код, который будет выполнен, когда событие, которое ассоциировано с обработчиком получит узел,для которого зарегистрирован обработчик.

Для регистрации обработчика используется метод addEventHandler(). Данный метод получает тип события и обработчик в виде аргумента. Ниже представлен пример , где первый обработчик добавляется к простому узлу и обрабатывается определенный тип события. Второй обработчик — для обработки события ввода, определен и зарегистрирован для 2-х различных узлов. Обработчик также зарегистрирован для двух различных типов событий.

//Пример регистрации обработчика для одного узла определенного типа события
node.addEventHandler(DragEvent.DRAG_ENTERED, 
                    new EventHandler() {
                        public void handle(DragEvent) { ... };
                    });

//Определение обработчика для предыдущего события
EventHandler handler = new EventHandler(() {
    public void handle(InputEvent event) {
        System.out.println("Handling event " + event.getEventType()); 
        event.consume();
    }

//Регистрация одного обработчика для двух различных узлов
myNode1.addEventHandler(DragEvent.DRAG_EXITED, handler);
myNode2.addEventHandler(DragEvent.DRAG_EXITED, handler);

//Регистрация еще одного типа события для первого из двух различных узлов
myNode1.addEventHandler(MouseEvent.MOUSE_DRAGGED, handler);

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

Когда вам больше не нужен обработчик события для узла, то его можно удалить, используя метод  removeEventHandler(). Данный метод в виде параметров получает тип удаляемого события и его обработчик. В ниже следующем примере представлен код, который демонстрирует данную возможность, где удаляется событие DragEvent.DRAG_EXITED узла myNode1 из предыдущего примера, но обработчик еще выполняет данный тип события для узла myNode2, и событие MouseEvent.MOUSE_DRAGGED для узла myNode1.

//Удаляем событие обработчика
myNode1.removeEventHandler(DragEvent.DRAG_EXITED, handler);

 Совет: Для удобства удаления обработчика события достаточно передать значение null в виде параметра через специальный метод, к примеру node1.setOnMouseDragged(null).

 

Архитектура JavaFX

👁 63 просмотров

В данной статье будет рассмотрена архитектура приложений JavaFX.  JavaFX является надслойкой виртуальной машины JVM и включает в себя целый набор утилит и модулей для полноценной работы с 2D/3D графикой, с представлениями окон, медиа — контентом, WEB — контентом, а также предоставляет программные инструменты для взаимодействия между, вышеперечисленными, компонентами. Ниже представлена иллюстрация того, как устроена надслойка JavaFX

Архитектура JavaFX

 

Графы сцены

Графы сцены или Scene Graph  — это самый верхний слой в архитектуре JavaFX. Он представлен иерархической структурой узлов и является начальной точкой построения визуального приложения JavFX, который включает в себя различные визуальные элементы управления. Данный слой управляет вводом и выводом данных начальных и конечных данных от пользователя. Графа сцены представлен набором узлов, которые имеют атрибуты такие как ID(уникальный идентификатор узла), который необходим для идентификации элемента управления в Java или CSS коде, class(используется, как правило при придании различных стилевых свойств атрибутов через CSS) и др., а также представлен определенным, ограниченным размером в пределах экрана монитора. За исключением корневого элемента или как его еще называют root node, каждый узел имеет свой родительский элемент и 0 или более дочерних узлов, которым можно придать следующие атрибуты:

  • Эффекты, такие как мутность и тень;
  • Прозрачность;
  • Трансформации;
  • Обработчики событий мыши, клавиатуры, внутренних методов в коде Java;
  • Специфичных для приложения различные состояния отображения;

В отличии от Swing и AWT(Abstract Window Toolkit) , JavaFX включает в себя еще графические примитивы такие как линии, прямоугольники, окружности и т.д., которые можно использовать наряду с остальными элементами управления и в дополнении имеет контейнеры, элементы для просмотра изображений и проигрывания медиа-контента.

JavaFX предоставляет богатые возможности для графов через javafx.animation API, который способен добавлять различные динамические спецэффекты и анимации.

JavaFX API позволяет создавать контент, специфичный для нескольких типов:

  • Узлы: Сущности (2-D и 3-D), изображения, медиа, встроенный WEB браузер, текст, UI элементы, графики, группы и другие контейнеры;
  • Состояние: Трансформации (позиции и ориентации узлов), визуальные эффекты и другие визуальные состояния;
  • Эффекты: Простые объекты, которые меняют свой внешний вид, обретая эффекты замутнения, тени и цветовых установок;

 Публичный открытый API для JavaFX

Верхний слой JavaFX архитектуры, показанный на вышеприведенной картинке, предоставляет законченный, публичный API, который поддерживает построение богатых возможностями клиентских приложений. Данный API предоставляет не параллельную, свободную и гибкую возможность для построения богатые клиентскими возможностями приложения. В JavaFX скомбинорованы лучшие возможности Java платформы со всесторонним погружением в медиа-функционал. Java для JavaFX характеризует:

  • Позволяет использовать полноценные Java характеристики , такие как генераторы, аннотации, многопоточность и лямбда выражения(включенные в Java SE 8);
  • Делает разработку для WEB очень легкой и позволяет для этого использовать другие, базовые для JVM, языки, такие как Groovy и JavaScript;
  • Позволяет разработчикам использовать другие системные языки, такие как Groovy для написания больших комплексных и сложных JavaFX приложений;
  • Позволяет использовать связывание, которое включают поддержку для высокопроизводительных lazy binding, binding выражения, bound sequence выражения и частичное связывание;
  • Внешние Java коллекции библиотек включают наблюдаемые списки(observable lists) и карты, которые позволяют программам соединять пользовательский интерфейс к моделям данных, позволяя наблюдать за обновлением или изменением данных в этих моделях и обновлением или изменением вместе с этим данных в пользовательских элементах управления;

JavaFX API и и программная модель имеет продолжение от JavaFX 1.x линейки выпуска, поэтому старые проекты можно легко перенести на новый выпуск JavaFX 2.x без особых затруднений.