1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Biubiuyuyu-JavaFX-Plus

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.en.md

Детальные функции JavaFX-Plus

Модульная разработка

Введение модульности

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

Как создать модуль JavaFX-Plus

  1. Просто создайте класс, расширяющий класс FXBaseController, и этот новый класс — то, что мы всегда называем Controller. Класс FXBaseController расширяет класс Pane, и в этом заключается идея JavaFX-Plus: всё является Pane.
  2. Пометьте этот контроллер аннотацией @FXController, указав адрес файла FXML.
  3. Если мы хотим показать контроллер в отдельном окне, мы можем добавить к классу аннотацию @FXWindow, чтобы пометить его, со значением «title», обозначающим заголовок окна, и «mainStage», указывающим, что это окно отображается как основная сцена при запуске приложения.

Пример показан ниже, благодаря чему нам будет легче разработать простое приложение JavaFX.

Импорт только что созданного элемента управления в SceneBuilder

Интеграция с Spring

Фреймворк может быстро поддерживать интеграцию с Spring, и с помощью одной строки кода он может инвертировать управление созданием экземпляров для управления контейнером Spring.

Пример показан ниже:

@FXScan(base = {"cn.edu.scau.biubiusuisui.example.springDemo"})
public class SpringDemo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //start spring
        FXPlusApplication.start(SpringDemo.class, new BeanBuilder() {
            @Override
            public Object getBean(Class type) {
                return  context.getBean(type);
            }
        });
    }
}

Журнал

Ведение журнала

JavaFX-Plus интегрирует фреймворк log4j, выполняя обработку журналов, которая может контролировать доставку информации журнала. Кроме того, его можно гибко настроить через файл конфигурации log4j.properties, так что разработчики могут быстро находить аномальные ошибки в процессах разработки.

Для проекта Maven файл конфигурации log4j log4j.properties или log4j.xml по умолчанию помещается в папку ресурсов (как показано ниже). Если путь к файлу не совпадает, вам нужно установить его в коде отдельно, иначе log4j не запустится нормально. Будет выдано сообщение о том, что файл не существует.

Использование

  1. Обработка log4j.properties

    • Пример кода log4j.properties выглядит следующим образом: журналы уровня DEBUG и ERROR по умолчанию JavaFX-Plus будут выводиться в текущий каталог logs/debug/javafxplus.log и logs/debug/javafxplus.log.
    ### setting###
    log4j.rootLogger=debug,stdout,D,E
    ### print log message to console###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] - %m%n
    ### print debug log message to File=E://logs/error.log ###
    log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
    ### Windowsy

#log4j.appender.D.File = E://logs/debug/log.log

MacOS

Примечание: часть текста запроса не удалось перевести из-за отсутствия контекста. Интерфейсы в процессе разработки, но напрямую работают с классами Java-бинов.

Пример:

@FXController(path = "fxml/Main.fxml")
@FXWindow(title = "demo1")
public class MainController extends FXBaseController{

    @FXML
    Button btn;

    @FXML
    Label label;

    Student student;

    int count = 1;

    @Override
    public void initialize() {
        // Получаем Student из FXEntityFactory
        student = (Student) FXEntityFactory.getInstance().createJavaBeanProxy(Student.class);
        student.setName("Jack"); // Устанавливаем имя для Student
        FXEntityProxy fxEntityProxy = FXPlusContext.getProryByBeanObject(student); //Получаем прокси для Student
        Property nameProperty = fxEntityProxy.getPropertyByFieldName("name"); //Получаем соответствующее свойство
        //Мы можем получить свойство для List через fxEntityProxy.getPropertyByFieldName("list");
        label.textProperty().bind(nameProperty); //Связываем со свойством
    }

    @FXML
    @FXSender
    public String send(){
        student.setName("Джек:" + count);
        count++;
        return "отправка сообщения";
    }
}
@FXEntity
public class Student {
    @FXField
    private String name; //Помечаем поле как преобразуемое в поле Property

    private int age;
    private  String gender;
    private  String code;

    @FXField
    private List<String> list = new ArrayList<>();

    public String getName() {
        return name;
    }
    
    // setter & getter
    //  ...

    public void addList(String word){
        list.add(word);
    }
    public void delList(String word){
        list.remove(word);
    }
}

Результат показывает нам следующее:

Мы напрямую работаем с классами Java-бинов, модифицируя интерфейс с помощью динамического связывания. И нам не нужно преобразовывать Java-бины в JavaFX-бины, что сокращает преобразование типов при разработке.

Подключаемая функция

В нашей структуре окна можно перетаскивать и масштабировать. В JavaFX, если окно скрывает свой заголовок, окно нельзя перетащить и изменить масштаб. Но в JavaFX-Plus мы решили эту проблему с помощью аннотации @FXWindow.

Как описано в коде выше, вы можете сделать окно без заголовка перетаскиваемым и масштабируемым (значение по умолчанию — перетаскиваемое).

Также окно можно сделать изменяемым по размеру (по умолчанию это значение доступно):

Связывание данных

В этом разделе, подобно связыванию интерфейса в Vue, мы используем аннотацию @FXBind, которая должна применяться к полю элементов управления JavaFX, отмечая режим связывания и свойства отмеченного поля. В настоящее время мы реализовали связывание между бином и представлением, между представлением и представлением и связывание функционального выражения.

Связывание между бином и представлением

Например, как показано ниже, мы связали имя Student с текстом TextField и пароль Student с текстом PasswordField, упрощая операцию передачи данных. При этом нет передачи данных интерфейса от интерфейса к контроллеру.

Пример показан ниже:

Результатом простого приложения является следующее:

Связывание между представлением и представлением

Результатом является: ``` @FXML public void registerClick() { if (validate()) { //validate(): validate that if a user can register UserEntity userEntity = new UserEntity(); userEntity.setUsername(usernameTF.getText()); userEntity.setPassword(passwordPF.getText()); userEntity.setEmail(emailTF.getText());

    // TODO register
    redirectToRegisterSuccess(userEntity);
}

}

@FXML public void loginClick() { redirectToLogin(); }

@FXRedirect public String redirectToLogin() { return "LoginController"; }

@FXRedirect public FXRedirectParam redirectToRegisterSuccess(UserEntity userEntity) { FXRedirectParam fxRedirectParam = new FXRedirectParam("SuccessController"); fxRedirectParam.addParam("user", userEntity); return fxRedirectParam; }


```java
@FXController(path = "fxml/redirectDemo/dialog.fxml")
@FXWindow(title = "Dialog")
public class DialogController extends FXBaseController {
}
  1. При перенаправлении на другой контроллер нам необходимо обработать данные. Мы можем переопределить метод onShow в FXBaseController, который будет вызван перед отменой showStage(). FXBaseController включает поля query и param, которые хранят преобразованные данные при перенаправлении.
@FXController(path = "fxml/redirectDemo/success.fxml")
@FXWindow(title = "success")
public class SuccessController extends FXBaseController implements Initializable {
    @FXML
    private Label title;

    @FXML
    private Label usernameLabel;

    @FXML
    private Label passwordLabel;

    @FXML
    private Label tokenLabel;

    @FXML
    @FXRedirect
    public String redirectToLogin() {
        return "LoginController";
    }

    @Override
    public void onShow() {
        if (this.getQuery().get("showType") != null) {
            String showType = (String) this.getQuery().get("showType");
            if (showType.equals("1")) { //register
                title.setText("Register Success");
                if (this.getParam().get("user") != null) {
                    UserEntity userEntity = (UserEntity) this.getParam().get("user");
                    usernameLabel.setText(userEntity.getUsername());
                    passwordLabel.setText(userEntity.getPassword());
                }
            } else { //login ,username and password will be transformed with param
                title.setText("Login Success");
                if (this.getParam().size() > 1) {
                    usernameLabel.setText(String.valueOf(this.getParam().get("username")));
                    passwordLabel.setText(String.valueOf(this.getParam().get("password")));
                }
            }
        }
    }
}

Пример кода

Пример кода хранится в папке cn.edu.scau.biubiusuisui.example.redirectDemo, а файл FXML — в папке redirectDemo под ресурсами.

  1. Перенаправление на другое окно (закрытие текущего окна).

  2. Всплывающее окно как диалог (текущее окно не закрывается).

  3. Перенаправление на другое окно с данными.

Интернационализация и локализация

Введение в модуль

JavaFX изначально поддерживает интернационализацию и локализацию через ResourceBundle и файлы конфигурации языка xxx_zh_CN.properties для операций интернационализации и локализации. Поскольку JavaFX-Plus инкапсулирует загрузку файлов FXML, а операции интернационализации и локализации должны быть настроены при загрузке файлов FXML, JavaFX-Plus предоставляет интерфейс для разработчиков.

Использование

FXPlusLocale и аннотации
  • Примечание: данный перевод может содержать неточности. Прежде всего, JavaFX-Plus предоставляет тип перечисления FXPlusLocale для установки нескольких языков и в настоящее время поддерживает такие распространённые языки, как упрощённый китайский и традиционный китайский. Вот пример кода на языке Java:
public enum FXPlusLocale {
    // 不设置
    NONE,

    // 简体中文
    SIMPLIFIED_CHINESE,

    // 繁体中文
    TRADITIONAL_CHINESE,

    // English          英语
    ENGLISH,

    // American         美语
    AMERICAN,

    // Le français      法语
    FRANCE,

    // Deutsch          德语
    GERMANY,

    // lingua italiana  意大利语
    ITALIAN,

    // 日本人            日语
    JAPANESE,

    // 한국어            韩语   
    KOREAN,
}

Когда необходимо интернационализировать и локализовать FXController, нужно добавить атрибут locale в @FXContorller, тип которого — FXPlusLocale, следующим образом:

@FXWindow(mainStage = true, title = "languageDemo")
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
public class ChineseController extends FXBaseController {
    @FXML
    public void clickToOtherLanguage() {
        redirect();
    }

    @FXRedirect
    public String redirect() {
        return "EnglishController";
    }
}
@FXWindow(mainStage = false, title = "languageDemo")
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.ENGLISH)
public class EnglishController extends FXBaseController {
    @FXML
    public void clickToOtherLanguage() {
        redirect();
    }

    @FXRedirect
    public String redirect() {
        return "ChineseController";
    }
}

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

FXML

JavaFX-Plus относится к тому же синтаксису, что и JavaFX. В атрибутах метки FXML, таких как text, label и т. д., используйте % для обозначения переменной. Эта символьная переменная должна быть проанализирована с международными ресурсами.

<Button mnemonicParsing="false" text="%register"/>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="%register.email"/>

Имя отмеченной переменной должно быть определено в файле свойств, иначе при загрузке FXML возникнет исключение LoadException. Если register1 в FXML с меткой %register1 не определён, будет сообщена следующая информация об исключении:

Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Resource "register1" not found.
properties configuration

Компиляция файла ресурсов Properties строго соответствует его грамматике:

# English
register=Register
register.username=Username
register.password=password
register.confirmPassword=Confirm Password
register.phone=Phone
register.email=Email

Следует отметить, что файлы свойств должны быть закодированы в формате ISO-8859-1, поэтому для обработки всех не западных языков их сначала необходимо преобразовать в формат Unicode Escape Java, иначе чтение ResourceBundle будет искажено. Поэтому нам нужен метод преобразования через инструмент native2ascii, который поставляется с JDK. Напишите следующую команду в консоли, чтобы преобразовать файл в кодировку Unicode.

native2ascii languageDemo_zh_CN.properties languageDemo_zh_CN.properties 
native2ascii languageDemo_ko.properties languageDemo_ko.properties 

Результат преобразования:

# 中文
register=\u6ce8\u518c
register.username=\u7528\u6237\u540d
register.password=\u5bc6\u7801
register.confirmPassword=\u786e\u8ba4\u5bc6\u7801
register.phone=\u624b\u673a
register.email=\u90ae\u7bb1

Пример

Пример кода находится в cn.edu.scau.biubiusuisui.example.langDemo, результат выполнения следующий:

language_demo

Все вышеперечисленные языки, кроме китайского, взяты из Google Translate.

Как использовать JavaFX-Plus

Шаблон кода

Чтобы помочь разработчикам быстро создавать спецификации кода, которые соответствуют... | | @FXField | чтобы пометить поле в java-компоненте, помеченном @FXEntity, как отражаемое в тип Property | | | | @FXSender | чтобы пометить метод как метод отправки сигнала | имя | не обязательно, переименовывает сигнал | | @FXReceiver | чтобы пометить метод как получающий сигнал | имя | необходимо, помечает подписанный сигнал | | @FXRedirect | чтобы пометить метод, который может перенаправить в другое окно | закрыть | не обязательно, логическое значение указывает, следует ли закрыть текущее окно; возвращаемым значением этого метода должно быть имя перенаправляющего контроллера или класса FXRedirectParam. |

Две фабрики и контекст

  1. Две фабрики

В JavaFX-Plus все объекты Controller и объекты FXEntity должны создаваться через фабрики.

student = (Student) FXEntityFactory.getInstance().wrapFxBean(Student.class); //Создаём Student через FXEntityFactory

Java-бины создаются через фабрику, и при их создании фабрика проксирует Java-бины и оборачивает соответствующие свойства Property.

MainController mainController = (MainController)FXFactory.getFXController(MainController.class); 
  1. Контекст

FXPlusContext хранит все прокси-классы для контроллеров и FXEntities, которые аннотированы @FXController и @FXEntity.

public class FXPlusContext {
    private FXPlusContext(){}

    private static Map<String, List<FXBaseController>> controllerContext = new ConcurrentHashMap<>(); //реестр контроллеров FXController

    private static Map<Object, FXEntityProxy> beanMap = new ConcurrentHashMap<>(); // регистрируем объект с FXEntityObject

    public static void addController(FXBaseController fxBaseController){
        List<FXBaseController> controllers = controllerContext.get(fxBaseController.getName());
        if(controllers == null){
            controllers = new LinkedList<>();
        }
        controllers.add(fxBaseController);
    }

    public static List<FXBaseController> getControllers(String key){
        return controllerContext.get(key);
    }

    public static FXEntityProxy getProxyByBeanObject(Object object){
        return beanMap.get(object);
    }

    public static void setProxyByBeanObject(Object object,FXEntityProxy fxEntityProxy){
         beanMap.put(object,fxEntityProxy);
    }
}

Запустите своё первое приложение JavaFX-Plus

  1. Создайте основной класс.
@FXScan(base = {"cn.edu.scau.biubiusuisui.example"}) // Сканируем классы, аннотированные @FXController и @FXEntity и инициализируем их
public class Demo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Другие параметры такие же, как у Application оригинального JavaFX
        // Здесь мы вызываем метод start класса FXPlusApplication
        FXPlusApplication.start(Demo.class);
    }
}
  1. Далее мы разрабатываем файл FXML и класс контроллера.
@FXController(path = "fxml/Main.fxml")
@FXWindow(title = "demo1")
public class MainController extends FXBaseController{
    @FXML
    private ResourceBundle resources;
    @FXML
    private URL location;
    @FXML
    private Button addBtn;
    @FXML
    private Button delBtn;
    @FXML
    private ListView<String> list;

    Student student;

    @FXML
    void addWord(ActionEvent event) {
        student.addList("hello" );
    }

    @FXML
    void delWord(ActionEvent event) {
        student.delList("hello");
    }

    @Override
    public void initialize() {
        // Получаем JavaFX бин, который упакован из Java бина в FXEntityFactory
        student = (Student) FXEntityFactory.wrapFxBean(Student.class);
        Property listProperty = FXPlusContext.getEntityPropertyByName(student, "list");

``` **Вот перевод текста на русский язык:**

3. Теперь мы создаём класс Studen.

```java
@FXEntity
public class Student {

    @FXField
    private String name;

    @FXField
    private List<String> list = new ArrayList<>();

    public void addList(String word){
        list.add(word);
    }
    public void delList(String word){
        list.remove(word);
    }
}

Следует отметить, что корневой ярлык файла FXML должен быть fx:root>.

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

<fx:root prefHeight="400.0" prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.MainController">
   <children>
      <Button fx:id="addBtn" layoutX="432.0" layoutY="83.0" mnemonicParsing="false" onAction="#addWord" text="add" />
      <Button fx:id="delBtn" layoutX="432.0" layoutY="151.0" mnemonicParsing="false" onAction="#delWord" text="del" />
      <ListView fx:id="list" layoutX="42.0" layoutY="51.0" prefHeight="275.0" prefWidth="334.0" />
   </children>
</fx:root>

Как показано в примере кода выше, это меньше операций с операционными интерфейсами, и объекты, с которыми мы работаем, содержат базовый тип. Это помогает нам преобразовать обычный Java-проект в проект JavaFX.

Результат нашего первого простого приложения выглядит следующим образом:

введите сюда описание изображения

Обновление списка

v1.0.0

  1. Модульная разработка.
  2. Интеграция со Spring.
  3. Сигнальный механизм.
  4. Преобразование JavaBean и JavaFXBean.
  5. Подключаемая функция.
  6. Привязка данных.

v1.1.0

  1. Добавление функции переключения между несколькими окнами.

v1.2.0

  1. Разработка шаблона кода, который после импорта в IDE позволяет быстро генерировать файлы FXPlusController, FXPlusWindow, FXPlusApplication, FXPlusFXML, соответствующие спецификации программирования JavaFX-Plus.
  2. Улучшение функции переключения между окнами, которая может перенаправлять данные (см. подробности: «Переключение между несколькими окнами»).
  3. Исправление ошибок, вызванных атрибутами изменяемого размера и перетаскивания в @FXWindow.
  4. Добавление поля значка в @FXWindow путём передачи URL-адреса значка типа String, что позволяет добавить значок в строку заголовка окна.
  5. Улучшение жизненного цикла JavaFX-Plus.
  6. Добавление модуля журнала.
  7. Добавление международных операций и локализации с помощью пакета ресурсов.
  8. Добавление примера жизненного цикла теста LifeDemo и примера LanguageDemo.
  9. Стандартизация кода и обновление README.

v1.3.0

  1. Добавлены методы setWindowTitle, setIcon, setDragAndResize.
  2. Отправка и получение асинхронно.
  3. Поддержка конфигурации более чем одного имени с FXSender и FXReceiver.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Java
MIT
Отмена

Обновления (5)

все

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/Biubiuyuyu-JavaFX-Plus.git
git@api.gitlife.ru:oschina-mirror/Biubiuyuyu-JavaFX-Plus.git
oschina-mirror
Biubiuyuyu-JavaFX-Plus
Biubiuyuyu-JavaFX-Plus
1.3.0