Детальные функции JavaFX-Plus
Как правило, многие интерфейсы похожи или дублируются при разработке приложения JavaFX. Поэтому было бы гораздо эффективнее упаковать эти интерфейсы в пользовательские элементы управления, которые можно перетащить из SceneBuilder. Мы предлагаем разделить различные интерфейсы на разные подмодули, чтобы уменьшить связанность и ускорить параллельную разработку. Например, мы всегда разделяем интерфейс на верхнюю панель инструментов, навигационную панель слева и внутреннюю панель справа. Если всё написано в одном контроллере, это вызовет много раздувания кода, поэтому мы хотим разделить разные интерфейсы и управлять ими отдельно.
FXBaseController
, и этот новый класс — то, что мы всегда называем Controller. Класс FXBaseController
расширяет класс Pane
, и в этом заключается идея JavaFX-Plus: всё является Pane.@FXController
, указав адрес файла FXML.@FXWindow
, чтобы пометить его, со значением «title», обозначающим заголовок окна, и «mainStage», указывающим, что это окно отображается как основная сцена при запуске приложения.Пример показан ниже, благодаря чему нам будет легче разработать простое приложение JavaFX.
Фреймворк может быстро поддерживать интеграцию с 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 не запустится нормально. Будет выдано сообщение о том, что файл не существует.
Обработка log4j.properties
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
Примечание: часть текста запроса не удалось перевести из-за отсутствия контекста. Интерфейсы в процессе разработки, но напрямую работают с классами 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 {
}
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 под ресурсами.
Перенаправление на другое окно (закрытие текущего окна).
Всплывающее окно как диалог (текущее окно не закрывается).
Перенаправление на другое окно с данными.
JavaFX изначально поддерживает интернационализацию и локализацию через ResourceBundle и файлы конфигурации языка xxx_zh_CN.properties для операций интернационализации и локализации. Поскольку JavaFX-Plus инкапсулирует загрузку файлов FXML, а операции интернационализации и локализации должны быть настроены при загрузке файлов FXML, JavaFX-Plus предоставляет интерфейс для разработчиков.
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 в соответствующем контроллере, отметьте его язык и используйте некоторые события щелчка для перехода на страницы на разных языках.
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 строго соответствует его грамматике:
# 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, результат выполнения следующий:
Все вышеперечисленные языки, кроме китайского, взяты из Google Translate.
Чтобы помочь разработчикам быстро создавать спецификации кода, которые соответствуют... | | @FXField | чтобы пометить поле в java-компоненте, помеченном @FXEntity, как отражаемое в тип Property | | | | @FXSender | чтобы пометить метод как метод отправки сигнала | имя | не обязательно, переименовывает сигнал | | @FXReceiver | чтобы пометить метод как получающий сигнал | имя | необходимо, помечает подписанный сигнал | | @FXRedirect | чтобы пометить метод, который может перенаправить в другое окно | закрыть | не обязательно, логическое значение указывает, следует ли закрыть текущее окно; возвращаемым значением этого метода должно быть имя перенаправляющего контроллера или класса FXRedirectParam. |
В JavaFX-Plus все объекты Controller и объекты FXEntity должны создаваться через фабрики.
student = (Student) FXEntityFactory.getInstance().wrapFxBean(Student.class); //Создаём Student через FXEntityFactory
Java-бины создаются через фабрику, и при их создании фабрика проксирует Java-бины и оборачивает соответствующие свойства Property.
MainController mainController = (MainController)FXFactory.getFXController(MainController.class);
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);
}
}
@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);
}
}
@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.
Результат нашего первого простого приложения выглядит следующим образом:
setWindowTitle
, setIcon
, setDragAndResize
.FXSender
и FXReceiver
.Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )