v1.2.0更新
1. 设计代码模块文件,导入IDE后可快速生成符合JavaFX-Plus编程规范的FXPlusController、FXPlusWindow、FXPlusApplication、FXPlusFXML文件 2. 完善多窗口切换功能,可携带数据跳转 3. 新增注解@FXWindow中的icon属性,传入String类型的图标URL,可为窗口标题栏增设图标 4. 完善JavaFX-Plus生命周期 5. 新增日志log模块 6. 新增语言国际化操作 7. 新增测试生命周期LifeDemo示例和测试国际化的LanguageDemo示例代码 8. 规范化代码和更新README
499
README.en.md
@@ -10,15 +10,25 @@ Language: [中文](README.md)
|
||||
|
||||
[Maven Repository](#maven-repository)
|
||||
|
||||
[Git](#git)
|
||||
|
||||
[The Specific Application with JavaFX-Plus](#the-specific-application-with-javafx-plus)
|
||||
|
||||
[The Detailed Functions of JavaFX-Plus](#the-detailed-functions-of-javafX-plus)
|
||||
|
||||
- [Modularization Development](#modularization-development)
|
||||
- [Introduction](#introduction)
|
||||
- [Introduction](#introduction-of-modularization)
|
||||
- [How to Create the Module of JavaFX-Plus](#how-to-create-the-module-of-javafX-plus)
|
||||
- [Import the control just generated above in SceneBuilder](#import-the-control-just-generated-above-in-scenebuilder)
|
||||
- [Integration with Spring](#integration-with-spring)
|
||||
- [Log](#log)
|
||||
- [Introduction](#log-introduction)
|
||||
- [How to use](#how-to-use)
|
||||
- [Result](#result)
|
||||
- [Life Cycle](#life-cycle)
|
||||
- [Introduction](#introduction-of-life-cycle)
|
||||
- [The life cycle of multiple controllers](#the-life-cycle-of-multiple-controllers)
|
||||
- [Example](#example)
|
||||
- [Signal Mechanism](#signal-mechanism)
|
||||
- [The conversion of JavaBean and JavaFXBean](#the-conversion-of-javabean-and-javafxbean)
|
||||
- [Pluggable function](#pluggable-function)
|
||||
@@ -30,17 +40,26 @@ Language: [中文](README.md)
|
||||
- [Introduction](#introduction)
|
||||
- [Related Annotations](#related-annotations)
|
||||
- [Specification](#specification)
|
||||
- [How to Use](#how-to-use)
|
||||
- [How to Use](#usage-of-multi-window-switching)
|
||||
- [Example Code](#example-code)
|
||||
- [Internationalization and localization](#internationalization-and-localization)
|
||||
|
||||
[How to Use JavaFX-Plus](#how-to-use-javafX-plus)
|
||||
|
||||
[Annotations](#annotations)
|
||||
- [Code Template](#code-template)
|
||||
- [JavaFXPlusApplication](#JavaFXPlusApplication)
|
||||
- [JavaFXPlusWindow](#JavaFXPlusWindow)
|
||||
- [JavaFXPlusController](#JavaFXPlusController)
|
||||
- [JavaFXPlusFXML](#JavaFXPlusFXML)
|
||||
|
||||
[Two Factories and A Context](#two-factories-and-a-context)
|
||||
- [Annotations](#annotations)
|
||||
|
||||
- [Two Factories and A Context](#two-factories-and-a-context)
|
||||
|
||||
[Start your first JavaFX-Plus Application](#start-your-first-javafx-plus-application)
|
||||
|
||||
[Update List](#update-list)
|
||||
|
||||
## Introduction
|
||||
|
||||
The framework is not the framework for beautifying UI, but to simplify the step of developing the JavaFX Application and reduce the component coupling. Precently, the main functions of our framework are shown as follows:
|
||||
@@ -78,6 +97,15 @@ Our project has suspended update from Nov. 25, 2019, and the next release will b
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## Git
|
||||
|
||||
```
|
||||
Github https://github.com/BillKiller/JavaFX-Plus.git
|
||||
Gitee https://gitee.com/Biubiuyuyu/JavaFX-Plus.git
|
||||
```
|
||||
|
||||
|
||||
|
||||
## The Specific Application with JavaFX-Plus
|
||||
|
||||
Available from this: [Paper Loader](https://gitee.com/Biubiuyuyu/JavaFX-Demo 'Demo')
|
||||
@@ -86,7 +114,7 @@ Available from this: [Paper Loader](https://gitee.com/Biubiuyuyu/JavaFX-Demo 'D
|
||||
|
||||
### Modularization Development
|
||||
|
||||
#### Introduction
|
||||
#### Introduction of modularization
|
||||
|
||||
Generally, many of the interfaces are similar or duplicate in the development of JavaFX application. Therefore it would be much more efficient to package these interfaces into custom controls that can be dragged from SceneBuilder. We propose to divide different interfaces into different sub-modules to reduce coupling and accelerate parallel development. For example, we always divide the interface into the top toolbar, the navigation bar on the left, and the internal bar on the right. If everything is written in one controller, it will cause a lot of bloat, so we want to divide different interfaces and manage them separatelly.
|
||||
|
||||
@@ -140,6 +168,180 @@ public class SpringDemo extends Application {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Log
|
||||
|
||||
#### Log Introduction
|
||||
|
||||
JavaFX-Plus integrates the log4j framework, performing log processing, which can control the delivery of log information. Additionally, it can be flexibly configured through the configuration file` log4j.properties`, so that developers can quickly locate abnormal errors in development processes.
|
||||
|
||||
For the Maven project, log4j's configuration file `log4j.properties` or `log4j.xml` is placed in the resources folder by default (as shown below). If the file path does not match, you need to set it in the code separately, otherwise log4j will not start normally. Prompt file not existed.
|
||||
|
||||
<img src="README.en/log_demo_en.png" alt="log_demo" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
#### How to use
|
||||
|
||||
1. Processing of log4j.properties
|
||||
|
||||
- The sample code of log4j.properties is as follows, JavaFX-Plus default DEBUG and ERROR level logs will be output to the current directory `logs/debug/javafxplus.log` and ` logs/debug/javafxplus.log`
|
||||
|
||||
```properties
|
||||
### 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
|
||||
log4j.appender.D.File=${log.base}/logs/debug/javafxplus.log
|
||||
log4j.appender.D.Append=true
|
||||
log4j.appender.D.Threshold=DEBUG
|
||||
log4j.appender.D.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.D.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
|
||||
### print error log message to File=E://logs/error.log ###
|
||||
log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
|
||||
### Windows
|
||||
#log4j.appender.E.File = E://logs/error/log.log
|
||||
# MacOS
|
||||
log4j.appender.E.File=${log.base}/logs/error/javafxplus.log
|
||||
log4j.appender.E.Append=true
|
||||
log4j.appender.E.Threshold=ERROR
|
||||
log4j.appender.E.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.E.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
|
||||
```
|
||||
|
||||
- Configure the output path of the log dynamically
|
||||
|
||||
In log.properties, `$ {log.base}` represents system variables, which can be customized. By default, JavaFX-Plus takes the current project path as the value of` log.base`. But you can also use the method `initLog4jBase(String base)` provided by the `LogUtil` class of JavaFX-Plus, where base is the value of` log.base`.
|
||||
|
||||
|
||||
|
||||
2. wo ways to print logs
|
||||
|
||||
- Through the ` getLogger()` method of FXPlusLoggerFactory, passing in the Class of the current class to get IFXPlusLogger, and then you can print the log by provided methods like `info`, ` debug`, `error` and other methods.
|
||||
|
||||
- Use LogUtil's static methods like `info`, ` debug`, `error`, etc. to print logs.
|
||||
|
||||
```java
|
||||
public class LogDemo {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LogDemo.class);
|
||||
|
||||
public void testLogger() {
|
||||
logger.info("info");
|
||||
logger.error("error");
|
||||
logger.debug("debug");
|
||||
logger.warn("warn");
|
||||
}
|
||||
public void testLogUtil() {
|
||||
LogUtil.info("info");
|
||||
LogUtil.error("error");
|
||||
LogUtil.debug("debug");
|
||||
LogUtil.warn("warn");
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
LogDemo demo = new LogDemo();
|
||||
demo.testLogger();
|
||||
demo.testLogUtil();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Result
|
||||
|
||||
There are differences between the two ways to print the log. The class names of the two logs are different, but they can accurately locate a line of the log.
|
||||
|
||||
```verilog
|
||||
[INFO ] 2020-05-03 01:22:40,165 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:18)] - info
|
||||
[ERROR] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:19)] - error
|
||||
[DEBUG] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:20)] - debug
|
||||
[WARN ] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:21)] - warn
|
||||
[INFO ] 2020-05-03 01:22:40,170 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:25)] - info
|
||||
[ERROR] 2020-05-03 01:22:40,170 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:26)] - error
|
||||
[DEBUG] 2020-05-03 01:22:40,173 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:27)] - debug
|
||||
[WARN ] 2020-05-03 01:22:40,173 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:28)] - warn
|
||||
```
|
||||
|
||||
### Life Cycle
|
||||
|
||||
JavaFX Applications have their life cycle, and our JavaFX-Plus refers to the life cycle of WeChat Miniprogram and Vue.js. Based on the life cycle of native JavaFX, a series of actions from JavaFX Application startup to JavaFXController initilization and registration. We provided empty implementations of several functions, such as: if you need to perform related operations before desiplaying the page, you can rewrite `onShow` method to perform related operation in body. The example demo of life cycle has shown in `cn.edu.scau.biubiusuisui.example.lifeDemo`.
|
||||
|
||||
#### Introduction of life cycle
|
||||
|
||||
Firstly, we'll show you the life cycle of JavaFX-Plus:
|
||||
|
||||
- **`launch()`**: The native static method of JavaFX, launching the JavaFX Application independently, which can not be rewritten.
|
||||
|
||||
- **`init()`**: The function to initialize the JavaFX Application, being revoked after `launch()`. The method can be rewritten, which is convenient to initialize the application before its startup. But this method is not UI thread, and any UI operations can not be performed here.
|
||||
|
||||
- **`start()`**: The main entrance to all JavaFX Applications. When the init method is executed, the start method will be called. And this method is a JavaFX Application thread and UI operations can be performed here.
|
||||
|
||||
- **`stop()`**: When the JavaFX application is stopped, the method will be executed first to facilitate the destruction of related resources at the end of the application. This method is a JavaFX Application thread and UI operations can be performed here.
|
||||
|
||||
- **`constructor()`**: Constructor is not an actual function, here refers to the constructor of JavaFX Controller.
|
||||
|
||||
- **`onLoad`**: Monitor the loading of FXML pages, and call it before the loading. The application can rewrite this method to perform related operations before loading the FXML page, which is only triggered sonce globally.
|
||||
|
||||
- **`initialize()`**: The initialization method called after the page is loaded. The application can rewrite this method. It is generally used to initialize the initial values of some controls before displaying the page. It is only triggered once globally.
|
||||
|
||||
- **`onShow()`**: Monitor the display of the page and call it before the page is displayed. The application can override this method to facilitate related data processing and other operations before displaying the page.
|
||||
- **`onHide()`**: The application can override this method to monitor the operation of page hiding or from foreground to background.
|
||||
|
||||
- **`onClose()`**: Monitor the closing of the page, such as the close button of the window title bar, stage.close () and other methods to call before closing, the application can override this method.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
Additional notes:
|
||||
|
||||
(1) The hidden pages we know are minimized windows, but `stage.hide()` and `stage.close() `are equivalent in the official JavaFX documentation, so developers need to pay attention when using these two native methods. JavaFX API documentation: http://docs.oracle.com/javafx/2/api/javafx/stage/Stage.html#close()
|
||||
|
||||
(2) By default, the JavaFX application will automatically exit after the last Stage is closed, that is, automatically call `Application.stop()`. If you need to cancel this default operation, you can set `Platform.setImplicitExit(false)`, which can be used for some programs that can still run in the background after closing the desktop page, such as download background.
|
||||
|
||||
|
||||
|
||||
#### The life cycle of multiple controllers
|
||||
|
||||
When there are multiple Controllers in the JavaFX-Plus program, firstly the JavaFX-Plus will scan and register in the dictionary order according to the package of the attribute value of the `FXScan` annotation, when another Controller (child component) is referenced in a Controller (parent component), after the parent component loads the FXML page, it will enter the initialization process of the child component. Just after the child component completes `initialize()`, it will return to execute the parent component's `initialize()`.
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
1. By running `cn.edu.scau.biubiusuisui.example.lifeDemo`, relevant information will be printed out in Console.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
2. The component composition is as follows. The parent component contains child components. The parent component can also pop up a set window through the button.
|
||||
|
||||
<img src="README.en/lifeDemo/life_demo_en.png" alt="life_demo_en" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
3. First, by default, under the package marked by the base attribute of the `@FXScan` annotation in FXPlusApplication (LifeDemo in this example), scanning and registering in dictionary order. After registering DialogController, when registering MainController, because its FXML file refers to SubController, so after MainController executes the loading of FXML, it will jump to the registration process of SubController, and then return to `initialize()` of MainController.
|
||||
|
||||
<img src="README.en/lifeDemo/lifeDemo_pkg_en.png" alt="life_demo01_en" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
Then, when the popup button is clicked, DialogController's `showStage()` is called. At this time, the `onShow` is triggered. Click the close button to trigger the ` onClose`. When minimized and maximized the window, `onHide` and` onShow` are triggered respectively.
|
||||
|
||||
<img src="README.en/lifeDemo/life_demo01_en.png" alt="life_demo01_en" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Signal Mechanism
|
||||
|
||||
There are two annotations, one is `@FXSender`, which is applied to a method, marking this method as the signal emission method. And we can change the name of this emitting function with the value of "name", which default name is the method name.
|
||||
@@ -153,7 +355,7 @@ Let's take an example of the implementation of custom compoent navigation top ba
|
||||
1. With the modularity of JavaFX, we designed a simple navigation bar:
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/topBar.fxml")
|
||||
@FXController(path = "fxml/mqDemo/topBar.fxml")
|
||||
public class TopBarController extends FXBaseController {
|
||||
@FXML
|
||||
public void indexClick() {
|
||||
@@ -189,7 +391,7 @@ public class TopBarController extends FXBaseController {
|
||||
2. Then we designed a main page, which contains the navigation bar.
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/main.fxml")
|
||||
@FXController(path = "fxml/mqDemo/main.fxml")
|
||||
@FXWindow(mainStage = true, title = "MQDemo")
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
@@ -222,7 +424,7 @@ Generally, we write Java beans of basic types, but the design philosophy of Java
|
||||
We hope we can avoid methods which directly operate on Property related to interfaces during the development, but directly operate on Java bean classes. The example is shown as follows:
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXController(path = "fxml/Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
|
||||
@@ -391,8 +593,8 @@ private Label us;
|
||||
As code shown follows, we implemented a simple exchange rate converter
|
||||
|
||||
```java
|
||||
@FXController(path = "bindDemo/bindDemo.fxml")
|
||||
@FXWindow(title = "bindDemo", mainStage = true)
|
||||
@FXController(path = "fxml/bindDemo/bindDemo.fxml")
|
||||
@FXWindow(title = "fxml/bindDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@FXBind("text=${@toUs(time.text)}") // bind the text of Label to the return value of toUs() function
|
||||
@@ -453,7 +655,7 @@ In JavaFX application, we always need to switch between multiple windows, such a
|
||||
|
||||
The JavaFX-Plus stipulates that if we need an annotated with `@FXRedirect` method to handle redirection, the return value must be Stirng property or FXRedirectParam class, which all should provide the name of registered Controller. For example, if we need redirecting to login success interface whose controller named SuccessController, we should write `return "SuccessController"` in the method handling redirection. But the way above had not transfer data to anothor stage. If we need to transfer data to anothor stage, we should return url or FXRedirectParam, the usage has follows:
|
||||
|
||||
#### How to Use
|
||||
#### Usage of Multi-window switching
|
||||
|
||||
1. The usage of annotation `FXRedirect` as shown follows:
|
||||
|
||||
@@ -512,8 +714,8 @@ The JavaFX-Plus stipulates that if we need an annotated with `@FXRedirect` metho
|
||||
The example code :
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/login.fxml")
|
||||
@FXWindow(title = "redirectDemo", mainStage = true)
|
||||
@FXController(path = "fxml/redirectDemo/login.fxml")
|
||||
@FXWindow(title = "fxml/redirectDemo", mainStage = true)
|
||||
public class LoginController extends FXBaseController {
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
@@ -566,7 +768,7 @@ The JavaFX-Plus stipulates that if we need an annotated with `@FXRedirect` metho
|
||||
3. Design the Controller which will be redirected to.
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/register.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/register.fxml")
|
||||
@FXWindow(title = "register")
|
||||
public class RegisterController extends FXBaseController {
|
||||
@FXML
|
||||
@@ -613,16 +815,16 @@ The JavaFX-Plus stipulates that if we need an annotated with `@FXRedirect` metho
|
||||
```
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/dialog.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/dialog.fxml")
|
||||
@FXWindow(title = "Dialog")
|
||||
public class DialogController extends FXBaseController {
|
||||
}
|
||||
```
|
||||
|
||||
4. When we redirect to another controller, we need to process the data. We can override the method of `beforeShowStage` in FXBaseController, which will be revoked before the revoke of `showStage()`. FXBaseController includes `query` and `param` fields, which storage the transformed data in the redirection.
|
||||
4. When we redirect to another controller, we need to process the data. We can override the method of `onShow` in FXBaseController, which will be revoked before the revoke of `showStage()`. FXBaseController includes `query` and `param` fields, which storage the transformed data in the redirection.
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/success.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/success.fxml")
|
||||
@FXWindow(title = "success")
|
||||
public class SuccessController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@@ -644,7 +846,7 @@ The JavaFX-Plus stipulates that if we need an annotated with `@FXRedirect` metho
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShowStage() {
|
||||
public void onShow() {
|
||||
if (this.getQuery().get("showType") != null) {
|
||||
String showType = (String) this.getQuery().get("showType");
|
||||
if (showType.equals("1")) { //register
|
||||
@@ -684,8 +886,238 @@ The example code is stored at `cn.edu.scau.biubiusuisui.example.redirectDemo`, a
|
||||
|
||||
|
||||
|
||||
### Internationalization and localization
|
||||
|
||||
#### Module Introduction
|
||||
|
||||
JavaFX natively supports internationalization and localization, through ResourceBundle and language configuration file xxx_zh_CN.properties for internationalization and localization operations. Because JavaFX-Plus encapsulates the loading of FXML files, and internationalization and localization operations need to be configured when the FXML files are loaded, JavaFX-Plus provides an interface for developers.
|
||||
|
||||
#### Usage
|
||||
|
||||
##### FXPlusLocale and annotatians
|
||||
|
||||
First of all, JavaFX-Plus provides the FXPlusLocale enumeration type in order to set multiple languages, and currently provides common languages such as simplified Chinese and traditional Chinese, as follows:
|
||||
|
||||
```java
|
||||
public enum FXPlusLocale {
|
||||
// 不设置
|
||||
NONE,
|
||||
|
||||
// 简体中文
|
||||
SIMPLIFIED_CHINESE,
|
||||
|
||||
// 繁体中文
|
||||
TRADITIONAL_CHINESE,
|
||||
|
||||
// English 英语
|
||||
ENGLISH,
|
||||
|
||||
// American 美语
|
||||
AMERICAN,
|
||||
|
||||
// Le français 法语
|
||||
FRANCE,
|
||||
|
||||
// Deutsch 德语
|
||||
GERMANY,
|
||||
|
||||
// lingua italiana 意大利语
|
||||
ITALIAN,
|
||||
|
||||
// 日本人 日语
|
||||
JAPANESE,
|
||||
|
||||
// 한국어 韩语
|
||||
KOREAN,
|
||||
}
|
||||
```
|
||||
|
||||
When an FXController needs to be internationalized and localized, you need to add the attribute `locale` in the `@FXContorller `, whose type is `FXPlusLocale`, as follows:
|
||||
|
||||
```java
|
||||
@FXWindow(mainStage = true, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
public class ChineseController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToOtherLanguage() {
|
||||
redirect();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect() {
|
||||
return "EnglishController";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@FXWindow(mainStage = false, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
|
||||
public class EnglishController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToOtherLanguage() {
|
||||
redirect();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect() {
|
||||
return "ChineseController";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Both FXControllers are bound to the same FXML file. When the view changes, there is no need to change multiple FXML files in different languages, just add the locale attribute to the `@FXController` in the corresponding Controller, mark its language, and Use some click events to jump to pages in different languages.
|
||||
|
||||
|
||||
|
||||
##### FXML
|
||||
|
||||
JavaFX-Plus refers to the same syntax as JavaFX. In FXML's label attributes such as `text`,` label`, etc., use `%` to mark in front of a variable. This character variable should be parsed with international resources.
|
||||
|
||||
```xml
|
||||
<Button mnemonicParsing="false" text="%register"/>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="%register.email"/>
|
||||
```
|
||||
|
||||
The name of the marked variable must be defined in the properties file, otherwise a LoadException exception will occur when loading FXML. If `register1` in FXML with the label `%register1` is not defined, the following exception information will be reported:
|
||||
|
||||
```
|
||||
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Resource "register1" not found.
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### properties configuration
|
||||
|
||||
The compilation of the Properties resource file is strictly in accordance with its grammar, as follows:
|
||||
|
||||
```properties
|
||||
# English
|
||||
register=Register
|
||||
register.username=Username
|
||||
register.password=password
|
||||
register.confirmPassword=Confirm Password
|
||||
register.phone=Phone
|
||||
register.email=Email
|
||||
```
|
||||
|
||||
It should be noted that the properties files must be ISO-8859-1 encoded, so for all non-Western language processing, they must first be converted to Java Unicode Escape format, otherwise ResourceBundle reading will be garbled. So we need conversion method which through the native2ascii tool that comes with JDK. Write the following command in the console to convert the file to unicode encoding.
|
||||
|
||||
```shell
|
||||
native2ascii languageDemo_zh_CN.properties languageDemo_zh_CN.properties
|
||||
native2ascii languageDemo_ko.properties languageDemo_ko.properties
|
||||
```
|
||||
|
||||
Conversion result:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
The sample code is in `cn.edu.scau.biubiusuisui.example.languageDemo`, the running result as follows:
|
||||
|
||||

|
||||
|
||||
All the above languages except Chinese are from Google Translate.
|
||||
|
||||
|
||||
|
||||
## How to Use JavaFX-Plus
|
||||
|
||||
### Code Template
|
||||
|
||||
In order to facilitate developers to quickly generate code specifications that conform to JavaFX-Plus, a code template is specially designed, which can be imported in the IDE.
|
||||
|
||||
#### JavaFXPlusApplication
|
||||
|
||||
Generate code of the main entrance of JavaFX-Plus Application, the extension of file is java.
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXScan(base = "${PACKAGE_NAME}")
|
||||
public class ${NAME} extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(getClass());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusWindow
|
||||
|
||||
Generate code of a window in JavaFX-Plus Application, the extension of file is java.
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXWindow(mainStage = true, title = "")
|
||||
@FXController(path = "")
|
||||
public class ${NAME} extends FXBaseController {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusController
|
||||
|
||||
Generate code of a controller in JavaFX-Plus Application, the extension of file is java.
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXController(path = "")
|
||||
public class ${NAME} extends FXBaseController {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusFXML
|
||||
|
||||
Generate code of FXML file in JavaFX-Plus Application, the extension of file is xml.
|
||||
|
||||
```java
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</fx:root>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Annotations
|
||||
|
||||
| Name | Usage | Parameter | Remark for Parameter |
|
||||
@@ -771,7 +1203,7 @@ public class Demo extends Application {
|
||||
2. Next, we design a FXML file and a controller class.
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXController(path = "fxml/Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
@FXML
|
||||
@@ -852,3 +1284,32 @@ The result of our first simple application as shown follows:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Update List
|
||||
|
||||
#### v1.0.0
|
||||
|
||||
1. Modularization Development
|
||||
2. Integration with Spring
|
||||
3. Signal Mechanism
|
||||
4. The conversion of JavaBean and JavaFXBean
|
||||
5. Pluggable function
|
||||
6. Data Binding
|
||||
|
||||
#### v1.1.0
|
||||
|
||||
1. Add the function of multi-window switching.
|
||||
|
||||
#### v1.2.0
|
||||
|
||||
1. Design code template, and quickly generate FXPlusController, FXPlusWindow, FXPlusApplication, FXPlusFXML files that conform to the JavaFX-Plus programming specification after importing the IDE.
|
||||
2. Improve the function of multi-window switching, which can redirect with data, see details:[Multi-window switching](#multi-window-switching).
|
||||
3. Fix bugs caused by resizable and draggable attributes in `@FXWindow`.
|
||||
4. Add an icon field to @FXWindow, passing in an icon URL of type String, which can add an icon to the window title bar.
|
||||
5. Improve the life cycle of JavaFX-Plus.
|
||||
6. Add a log module.
|
||||
7. Add international and localization operation with resource budle.
|
||||
8. Add the test life cycle LifeDemo example and LanguageDemo example.
|
||||
9. Standardized code and updated README
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 147 KiB |
BIN
README.en/language_demo.gif
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
README.en/language_demo_en.gif
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
README.en/lifeDemo/lifeDemo_en.gif
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
README.en/lifeDemo/life_demo01_en.png
Normal file
|
After Width: | Height: | Size: 193 KiB |
BIN
README.en/lifeDemo/life_demo_en.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
README.en/log_demo_en.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
README.en/template_en.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
BIN
README.en/template_incude_en.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
513
README.md
@@ -10,45 +10,59 @@
|
||||
|
||||
[Maven仓库地址](#Maven仓库地址)
|
||||
|
||||
[Git地址](#git地址)
|
||||
|
||||
[具体应用](#具体应用)
|
||||
|
||||
[框架功能描述](#框架功能描述)
|
||||
|
||||
- [模块化开发](#模块化开发)
|
||||
- [介绍](#介绍)
|
||||
- [介绍](#描述)
|
||||
- [如何创建模块](#如何创建模块)
|
||||
- [scenebuilder中导入刚刚生成的上面的控件](#scenebuilder中导入刚刚生成的上面的控件)
|
||||
|
||||
- [与Spring的融合](#与Spring的融合)
|
||||
|
||||
- [日志](#日志)
|
||||
- [介绍](#介绍)
|
||||
- [如何使用](#如何使用)
|
||||
- [输出结果](#输出结果)
|
||||
- [生命周期](#生命周期)
|
||||
- [说明](#说明)
|
||||
- [多个Controller的生命周期](#多个Controller的生命周期)
|
||||
- [示例](#示例)
|
||||
- [信号机制](#信号机制)
|
||||
|
||||
- [JavaBean与JavaFXBean的转换](#JavaBean与JavaFXBean的转换)
|
||||
|
||||
- [可拔插功能](#可拔插功能)
|
||||
|
||||
- [数据绑定](#数据绑定)
|
||||
- [Bean和View绑定](#Bean和View绑定)
|
||||
- [View和View绑定](#View和View绑定)
|
||||
- [函数表达式绑定](#函数表达式绑定)
|
||||
|
||||
- [多窗口切换功能](#多窗口切换功能)
|
||||
|
||||
- [介绍](#介绍)
|
||||
|
||||
- [介绍](#功能介绍)
|
||||
- [涉及到的注解](#涉及到的注解)
|
||||
- [规定](#规定)
|
||||
- [规定](#规定)
|
||||
- [使用方法](#使用方法)
|
||||
- [示例演示](#示例演示)
|
||||
- [国际化和本地化](#国际化和本地化)
|
||||
- [介绍](#模块介绍)
|
||||
- [使用方法](#使用方法)
|
||||
- [示例演示](#示例演示)
|
||||
|
||||
[框架的使用](#框架的使用)
|
||||
|
||||
- [代码模板](#代码模板)
|
||||
- [JavaFXPlusApplication](#JavaFXPlusApplication)
|
||||
- [JavaFXPlusWindow](#JavaFXPlusWindow)
|
||||
- [JavaFXPlusController](#JavaFXPlusController)
|
||||
- [JavaFXPlusFXML](#JavaFXPlusFXML)
|
||||
|
||||
- [内置注解](#内置注解)
|
||||
|
||||
- [两个工厂和一个context](#两个工厂和一个context)
|
||||
|
||||
[创建第一个程序](#创建第一个程序)
|
||||
|
||||
[更新列表](#更新列表)
|
||||
|
||||
## 前言
|
||||
|
||||
这个框架不是UI美化框架,为了简化javaFX项目开发、为了减少项目之间组件耦合而打造的框架。目前框架主要功能如下图所示:
|
||||
@@ -81,14 +95,24 @@
|
||||
<version>1.0.0-RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
## Git地址
|
||||
|
||||
```
|
||||
Github https://github.com/BillKiller/JavaFX-Plus.git
|
||||
Gitee https://gitee.com/Biubiuyuyu/JavaFX-Plus.git
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 具体应用
|
||||
|
||||
可见 [下载器](https://gitee.com/Biubiuyuyu/JavaFX-Demo 'Demo')
|
||||
|
||||
## 框架功能描述
|
||||
|
||||
### 模块化开发
|
||||
|
||||
#### 介绍
|
||||
#### 描述
|
||||
|
||||
在Java开发过程中很多界面是相似或者重复的,如果能够将这些界面打包成为一个自定义控件,并且通过Scenebuilder拖动就能产生一个控件那将会大大提高我们的开发效率。所以我们提出将不同区域划分为不同的子模块,已达到减少耦合和加速并行开发。一般我们经常把界面分为顶部工具栏,左边导航栏,右侧的内容栏,如果全部内容都写在一个Controller那么将会导致十分臃肿,我们希望将不同的区域划分开来分而治之。
|
||||
|
||||
@@ -135,6 +159,185 @@ public class SpringDemo extends Application {
|
||||
|
||||
|
||||
|
||||
### 日志
|
||||
|
||||
#### 介绍
|
||||
|
||||
JavaFX-Plus集成log4j框架,进行日志处理,可以控制日志信息的输送,并可通过配置文件log4j.properties进行灵活配置,便于开发者能快速定位关键开发过程中的异常错误。
|
||||
|
||||
对于Maven项目而言,log4j其配置文件log4j.properties或log4j.xml默认放在resources文件夹下(如下图),若文件路径不符合,则需要在代码中另行设置,否则log4j将无法正常启动,提示file not existed。
|
||||
|
||||
<img src="README/log_demo.png" alt="log_demo" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
#### 如何使用
|
||||
|
||||
1. log4j.properties的处理
|
||||
|
||||
- log4j.properties的示例代码如下,JavaFX-Plus默认DEBUG和ERROR级别以上的日志会输出至当前目录的`logs/debug/javafxplus.log`和`logs/debug/javafxplus.log`。
|
||||
|
||||
```properties
|
||||
### 设置###
|
||||
log4j.rootLogger=debug,stdout,D,E
|
||||
### 输出信息到控制台 ###
|
||||
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
|
||||
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
|
||||
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
|
||||
### Windowsy
|
||||
#log4j.appender.D.File = E://logs/debug/log.log
|
||||
# MacOS
|
||||
log4j.appender.D.File=${log.base}/logs/debug/javafxplus.log
|
||||
log4j.appender.D.Append=true
|
||||
log4j.appender.D.Threshold=DEBUG
|
||||
log4j.appender.D.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.D.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
|
||||
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
|
||||
log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
|
||||
### Windows
|
||||
#log4j.appender.E.File = E://logs/error/log.log
|
||||
# MacOS
|
||||
log4j.appender.E.File=${log.base}/logs/error/javafxplus.log
|
||||
log4j.appender.E.Append=true
|
||||
log4j.appender.E.Threshold=ERROR
|
||||
log4j.appender.E.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.E.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
|
||||
```
|
||||
|
||||
- 动态配置日志的输出路径
|
||||
|
||||
在log.properties中`${log.base}`表示系统变量,可自定义。默认情况下,JavaFX-Plus取当前项目路径为log.base的值。但是也可以通过JavaFX-Plus的LogUtil类提供的方法`initLog4jBase(String base)`,其中base为log.base的值。
|
||||
|
||||
|
||||
|
||||
2. 打印日志的两种方式
|
||||
|
||||
- 通过FXPlusLoggerFactory的getLogger()方法,传入当前类的Class,获取IFXPlusLogger,即可通过其提供`info`, `debug`, `error`等方法打印日志,如以下的`testLogger()`。
|
||||
|
||||
- 通过LogUtil的静态方法`info`, `debug`, `error`等打印日志,如以下的`testLogUtil()`。
|
||||
|
||||
```java
|
||||
public class LogDemo {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LogDemo.class);
|
||||
|
||||
public void testLogger() {
|
||||
logger.info("info");
|
||||
logger.error("error");
|
||||
logger.debug("debug");
|
||||
logger.warn("warn");
|
||||
}
|
||||
public void testLogUtil() {
|
||||
LogUtil.info("info");
|
||||
LogUtil.error("error");
|
||||
LogUtil.debug("debug");
|
||||
LogUtil.warn("warn");
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
LogDemo demo = new LogDemo();
|
||||
demo.testLogger();
|
||||
demo.testLogUtil();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 输出结果
|
||||
|
||||
两种打印日志的方式是有区别的,两种日志所停留的类名是不同的,但是均可准确定位到所打日志的某一行。
|
||||
|
||||
```
|
||||
[INFO ] 2020-05-03 01:22:40,165 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:18)] - info
|
||||
[ERROR] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:19)] - error
|
||||
[DEBUG] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:20)] - debug
|
||||
[WARN ] 2020-05-03 01:22:40,169 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogger(LogDemo.java:21)] - warn
|
||||
[INFO ] 2020-05-03 01:22:40,170 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:25)] - info
|
||||
[ERROR] 2020-05-03 01:22:40,170 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:26)] - error
|
||||
[DEBUG] 2020-05-03 01:22:40,173 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:27)] - debug
|
||||
[WARN ] 2020-05-03 01:22:40,173 [main] [cn.edu.scau.biubiusuisui.example.logDemo.LogDemo.testLogUtil(LogDemo.java:28)] - warn
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 生命周期
|
||||
|
||||
JavaFX应用程序是具有生命周期的,JavaFX-Plus则参考微信小程序和Vue的生命周期,在原生JavaFX生命周期基础上,将从JavaFXApplication启动到JavaFXController进行初始化注册的一系列动作抽象出来,为开发者提供几个函数的空实现,如:若开发过程中需要在页面之前进行相关操作,如数据加载等,可重写`onShow`函数,在函数体中进行相关操作。测试生命周期可见示例:`cn.edu.scau.biubiusuisui.example.lifeDemo`
|
||||
|
||||
#### 说明
|
||||
|
||||
以下说明JavaFX-Plus的生命周期:
|
||||
|
||||
**`launch()`**: 启动独立JavaFX Application,为JavaFX原生static函数,不可重写。
|
||||
|
||||
**`init()`**: JavaFXApplication完成初始化操作的方法,在加载和构造应用程序类(`launch()`)后立即调用。应用程序可重写此方法,以便在实际启动应用程序之前进行初始化。此方法为JavaFX-Launcher线程,非UI线程,不可在此进行UI操作。
|
||||
|
||||
**`start()`**: 所有JavaFX Application的主入口。当init方法执行完成后,将调用start方法,该方法为JavaFX Application线程,可在此进行UI操作。
|
||||
|
||||
**`stop()`**: 当JavaFX应用程序停止时,会优先执行该函数,以便于应用程序结束时进行相关资源销毁等操作,该方法为JavaFX Application线程,可在此进行UI操作。
|
||||
|
||||
**`constructor()`**: constructor并不是实际函数,此处指代JavaFXController的构造函数。
|
||||
|
||||
**`onLoad()`**: 监听FXML页面的加载,在页面加载前进行调用,应用程序可重写此方法,以便在加载FXML页面之前进行相关操作,全局只触发一次。
|
||||
|
||||
**`initialize()`**: 初始化函数,在页面加载后方调用,应用程序可重写此方法,一般用于在显示页面之前初始化某些控件初始值,全局只触发一次。
|
||||
|
||||
**`onShow()`**: 监听页面的显示,在页面显示前进行调用,应用程序可重写此方法,以便于在显示页面前进行相关数据处理等操作。
|
||||
|
||||
**`onHide()`**: 监听页面隐藏或从前台到后台的操作,应用程序可重写此方法。
|
||||
|
||||
**`onClose()`**: 监听页面的关闭,如窗口标题栏的关闭按钮、`stage.close()`等方式关闭前进行调用,应用程序可重写此方法。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
补充说明:
|
||||
|
||||
1. 我们所认识的隐藏页面即最小化窗口,而在JavaFX官方文档中`stage.hide()`和`stage.close()`是等价的,故开发者在使用原生的这两个函数时需要注意。JavaFX文档:http://docs.oracle.com/javafx/2/api/javafx/stage/Stage.html#close()
|
||||
2. 默认情况下,JavaFX应用程序运行时会在最后一个Stage被Close后默认自动退出,即自动调用`Application.stop()`,如果需要取消这项默认操作,可设置`Platform.setImplicitExit(false);`,可用于一些关闭了桌面页面仍可以后台运行的程序,比如后台下载等。
|
||||
|
||||
|
||||
|
||||
#### 多个Controller的生命周期
|
||||
|
||||
当JavaFX-Plus程序中含有多个Controller时,首先按照注解FXScan中base的属性值的包下按照字典顺序进行扫描注册,当某个Controller(父组件)中引用了另一个Controller(子组件)时,父组件加载完FXML页面后会进入子组件的初始化过程,子组件完成`initialize()`后,方返回执行父组件的`initialize()`。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 示例
|
||||
|
||||
1. 通过运行`cn.edu.scau.biubiusuisui.example.lifeDemo`,会在Console打印出相关信息。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
2. 其组件构图如下,父组件中含有子组件,父组件还可通过按钮弹出某个已设置好的窗口。
|
||||
|
||||
<img src="README/lifeDemo/lifeDemo.png" alt="lifeDemo" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
3. 首先,在默认情况下,在FXPlusApplication(此例子中为LifeDemo)中的`@FXScan`注解的base属性标注的包下,按照字典顺序进行扫描注册。注册完DialogController后,注册MainController时,由于其中FXML文件引用了SubController,故在MainController执行完加载FXML操作后,会跳转至SubController的注册过程,然后才回到MainController的`initialize`。
|
||||
|
||||
<img src="README/lifeDemo/lifeDemo_pkg.png" alt="image-20200502093308298" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
然后,当点击弹窗按钮时,DialogController的`showStage()`被调用,此时触发`onShow`操作,点击关闭按钮,触发`onClose`操作,最小化最大化时分别触发`onHide`和`onShow`操作。
|
||||
|
||||
<img src="README/lifeDemo/life_demo01.png" alt="life_demo01" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 信号机制
|
||||
|
||||
@@ -147,7 +350,7 @@ public class SpringDemo extends Application {
|
||||
1. 利用JavaFX的模块化,我们设计一个简单的导航栏:
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/topBar.fxml")
|
||||
@FXController(path = "fxml/mqDemo/topBar.fxml")
|
||||
public class TopBarController extends FXBaseController {
|
||||
@FXML
|
||||
public void indexClick() {
|
||||
@@ -183,7 +386,7 @@ public class TopBarController extends FXBaseController {
|
||||
2. 再设计一个主界面,里面包含导航栏
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/main.fxml")
|
||||
@FXController(path = "fxml/mqDemo/main.fxml")
|
||||
@FXWindow(mainStage = true, title = "MQDemo")
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
@@ -215,7 +418,7 @@ public class MainController extends FXBaseController {
|
||||
而本次设计的过程中希望尽量避免操作界面相关的Property等方法,而是直接操作JavaBean类。例如下面代码。
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXController(path = "fxml/Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
|
||||
@@ -412,8 +615,8 @@ private Label us;
|
||||
如以下代码,实现简单的汇率转换器。
|
||||
|
||||
```java
|
||||
@FXController(path = "bindDemo/bindDemo.fxml")
|
||||
@FXWindow(title = "bindDemo", mainStage = true)
|
||||
@FXController(path = "fxml/bindDemo/bindDemo.fxml")
|
||||
@FXWindow(title = "fxml/bindDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@FXBind("text=${@toUs(time.text)}") // 将Label中的text和toUs()函数的返回值绑定
|
||||
@@ -458,7 +661,7 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
|
||||
### 多窗口切换功能
|
||||
|
||||
#### 介绍
|
||||
#### 功能介绍
|
||||
|
||||
在JavaFX中常常需要多个窗口之间进行切换,比如登录窗口,点击登录后跳转至登录成功/失败窗口,网上部分有关多窗口切换的JavaFX教程实现过程为:在Controller中是实现FXML绑定,并通过外部调用某个show方法来切换窗口。由于本框架已经将FXML绑定这一功能封装,故通过在Controller内部直接初始化Stage并设置参数这一方法并不现实。因此,在本框架中,编写StageController类对Controller进行管理。
|
||||
|
||||
@@ -531,8 +734,8 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
代码如下:
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/login.fxml")
|
||||
@FXWindow(title = "redirectDemo", mainStage = true)
|
||||
@FXController(path = "fxml/redirectDemo/login.fxml")
|
||||
@FXWindow(title = "fxml/redirectDemo", mainStage = true)
|
||||
public class LoginController extends FXBaseController {
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
@@ -586,7 +789,7 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
3. 编写需要跳转的界面Controller,比如登录时,尚无账号跳转至注册界面(不弹窗)和测试弹窗的Controller
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/register.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/register.fxml")
|
||||
@FXWindow(title = "register")
|
||||
public class RegisterController extends FXBaseController {
|
||||
@FXML
|
||||
@@ -633,16 +836,16 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
```
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/dialog.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/dialog.fxml")
|
||||
@FXWindow(title = "弹窗")
|
||||
public class DialogController extends FXBaseController {
|
||||
}
|
||||
```
|
||||
|
||||
4. 在携带数据跳转至另一Controller后,需要对传入数据进行处理,此时需要重写FXBaseController中的`beforeShowStage()`函数,此函数将在某一Controller的`showStage()`之前执行,即在Controller显示之前进行处理数据等相关操作。FXBaseController中包含`query`和`param`两个属性,用于存储重定向中的传递数据。
|
||||
4. 在携带数据跳转至另一Controller后,需要对传入数据进行处理,此时需要重写FXBaseController中的`onShow()`函数,此函数将在某一Controller的`showStage()`之前执行,即在Controller显示之前进行处理数据等相关操作。FXBaseController中包含`query`和`param`两个属性,用于存储重定向中的传递数据。
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/success.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/success.fxml")
|
||||
@FXWindow(title = "success")
|
||||
public class SuccessController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@@ -664,7 +867,7 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShowStage() {
|
||||
public void onShow() {
|
||||
if (this.getQuery().get("showType") != null) {
|
||||
String showType = (String) this.getQuery().get("showType");
|
||||
if (showType.equals("1")) { //注册
|
||||
@@ -706,7 +909,238 @@ public class MainController extends FXBaseController implements Initializable {
|
||||
|
||||
|
||||
|
||||
### 国际化和本地化
|
||||
|
||||
#### 模块介绍
|
||||
|
||||
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需要国际化和本地化时,需要在@FXContorller注解中新增属性locale,类型为FXPlusLocale,如以下:
|
||||
|
||||
```java
|
||||
@FXWindow(mainStage = true, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
public class ChineseController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToOtherLanguage() {
|
||||
redirect();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect() {
|
||||
return "EnglishController";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@FXWindow(mainStage = false, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
|
||||
public class EnglishController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToOtherLanguage() {
|
||||
redirect();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect() {
|
||||
return "ChineseController";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
两个FXController都绑定同一个FXML文件,当视图发生改变时,并不需要改变多个不同语言的FXML文件,只需要添加对应的Controller中的@FXController注解中添加locale属性,标注其语言,并利用某些点击事件等进行不同语言的页面跳转。
|
||||
|
||||
|
||||
|
||||
##### FXML文件的编写
|
||||
|
||||
在JavaFX-Plus中引用了与JavaFX同样的语法,在FXML中的`text`, `label`等标签属性中,用 `%` 在某变量前标记,该字符变量应该用国际化资源解析。
|
||||
|
||||
```xml
|
||||
<Button mnemonicParsing="false" text="%register"/>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="%register.email"/>
|
||||
```
|
||||
|
||||
所标记的变量名必须在properties文件中定义,否则在加载FXML时会发生LoadException异常,如FXML中标记`%register1`的register1并无定义,会报以下异常信息:
|
||||
|
||||
```
|
||||
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Resource "register1" not found.
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### properties资源文件的编写
|
||||
|
||||
Properties资源文件的编写严格按照其语法进行编写,如下:
|
||||
|
||||
```properties
|
||||
# English
|
||||
register=Register
|
||||
register.username=Username
|
||||
register.password=password
|
||||
register.confirmPassword=Confirm Password
|
||||
register.phone=Phone
|
||||
register.email=Email
|
||||
```
|
||||
|
||||
需要注意的是,资源文件都必须是ISO-8859-1编码,因此,对于所有非西方语系的处理,都必须先将之转换为Java Unicode Escape格式,否则ResourceBundle读取会出现乱码问题,转换方法是通过JDK自带的工具native2ascii,在console中编写以下命令,即可将文件转换为unicode编码。
|
||||
|
||||
```shell
|
||||
native2ascii languageDemo_zh_CN.properties languageDemo_zh_CN.properties
|
||||
native2ascii languageDemo_ko.properties languageDemo_ko.properties
|
||||
```
|
||||
|
||||
转换结果:
|
||||
|
||||
```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.languageDemo`中,运行可得:
|
||||
|
||||

|
||||
|
||||
以上除中文外的语言均来自谷歌翻译。
|
||||
|
||||
|
||||
|
||||
## 框架的使用
|
||||
|
||||
### 代码模板
|
||||
|
||||
为方便开发者快速生成符合JavaFX-Plus的代码规范,特设计了一下代码模板,只需在IDE中导入即可。
|
||||
|
||||
#### JavaFXPlusApplication
|
||||
|
||||
生成JavaFX-Plus程序的主入口,拓展名是java
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXScan(base = "${PACKAGE_NAME}")
|
||||
public class ${NAME} extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(getClass());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusWindow
|
||||
|
||||
生成JavaFX-Plus程序中的Window(以窗口形式显示),拓展名是java。
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXWindow(mainStage = true, title = "")
|
||||
@FXController(path = "")
|
||||
public class ${NAME} extends FXBaseController {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusController
|
||||
|
||||
生成JavaFX-Plus程序中的Controller(可以窗口和普通控件形式显示),拓展名是java。
|
||||
|
||||
```java
|
||||
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
#parse("File Header.java")
|
||||
@FXController(path = "")
|
||||
public class ${NAME} extends FXBaseController {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### JavaFXPlusFXML
|
||||
|
||||
生成JavFX-Plus程序中的显示层FXML文件,以`fx:root`为根标签,父组件统一为Pane,拓展名为xml。
|
||||
|
||||
```java
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</fx:root>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 内置注解
|
||||
|
||||
| 名字 | 作用 | 参数 | 备注 |
|
||||
@@ -791,7 +1225,7 @@ public class Demo extends Application {
|
||||
2. 接下来我们生成FXML和Controller
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXController(path = "fxml/Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
@FXML
|
||||
@@ -870,3 +1304,30 @@ public class Student {
|
||||

|
||||
|
||||
|
||||
|
||||
## 更新列表
|
||||
|
||||
#### v1.0.0
|
||||
|
||||
1. 模块化开发
|
||||
2. 与Spring的融合
|
||||
3. 信号机制
|
||||
4. JavaBean与JavaFXBean的转换
|
||||
5. 可拔插功能
|
||||
6. 数据绑定
|
||||
|
||||
#### v1.1.0
|
||||
|
||||
1. 新增多窗口切换功能
|
||||
|
||||
#### v1.2.0
|
||||
|
||||
1. 设计代码模块文件,导入IDE后可快速生成符合JavaFX-Plus编程规范的FXPlusController、FXPlusWindow、FXPlusApplication、FXPlusFXML文件
|
||||
2. 完善多窗口切换功能,可携带数据跳转,详见:[多窗口切换功能](#多窗口切换功能)
|
||||
3. 新增注解@FXWindow中的icon属性,传入String类型的图标URL,可为窗口标题栏增设图标
|
||||
4. 完善JavaFX-Plus生命周期
|
||||
5. 新增日志log模块
|
||||
6. 新增语言国际化操作
|
||||
7. 新增测试生命周期LifeDemo示例和测试国际化的LanguageDemo示例代码
|
||||
8. 规范化代码和更新README
|
||||
|
||||
|
||||
BIN
README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_01.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_02.png
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
README/language_demo.gif
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
README/lifeDemo/lifeDemo.gif
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
README/lifeDemo/lifeDemo.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
README/lifeDemo/life_demo01.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
README/log_demo.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
README/template.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
BIN
README/template_incude.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
doc/JavaFX-Plus-Introduction.xmind
Normal file
BIN
doc/JavaFX-Plus-Introduction_en.xmind
Normal file
BIN
doc/JavaFX-Plus-LifeCycle.pptx
Normal file
BIN
doc/JavaFX-Plus-LifeCycle_en.pptx
Normal file
13
pom.xml
@@ -43,6 +43,19 @@
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- log4j 日志-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.7.21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-core</artifactId>
|
||||
<version>9.0.29</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -2,10 +2,13 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Inherited
|
||||
public @interface FXBind {
|
||||
String [] value();
|
||||
String[] value();
|
||||
}
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* This is use for marking A controller as FX-Plus Controller
|
||||
@Author jack
|
||||
@Date:2019/6/25 1:34
|
||||
*
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 1:34
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface FXController {
|
||||
String path();
|
||||
|
||||
double preWidth() default 0.0;
|
||||
|
||||
double preHeight() default 0.0;
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @description 程序语言,默认不设置
|
||||
* @version 1.2
|
||||
*/
|
||||
FXPlusLocale locale() default FXPlusLocale.NONE;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:36
|
||||
*/
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 1:36
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Inherited
|
||||
|
||||
@@ -3,8 +3,10 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:35
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 1:35
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
@@ -6,8 +6,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/27 20:10
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/27 20:10
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
|
||||
@@ -3,8 +3,10 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 13:06
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 13:06
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
|
||||
@@ -3,10 +3,11 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description 重定向的注解
|
||||
* @date 2019/12/3 12:53
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,8 +6,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:55
|
||||
* @author jack
|
||||
* @date 2019/6/25 2:55
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
@@ -11,28 +11,30 @@ import java.lang.annotation.Target;
|
||||
* It is legal to use same method which has same name because JavaFX-Plus will identify a method with its full class name
|
||||
* In addition ,name is optional , default name will be the class name and method name
|
||||
* you can use this cn.edu.scau.biubiusuisui.annotation as the following cn.edu.scau.biubiusuisui.example
|
||||
* @FXSernder
|
||||
* public class A{
|
||||
* public void test(){
|
||||
*
|
||||
* }
|
||||
* }
|
||||
* <p>
|
||||
* \@FXSender
|
||||
* public class A{
|
||||
* public void test(){
|
||||
* <p>
|
||||
* }
|
||||
* }
|
||||
* name will be A.name(It will only contain base class name and this name)
|
||||
* or you can use
|
||||
* @FXSernder("testDemo")
|
||||
* public class A{
|
||||
* public void test(){
|
||||
*
|
||||
* }
|
||||
* }
|
||||
* name will be A.testDemo
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 13:02
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @FXSernder("testDemo") public class A{
|
||||
* public void test(){
|
||||
* <p>
|
||||
* }
|
||||
* }
|
||||
* name will be A.testDemo
|
||||
* @date 2019/6/25 13:02
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface FXSender {
|
||||
String name()default "";
|
||||
String name() default "";
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ package cn.edu.scau.biubiusuisui.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 3:06
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 3:06
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
|
||||
@@ -1,24 +1,44 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:36
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 1:36
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface FXWindow {
|
||||
double preWidth() default 0.0;
|
||||
double preHeight()default 0.0;
|
||||
|
||||
double preHeight() default 0.0;
|
||||
|
||||
double minWidth() default 0.0;
|
||||
|
||||
double minHeight() default 0.0;
|
||||
|
||||
boolean resizable() default false;
|
||||
|
||||
boolean draggable() default false;
|
||||
|
||||
boolean mainStage() default false;
|
||||
|
||||
StageStyle style() default StageStyle.DECORATED;
|
||||
String title () ;
|
||||
|
||||
String title();
|
||||
|
||||
/**
|
||||
* @description 图标URL
|
||||
* @version 1.2
|
||||
*/
|
||||
String icon() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -58,29 +58,12 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads an object hierarchy from an XML document.
|
||||
*
|
||||
* @since JavaFX 2.0
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXMLLoaderPlus {
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@ import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXBuilder;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXControllerFactory;
|
||||
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtils;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtil;
|
||||
import cn.edu.scau.biubiusuisui.utils.FileUtil;
|
||||
import cn.edu.scau.biubiusuisui.utils.LogUtil;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
@@ -14,10 +18,14 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:54
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 2:54
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXPlusApplication {
|
||||
private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXPlusApplication.class);
|
||||
// Application
|
||||
|
||||
private static FXWindowParser windowAnnotationParser = new FXWindowParser();
|
||||
|
||||
@@ -28,9 +36,15 @@ public class FXPlusApplication {
|
||||
public static boolean IS_SCENE_BUILDER = true;
|
||||
|
||||
public static void start(Class clazz, BeanBuilder beanBuilder) {
|
||||
logger.info("starting JavaFX-Plus Application");
|
||||
logger.info("\n" + FileUtil.readFileFromResources("banner.txt"));
|
||||
// 初始化日志路径
|
||||
LogUtil.initLog4jBase();
|
||||
|
||||
IS_SCENE_BUILDER = false;
|
||||
FXPlusApplication.beanBuilder = beanBuilder;
|
||||
Annotation[] annotations = clazz.getDeclaredAnnotations();
|
||||
logger.info("starting to scanning and registering controllers");
|
||||
for (Annotation annotation : annotations) {
|
||||
if (FXScan.class.equals(annotation.annotationType())) {
|
||||
String[] dirs = ((FXScan) annotation).base();
|
||||
@@ -40,12 +54,15 @@ public class FXPlusApplication {
|
||||
}
|
||||
Set<String> classNames = new HashSet<>();
|
||||
for (String dir : sets) {
|
||||
ClassUtils classUtils = new ClassUtils();
|
||||
List<String> temps = classUtils.scanAllClassName(dir);
|
||||
logger.info("scanning directory: " + dir);
|
||||
ClassUtil classUtil = new ClassUtil();
|
||||
List<String> temps = classUtil.scanAllClassName(dir);
|
||||
for (String className : temps) {
|
||||
try {
|
||||
logger.info("loading class: " + className);
|
||||
loadFXPlusClass(className, beanBuilder);
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -60,7 +77,9 @@ public class FXPlusApplication {
|
||||
|
||||
private static void loadFXPlusClass(String className, BeanBuilder beanBuilder) throws ClassNotFoundException {
|
||||
Class clazz = Class.forName(className);
|
||||
// 是窗口,需要初始化Stage
|
||||
if (clazz.getAnnotation(FXWindow.class) != null) {
|
||||
logger.info("loading stage of class: " + className);
|
||||
FXControllerFactory.loadStage(clazz, beanBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,21 +4,20 @@ import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import cn.edu.scau.biubiusuisui.exception.NotFXWindowException;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtils;
|
||||
import javafx.scene.Scene;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.utils.ResourceBundleUtil;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtil;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 5:51
|
||||
*/
|
||||
|
||||
/**
|
||||
* In JavaFX-Plus Framework Controller
|
||||
@@ -28,7 +27,16 @@ import java.util.Map;
|
||||
* M means model which is base cn.edu.scau.biubiusuisui.entity in your program
|
||||
* Every BaseController has a name which is used for identifying different <strong>instance</strong>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 5:51
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXBaseController extends Pane {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBaseController.class);
|
||||
|
||||
protected String name = "";
|
||||
private Stage stage;
|
||||
@@ -37,8 +45,8 @@ public class FXBaseController extends Pane {
|
||||
|
||||
|
||||
/**
|
||||
* @Author: yangsuiyu
|
||||
* @Descriptions: 用于携带信息数据
|
||||
* @description 用于携带信息数据
|
||||
* @version 1.2
|
||||
*/
|
||||
private Map<String, Object> query = new HashMap<>();
|
||||
private Map<String, Object> param = new HashMap<>();
|
||||
@@ -49,6 +57,7 @@ public class FXBaseController extends Pane {
|
||||
|
||||
public FXBaseController() {
|
||||
FXController fxController = null;
|
||||
FXWindow fxWindow = null;
|
||||
Annotation[] annotations = getClass().getAnnotations();
|
||||
// Find FXController cn.edu.scau.biubiusuisui.annotation
|
||||
for (Annotation annotation : annotations) {
|
||||
@@ -59,42 +68,119 @@ public class FXBaseController extends Pane {
|
||||
}
|
||||
// 添加赋予是否为窗口的逻辑
|
||||
if (annotation.annotationType().equals(FXWindow.class)) {
|
||||
fxWindow = (FXWindow) annotation;
|
||||
isWindow = true;
|
||||
}
|
||||
}
|
||||
//load fxml file to show panel in scene builder
|
||||
if (isController && FXPlusApplication.IS_SCENE_BUILDER == true) {
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(getClass().getClassLoader().getResource(fxController.path()));
|
||||
logger.info("loading the FXML file of " + this.getName());
|
||||
URL location = getClass().getClassLoader().getResource(fxController.path());
|
||||
String fxmlBaseName = StringUtil.getFilePathInResources(fxController.path());
|
||||
ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundle(fxmlBaseName, fxController.locale());
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(location);
|
||||
fxmlLoader.setRoot(this);
|
||||
fxmlLoader.setController(this);
|
||||
fxmlLoader.setShow(true);
|
||||
fxmlLoader.setResources(resourceBundle);
|
||||
try {
|
||||
// 加载前
|
||||
onLoad();
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
|
||||
/**
|
||||
* @description 相当于onReady, 页面渲染完后的操作
|
||||
* @version 1.2
|
||||
*/
|
||||
public void initialize() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在显示Stage之前的操作
|
||||
* @description 初始化onShow, onHide, onClose的生命周期
|
||||
* @version 1.2
|
||||
*/
|
||||
public void beforeShowStage() {
|
||||
public final void initLifeCycle() {
|
||||
logger.info("init the life cycle of " + this.getName());
|
||||
this.stage.setOnShowing(event -> {
|
||||
try {
|
||||
onShow();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
this.stage.setOnCloseRequest(event -> {
|
||||
try {
|
||||
onClose();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// 监听最小化窗口
|
||||
this.stage.iconifiedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
try {
|
||||
if (newValue) { //最小化
|
||||
onHide();
|
||||
} else {
|
||||
onShow(); //取消最小化
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 在加载页面之前的操作
|
||||
* @version 1.2
|
||||
*/
|
||||
public void onLoad() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 在显示页面之前的操作
|
||||
* @version 1.2
|
||||
*/
|
||||
public void onShow() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 在关闭窗口之前的操作
|
||||
* @version 1.2
|
||||
*/
|
||||
public void onClose() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 在隐藏窗口之前的操作
|
||||
* @version 1.2
|
||||
*/
|
||||
public void onHide() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* 唤起舞台
|
||||
*/
|
||||
public void showStage() {
|
||||
this.beforeShowStage();
|
||||
if (isWindow) {
|
||||
this.stage.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void showAndWait() {
|
||||
if (isWindow) {
|
||||
this.stage.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,18 +193,21 @@ public class FXBaseController extends Pane {
|
||||
}
|
||||
}
|
||||
|
||||
public void showAndWait() {
|
||||
this.beforeShowStage();
|
||||
/**
|
||||
* @description 最小化
|
||||
* @version 1.2
|
||||
*/
|
||||
public void hideStage() {
|
||||
if (isWindow) {
|
||||
this.stage.showAndWait();
|
||||
this.stage.setIconified(true);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if ("".equals(name) || name == null) { // 原本无“name == null”判断条件,会出错
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName());
|
||||
return StringUtil.getBaseClassName(getClass().getSimpleName());
|
||||
} else {
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName()) + "#" + name;
|
||||
return StringUtil.getBaseClassName(getClass().getSimpleName()) + "#" + name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ import javafx.beans.property.Property;
|
||||
/**
|
||||
* 将Controller中的JavaFX的field包装成FXFieldWrapper
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 10:03
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/28 10:03
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXFieldWrapper {
|
||||
|
||||
|
||||
@@ -5,8 +5,11 @@ import java.lang.reflect.Method;
|
||||
/**
|
||||
* This class is base cn.edu.scau.biubiusuisui.entity for queue message(or signal)
|
||||
* you mush save the instance and method which means who will run this method
|
||||
* @Author jack
|
||||
* @Date:2019/6/26 15:39
|
||||
*
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/26 15:39
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXMethodEntity {
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* Context is use for storing Controller
|
||||
* In addition,you can store an instance into Session to use it everywhere
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/26 12:28
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/26 12:28
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXPlusContext {
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package cn.edu.scau.biubiusuisui.entity;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description JavaFX的Locale枚举类型
|
||||
* @date 2020/5/3 10:47
|
||||
* @since JDK1.8 JavaFX2.0
|
||||
*/
|
||||
public enum FXPlusLocale {
|
||||
/**
|
||||
* 不设置
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* 简体中文
|
||||
*/
|
||||
SIMPLIFIED_CHINESE,
|
||||
|
||||
/**
|
||||
* 繁体中文
|
||||
*/
|
||||
TRADITIONAL_CHINESE,
|
||||
|
||||
|
||||
/**
|
||||
* English 英语
|
||||
*/
|
||||
ENGLISH,
|
||||
|
||||
|
||||
/**
|
||||
* American 美语
|
||||
*/
|
||||
AMERICAN,
|
||||
|
||||
|
||||
/**
|
||||
* Le français 法语
|
||||
*/
|
||||
FRANCE,
|
||||
|
||||
|
||||
/**
|
||||
* Deutsch 德语
|
||||
*/
|
||||
GERMANY,
|
||||
|
||||
|
||||
/**
|
||||
* lingua italiana 意大利语
|
||||
*/
|
||||
ITALIAN,
|
||||
|
||||
|
||||
/**
|
||||
* 日本人 日语
|
||||
*/
|
||||
JAPANESE,
|
||||
|
||||
|
||||
/**
|
||||
* 한국어 韩语
|
||||
*/
|
||||
KOREAN,
|
||||
}
|
||||
@@ -4,10 +4,11 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 跳转窗口携带的参数
|
||||
* @date 2020/4/6 18:06
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXRedirectParam {
|
||||
private String toController;
|
||||
|
||||
@@ -6,8 +6,11 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @date 2020/5/1 1:43
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.bindDemo")
|
||||
public class BindDemo extends Application {
|
||||
|
||||
@@ -14,11 +14,15 @@ import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @date 2020/5/1 1:43
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "bindDemo/bindDemo.fxml")
|
||||
@FXController(path = "fxml/bindDemo/bindDemo.fxml")
|
||||
@FXWindow(title = "bindDemo", mainStage = true)
|
||||
// TODO 待完善
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
// View bind to View
|
||||
@FXML
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.example.bindDemo;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 详细信息
|
||||
* @date 2020/4/6 00:29
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class Profile {
|
||||
private String birthday;
|
||||
|
||||
@@ -6,8 +6,10 @@ import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author yangsuiyu
|
||||
* @Date:2020/4/5 12:19
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @date 2020/4/5 12:19
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXEntity
|
||||
public class User {
|
||||
|
||||
@@ -4,10 +4,11 @@ import javafx.beans.property.*;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description User的JavaFXBean
|
||||
* @date 2020/4/6 14:30
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class UserPropertyEntity {
|
||||
private SimpleStringProperty name;
|
||||
|
||||
@@ -6,15 +6,17 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @description 第一个示例
|
||||
* @date 2020/1/1 23:06
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.firstDemo"}) //会扫描带FXController和FXEntity的类进行初始化
|
||||
public class Demo extends Application {
|
||||
public class FirstDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(Demo.class); //其他配置和JavaFX相同,这里要调用FXPlusAppcalition的start方法,开始FX-plus加强
|
||||
FXPlusApplication.start(FirstDemo.class); //其他配置和JavaFX相同,这里要调用FXPlusAppcalition的start方法,开始FX-plus加强
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,14 @@ import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @author jack
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @description 示例的主窗口
|
||||
* @date 2020/1/1 23:06
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "firstDemo/firstDemo.fxml")
|
||||
@FXController(path = "fxml/firstDemo/firstDemo.fxml")
|
||||
@FXWindow(title = "firstDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @description
|
||||
* @date 2020/1/1 23:07
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
|
||||
@FXEntity
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.edu.scau.biubiusuisui.example.languageDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @description 中文界面
|
||||
* @date 2020/5/3 16:23
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@FXWindow(mainStage = true, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
public class ChineseController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToChinese() {
|
||||
redirect("ChineseController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToEnglish() {
|
||||
redirect("EnglishController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToKorean() {
|
||||
redirect("KoreanController");
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect(String name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.edu.scau.biubiusuisui.example.languageDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @description 英文界面
|
||||
* @date 2020/5/3 19:54
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@FXWindow(mainStage = false, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
|
||||
public class EnglishController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToChinese() {
|
||||
redirect("ChineseController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToEnglish() {
|
||||
redirect("EnglishController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToKorean() {
|
||||
redirect("KoreanController");
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect(String name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.edu.scau.biubiusuisui.example.languageDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @description 法语界面
|
||||
* @date 2020/5/4 14:01
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@FXWindow(mainStage = false, title = "languageDemo")
|
||||
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.KOREAN)
|
||||
public class KoreanController extends FXBaseController {
|
||||
@FXML
|
||||
public void clickToChinese() {
|
||||
redirect("ChineseController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToEnglish() {
|
||||
redirect("EnglishController");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void clickToKorean() {
|
||||
redirect("KoreanController");
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirect(String name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.edu.scau.biubiusuisui.example.languageDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @description 测试语言国际化的Demo
|
||||
* @date 2020/5/3 09:57
|
||||
* @since JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.languageDemo")
|
||||
public class LanguageDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.edu.scau.biubiusuisui.example.lifeDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 弹窗
|
||||
* @date 2020/5/1 13:49
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXWindow(title = "Dialog")
|
||||
@FXController(path = "fxml/lifeDemo/dialog.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
|
||||
public class DialogController extends FXBaseController {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(DialogController.class);
|
||||
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
logger.info("DialogController----initialize");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() throws Exception {
|
||||
logger.info("DialogController----onLoad");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() throws Exception {
|
||||
logger.info("DialogController----onShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() throws Exception {
|
||||
logger.info("DialogController----onClose");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() throws Exception {
|
||||
logger.info("DialogController----onHide");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.edu.scau.biubiusuisui.example.lifeDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.utils.LogUtil;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 测试生命周期的Demo
|
||||
* @date 2020/5/1 11:50
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.lifeDemo")
|
||||
public class LifeDemo extends Application {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LifeDemo.class);
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
logger.info("LifeDemo---start");
|
||||
// Platform.setImplicitExit(false); //设置当关闭最后一个Stage时,JavaFX应用程序不会自动退出
|
||||
FXPlusApplication.start(getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
logger.info("LifeDemo---init");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
logger.info("LifeDemo---stop");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.edu.scau.biubiusuisui.example.lifeDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.input.Clipboard;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 主窗口
|
||||
* @date 2020/5/1 11:53
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXWindow(mainStage = true, title = "lifeDemo", icon = "image/icon.png")
|
||||
@FXController(path = "fxml/lifeDemo/lifeMain.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
public class MainController extends FXBaseController {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBaseController.class);
|
||||
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
logger.info("MainController----initialize");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() throws Exception {
|
||||
logger.info("MainController----onShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() throws Exception {
|
||||
logger.info("MainController----onLoad");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() throws Exception {
|
||||
logger.info("MainController----onClose");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() throws Exception {
|
||||
logger.info("MainController----onHide");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void go() {
|
||||
redirectToDialog();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void goAndClose() {
|
||||
redirectToDialogAndClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹窗不关闭窗口
|
||||
*/
|
||||
@FXRedirect(close = false)
|
||||
public String redirectToDialog() {
|
||||
return "DialogController";
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹窗并关闭本窗口
|
||||
*/
|
||||
@FXRedirect()
|
||||
public String redirectToDialogAndClose() {
|
||||
return "DialogController";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.edu.scau.biubiusuisui.example.lifeDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 子组件
|
||||
* @date 2020/5/1 13:48
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "fxml/lifeDemo/subBar.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
|
||||
public class SubController extends FXBaseController {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(SubController.class);
|
||||
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
logger.info("SubController----initialize");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() throws Exception {
|
||||
logger.info("SubController----onShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() throws Exception {
|
||||
logger.info("SubController----onLoad");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() throws Exception {
|
||||
logger.info("SubController----onClose");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() throws Exception {
|
||||
logger.info("SubController----onHide");
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,15 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 1:43
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.listDemo")
|
||||
public class ListDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(ListDemo.class);
|
||||
FXPlusApplication.start(getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,15 @@ import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 1:43
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "listDemo/listDemo.fxml")
|
||||
@FXController(path = "fxml/listDemo/listDemo.fxml")
|
||||
@FXWindow(title = "listDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 12:19
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 12:19
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXEntity
|
||||
public class User {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.edu.scau.biubiusuisui.example.logDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.example.lifeDemo.LifeDemo;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.utils.LogUtil;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @description 测试日志的Demo
|
||||
* @date 2020/5/2 19:58
|
||||
* @since JDK1.8
|
||||
*/
|
||||
public class LogDemo {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LogDemo.class);
|
||||
|
||||
public void testLogger() {
|
||||
logger.info("info");
|
||||
logger.error("error");
|
||||
logger.debug("debug");
|
||||
logger.warn("warn");
|
||||
}
|
||||
|
||||
public void testLogUtil() {
|
||||
LogUtil.info("info");
|
||||
LogUtil.error("error");
|
||||
LogUtil.debug("debug");
|
||||
LogUtil.warn("warn");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
LogDemo demo = new LogDemo();
|
||||
demo.testLogger();
|
||||
demo.testLogUtil();
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,28 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.mqDemo")
|
||||
public class MQDemo extends Application {
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
System.out.println("application init");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
System.out.println("application start");
|
||||
FXPlusApplication.start(MQDemo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
System.out.println("application stop");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.control.TextArea;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 主界面
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "mqDemo/main.fxml")
|
||||
@FXController(path = "fxml/mqDemo/main.fxml")
|
||||
@FXWindow(mainStage = true, title = "MQDemo")
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
@@ -31,5 +32,4 @@ public class MainController extends FXBaseController {
|
||||
// 处理导航栏的点击事件
|
||||
outTA.appendText(msg + "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@ import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description 导航栏示例
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "mqDemo/topBar.fxml")
|
||||
@FXController(path = "fxml/mqDemo/topBar.fxml")
|
||||
public class TopBarController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
|
||||
@@ -5,12 +5,14 @@ import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description
|
||||
* @date 2019/12/4 21:00
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "redirectDemo/dialog.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/dialog.fxml")
|
||||
@FXWindow(title = "弹窗")
|
||||
public class DialogController extends FXBaseController {
|
||||
|
||||
}
|
||||
|
||||
@@ -10,16 +10,15 @@ import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description
|
||||
* @date 2019/12/3 11:53
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "redirectDemo/login.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/login.fxml")
|
||||
@FXWindow(title = "redirectDemo", mainStage = true)
|
||||
public class LoginController extends FXBaseController {
|
||||
|
||||
|
||||
@@ -6,13 +6,15 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description 测试重定向功能的Application
|
||||
* @date 2019/12/3 11:52
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.redirectDemo")
|
||||
public class RedirectDemo extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(RedirectDemo.class);
|
||||
|
||||
@@ -11,12 +11,13 @@ import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description
|
||||
* @date 2019/12/4 00:07
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "redirectDemo/register.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/register.fxml")
|
||||
@FXWindow(title = "register")
|
||||
public class RegisterController extends FXBaseController {
|
||||
@FXML
|
||||
|
||||
@@ -4,23 +4,19 @@ import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.exception.NotFXWindowException;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description 登录成功的Controller
|
||||
* @date 2019/12/3 12:43
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "redirectDemo/success.fxml")
|
||||
@FXController(path = "fxml/redirectDemo/success.fxml")
|
||||
@FXWindow(title = "success")
|
||||
public class SuccessController extends FXBaseController implements Initializable {
|
||||
public class SuccessController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
private Label title;
|
||||
@@ -41,7 +37,12 @@ public class SuccessController extends FXBaseController implements Initializable
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShowStage() {
|
||||
public void onShow() {
|
||||
try {
|
||||
super.onShow();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (this.getQuery().get("showType") != null) {
|
||||
String showType = (String) this.getQuery().get("showType");
|
||||
if (showType.equals("1")) { //注册
|
||||
@@ -67,8 +68,4 @@ public class SuccessController extends FXBaseController implements Initializable
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.1
|
||||
* @description 简单的用户实体
|
||||
* @date 2020/1/14 22:39
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class UserEntity {
|
||||
private String username;
|
||||
|
||||
@@ -7,12 +7,13 @@ import javafx.fxml.FXML;
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 主控制器
|
||||
* @date 2020/4/5 00:05
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXController(path = "resizableDemo/resizableDemo.fxml")
|
||||
@FXController(path = "fxml/resizableDemo/resizableDemo.fxml")
|
||||
@FXWindow(mainStage = true, title = "resizableDemo", draggable = true, resizable = true, style = StageStyle.UNDECORATED)
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
|
||||
@@ -6,15 +6,16 @@ import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.0
|
||||
* @description 缩放和拖拽的示例
|
||||
* @date 2020/4/5 00:04
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.resizableDemo")
|
||||
public class Demo extends Application {
|
||||
public class ResizableDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(Demo.class);
|
||||
FXPlusApplication.start(ResizableDemo.class);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.exception;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 不合法URL
|
||||
* @date 2020/4/6 15:59
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class InvalidURLException extends Exception {
|
||||
public InvalidURLException() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package cn.edu.scau.biubiusuisui.exception;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 3:00
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 3:00
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class NoSuchChangeMethod extends Exception {
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.exception;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 某Controller不是窗口
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 某Controller不是窗口的错误
|
||||
* @date 2020/4/6 17:10
|
||||
* @email suiyu_yang@163.com
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class NotFXWindowException extends Exception {
|
||||
public NotFXWindowException() {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package cn.edu.scau.biubiusuisui.exception;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 7:23
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 7:23
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class ProtocolNotSupport extends Exception{
|
||||
public ProtocolNotSupport(){
|
||||
public class ProtocolNotSupport extends Exception {
|
||||
public ProtocolNotSupport() {
|
||||
super("protocolNotSupport");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.expression;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 2:02
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 2:02
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public interface BindParser {
|
||||
public void parse(Object target,String expression);
|
||||
public void parse(Object target, String expression);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ package cn.edu.scau.biubiusuisui.expression.action;
|
||||
import cn.edu.scau.biubiusuisui.expression.BindParser;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 2:03
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 2:03
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class ChangeParser implements BindParser {
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 20:03
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 20:03
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExpFunction<T,U,R>{
|
||||
public interface ExpFunction<T, U, R> {
|
||||
R apply(T t, U u);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ import java.lang.reflect.Parameter;
|
||||
* 最后
|
||||
* left.bind(right)
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/7/23 15:05
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/23 15:05
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class ExpressionParser {
|
||||
|
||||
|
||||
@@ -9,8 +9,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 20:00
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 20:00
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FunctionExpression extends Expression {
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ import com.sun.javafx.fxml.BeanAdapter;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/23 15:16
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/23 15:16
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class MyBeanAdapter extends BeanAdapter {
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class MyExpressionValue extends ObservableValueBase<Object> {
|
||||
|
||||
// Monitors a namespace for changes along a key path
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/4 11:16
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/4 11:16
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public interface BeanBuilder {
|
||||
/**
|
||||
* 万能工厂方法
|
||||
* 万能工厂方法
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 实例对象
|
||||
*/
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/4 11:13
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/4 11:13
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXBuilder implements BeanBuilder{
|
||||
public class FXBuilder implements BeanBuilder {
|
||||
private IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBuilder.class);
|
||||
|
||||
@Override
|
||||
public Object getBean(Class type) {
|
||||
Object object = null;
|
||||
try {
|
||||
object = type.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return object;
|
||||
|
||||
@@ -7,12 +7,17 @@ import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
|
||||
import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
|
||||
import cn.edu.scau.biubiusuisui.expression.data.ExpressionParser;
|
||||
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXControllerProxy;
|
||||
import cn.edu.scau.biubiusuisui.stage.StageManager;
|
||||
import cn.edu.scau.biubiusuisui.utils.ResourceBundleUtil;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtil;
|
||||
import javafx.collections.ObservableMap;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.Pane;
|
||||
@@ -21,12 +26,16 @@ import javafx.stage.Stage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 8:12
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 8:12
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXControllerFactory {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXControllerFactory.class);
|
||||
|
||||
private static final BeanBuilder BEAN_BUILDER = new FXBuilder();
|
||||
private static FXWindowParser fxWindowAnnotationParser = new FXWindowParser();
|
||||
@@ -91,7 +100,11 @@ public class FXControllerFactory {
|
||||
FXBaseController fxBaseController = null;
|
||||
FXBaseController fxControllerProxy = null;
|
||||
if (fxController != null) {
|
||||
logger.info("loading the FXML file of " + clazz.getName());
|
||||
String fxmlPathName = fxController.path();
|
||||
String fxmlBaseName = StringUtil.getFilePathInResources(fxmlPathName);
|
||||
FXPlusLocale fxPlusLocale = fxController.locale();
|
||||
ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundle(fxmlBaseName, fxPlusLocale);
|
||||
fxmlPath = clazz.getClassLoader().getResource(fxmlPathName);
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(fxmlPath);
|
||||
// create a cn.edu.scau.biubiusuisui.proxy for monitoring methods
|
||||
@@ -105,8 +118,13 @@ public class FXControllerFactory {
|
||||
fxmlLoader.setRoot(fxControllerProxy);
|
||||
fxmlLoader.setController(fxControllerProxy);
|
||||
fxmlLoader.setBaseController(fxBaseController);
|
||||
fxmlLoader.setResources(resourceBundle);
|
||||
try {
|
||||
|
||||
fxControllerProxy.onLoad(); //页面加载
|
||||
|
||||
parent = fxmlLoader.load();
|
||||
|
||||
if (controllerName != null) {
|
||||
fxControllerProxy.setName(controllerName);
|
||||
fxBaseController.setName(controllerName);
|
||||
@@ -118,7 +136,10 @@ public class FXControllerFactory {
|
||||
scanBind(namespace, fxBaseController); //处理@FXBind
|
||||
register(fxBaseController, fxControllerProxy);
|
||||
} catch (IOException exception) {
|
||||
logger.error(exception.getMessage());
|
||||
throw new RuntimeException(exception);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -147,6 +168,7 @@ public class FXControllerFactory {
|
||||
* @Description 为有FXWindow注解的类创建Stage
|
||||
*/
|
||||
private static Stage createWindow(FXWindow fxWindow, Class clazz, FXBaseController fxBaseControllerProxy) {
|
||||
logger.info("creating window");
|
||||
Stage stage = new Stage();
|
||||
fxBaseControllerProxy.setStage(stage);
|
||||
double preWidth = fxWindow.preWidth() == 0 ? fxBaseControllerProxy.getPrefWidth() : fxWindow.preWidth();
|
||||
@@ -155,6 +177,9 @@ public class FXControllerFactory {
|
||||
stage.setScene(scene);
|
||||
fxWindowAnnotationParser.parse(stage, fxBaseControllerProxy, fxWindow);
|
||||
|
||||
// 此处设置生命周期中的onShow,onHide,onClose
|
||||
fxBaseControllerProxy.initLifeCycle();
|
||||
|
||||
StageManager.getInstance().registerWindow(clazz, fxBaseControllerProxy); //注册舞台
|
||||
if (fxWindow.mainStage() == true) { //当是主舞台时,先show为敬
|
||||
fxBaseControllerProxy.showStage();
|
||||
@@ -253,6 +278,7 @@ public class FXControllerFactory {
|
||||
Object fieldValueProxy = FXEntityFactory.wrapFXBean(fieldValue);
|
||||
field.set(fxControllerObject, fieldValueProxy);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -277,6 +303,7 @@ public class FXControllerFactory {
|
||||
Object fieldValue = field.get(object);
|
||||
namespace.put(fx_id, fieldValue);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -303,8 +330,10 @@ public class FXControllerFactory {
|
||||
expressionParser.parse(objectValue, e);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchChangeMethod noSuchChangeMethod) {
|
||||
logger.error(noSuchChangeMethod.getMessage());
|
||||
noSuchChangeMethod.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXFieldWrapper;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtils;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtil;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
@@ -15,8 +15,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 1:12
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/28 1:12
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXEntityFactory {
|
||||
|
||||
@@ -65,7 +67,7 @@ public class FXEntityFactory {
|
||||
Map<String, FXFieldWrapper> fxFieldWrapperMap = new HashMap<>();
|
||||
Field[] fields = entityObject.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
Annotation annotation = ClassUtils.getAnnotationInList(FXField.class, field.getDeclaredAnnotations());
|
||||
Annotation annotation = ClassUtil.getAnnotationInList(FXField.class, field.getDeclaredAnnotations());
|
||||
if (annotation != null) {
|
||||
Property property = null;
|
||||
field.setAccessible(true);
|
||||
|
||||
@@ -7,8 +7,10 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/30 10:11
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/30 10:11
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class DragWindowHandlerImpl implements EventHandler<MouseEvent> {
|
||||
//参考<a href="https://www.cnblogs.com/moonlightL/p/5982679.html"></a>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:54
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/7/27 1:54
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public interface Draggale {
|
||||
|
||||
|
||||
@@ -1,33 +1,66 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
import cn.edu.scau.biubiusuisui.utils.FileUtil;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtil;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/30 10:40
|
||||
* @Description 解析@FXWindow
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/30 10:40
|
||||
* @description 解析@FXWindow
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXWindowParser {
|
||||
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXWindowParser.class);
|
||||
|
||||
public void parse(Stage stage, Pane fxControllerProxy, FXWindow fxWindow) {
|
||||
|
||||
public void parse(Stage stage, FXBaseController fxControllerProxy, FXWindow fxWindow) {
|
||||
logger.info("parsing @FXWindow of class: " + fxControllerProxy.getName());
|
||||
// 处理 title
|
||||
stage.setTitle(fxWindow.title());
|
||||
|
||||
// 处理 icon
|
||||
if (!"".equals(fxWindow.icon())) {
|
||||
try {
|
||||
URL iconUrl = new FileUtil().getFilePathFromResources(fxWindow.icon());
|
||||
if (iconUrl != null) {
|
||||
if (new File(StringUtil.getRootPath(iconUrl)).exists()) {
|
||||
stage.getIcons().add(new Image(fxWindow.icon()));
|
||||
} else {
|
||||
logger.warn("the icon file has not existed");
|
||||
}
|
||||
} else {
|
||||
logger.warn("the icon file has not existed");
|
||||
}
|
||||
} catch (ProtocolNotSupport protocolNotSupport) {
|
||||
logger.error(protocolNotSupport.getMessage(), protocolNotSupport);
|
||||
protocolNotSupport.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// fxWindow的resizable默认为false
|
||||
if (fxWindow.resizable()) {
|
||||
stage.setResizable(true);
|
||||
}
|
||||
|
||||
// 处理draggable和resizable
|
||||
if (fxWindow.draggable() || fxWindow.resizable()) {
|
||||
EventHandler dragWindowHandler = new DragWindowHandlerImpl(stage, fxWindow.minWidth(), fxWindow.minHeight(), fxControllerProxy, fxWindow.draggable(), fxWindow.resizable());
|
||||
fxControllerProxy.setOnMousePressed(dragWindowHandler);
|
||||
fxControllerProxy.setOnMouseDragged(dragWindowHandler);
|
||||
fxControllerProxy.setOnMouseMoved(dragWindowHandler);
|
||||
}
|
||||
// 处理style
|
||||
stage.initStyle(fxWindow.style());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
67
src/main/java/cn/edu/scau/biubiusuisui/log/FXPlusLogger.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package cn.edu.scau.biubiusuisui.log;
|
||||
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description JavaPlus的日志类
|
||||
* @date 2020/5/1 10:55
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXPlusLogger implements IFXPlusLogger {
|
||||
private Logger logger;
|
||||
private String FQCN;
|
||||
|
||||
public FXPlusLogger(Logger logger) {
|
||||
this.FQCN = FXPlusLogger.class.getName();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public FXPlusLogger(String fqcn, Logger logger) {
|
||||
this.FQCN = fqcn;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Object message) {
|
||||
logger.log(FQCN, Level.DEBUG, message, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Object message, Throwable t) {
|
||||
logger.log(FQCN, Level.DEBUG, message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message) {
|
||||
logger.log(FQCN, Level.INFO, message, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message, Throwable t) {
|
||||
logger.log(FQCN, Level.INFO, message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message) {
|
||||
logger.log(FQCN, Level.WARN, message, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message, Throwable t) {
|
||||
logger.log(FQCN, Level.WARN, message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message) {
|
||||
logger.log(FQCN, Level.ERROR, message, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message, Throwable t) {
|
||||
logger.log(FQCN, Level.ERROR, message, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.edu.scau.biubiusuisui.log;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 日志类上下文
|
||||
* @date 2020/5/1 10:56
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXPlusLoggerContext {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.edu.scau.biubiusuisui.log;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.utils.LogUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 生成日志类的工厂
|
||||
* @date 2020/5/1 10:56
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXPlusLoggerFactory {
|
||||
|
||||
private FXPlusLoggerFactory() {
|
||||
|
||||
}
|
||||
|
||||
public static IFXPlusLogger getLogger(Class<?> clazz) {
|
||||
LogUtil.initLog4jBase();
|
||||
Logger logger = Logger.getLogger(clazz);
|
||||
return new FXPlusLogger(logger);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.edu.scau.biubiusuisui.log;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* @author suisui
|
||||
* @version 1.2
|
||||
* @description 日志接口
|
||||
* @date 2020/5/1 10:54
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public interface IFXPlusLogger {
|
||||
void debug(Object message);
|
||||
|
||||
void debug(Object message, Throwable t);
|
||||
|
||||
void info(Object message);
|
||||
|
||||
void info(Object message, Throwable t);
|
||||
|
||||
void warn(Object message);
|
||||
|
||||
void warn(Object message, Throwable t);
|
||||
|
||||
void error(Object message);
|
||||
|
||||
void error(Object message, Throwable t);
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package cn.edu.scau.biubiusuisui.messageQueue;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXReceiver;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXMethodEntity;
|
||||
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
|
||||
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -13,11 +15,14 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 12:24
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 12:24
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
|
||||
public class MessageQueue {
|
||||
private IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(MessageQueue.class);
|
||||
|
||||
private static Map<String, List<FXMethodEntity>> receivers = new ConcurrentHashMap<>(); //Map<主题,订阅了主题的所有方法>
|
||||
|
||||
@@ -45,6 +50,7 @@ public class MessageQueue {
|
||||
Annotation[] annotations = method.getDeclaredAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
if (FXReceiver.class.equals(annotation.annotationType())) {
|
||||
logger.info("registering consumer: " + fxBaseControllerProxy.getName());
|
||||
// System.out.println("FXReceiver");
|
||||
FXReceiver receiver = (FXReceiver) annotation;
|
||||
FXMethodEntity fxMethodEntity = new FXMethodEntity(fxBaseControllerProxy, method);
|
||||
@@ -75,8 +81,10 @@ public class MessageQueue {
|
||||
try {
|
||||
method.invoke(fxBaseController);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
@@ -84,8 +92,10 @@ public class MessageQueue {
|
||||
// obj the object the underlying method is invoked from
|
||||
method.invoke(fxBaseController, msg);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
logger.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ import java.lang.reflect.Method;
|
||||
* This proxy class intercept Methods that has special annotation such as
|
||||
* FXSender which is a mark for message queue
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:03
|
||||
* @author jack
|
||||
* @version 1.0
|
||||
* @date 2019/6/25 2:03
|
||||
* @since JavaFX2.0 JDK1.8
|
||||
*/
|
||||
public class FXControllerProxy implements MethodInterceptor {
|
||||
|
||||
|
||||