├── .gitignore
├── LICENSE
├── README.en.md
├── README.en
├── JavaFX-Plus-LifeCycle_en
│ ├── JavaFX-Plus-LifeCycle_en_01.png
│ └── JavaFX-Plus-LifeCycle_en_02.png
├── JavaFX-Plus.png
├── JavaFX-Plus_en.png
├── Resizable_en.gif
├── actionDemo
│ └── 20191210-175409-actionDemo.gif
├── bindhow.gif
├── controllerConfig.png
├── demo1.png
├── draggable_en.gif
├── expression.gif
├── expressionV2V.gif
├── helloWorldDemo.gif
├── language_demo.gif
├── language_demo_en.gif
├── lifeDemo
│ ├── lifeDemo_en.gif
│ ├── lifeDemo_pkg_en.png
│ ├── life_demo01_en.png
│ └── life_demo_en.png
├── log_demo_en.png
├── modulesAction.gif
├── moveable.gif
├── mqDemo
│ └── 20191208-194336-signalshow.gif
├── redirectDemo
│ ├── 20191208-125511-not_close.gif
│ └── 20191208-125739-close.gif
├── redirect_with_data_en.gif
├── resizeAble.gif
├── template_en.png
├── template_incude_en.png
└── wrap_JavaBean.png
├── README.md
├── README
├── JavaFX-Plus-LifeCycle
│ ├── JavaFX-Plus-LifeCycle_01.png
│ └── JavaFX-Plus-LifeCycle_02.png
├── JavaFX-Plus.png
├── JavaFX-Plus_en.png
├── Resizable.gif
├── actionDemo
│ └── 20191210-175409-actionDemo.gif
├── bindhow.gif
├── controllerConfig.png
├── demo1.png
├── draggable.gif
├── expression.gif
├── expressionV2V.gif
├── helloWorldDemo.gif
├── image-20200407003220469.png
├── language_demo.gif
├── lifeDemo
│ ├── lifeDemo.gif
│ ├── lifeDemo.png
│ ├── lifeDemo_pkg.png
│ └── life_demo01.png
├── log_demo.png
├── modulesAction.gif
├── moveable.gif
├── mqDemo
│ └── 20191208-194336-signalshow.gif
├── redirectDemo
│ ├── 20191208-125511-not_close.gif
│ └── 20191208-125739-close.gif
├── redirect_with_data.gif
├── resizeAble.gif
├── template.png
├── template_incude.png
└── wrap_JavaBean.png
├── doc
├── JavaFX-Plus-Introduction.xmind
├── JavaFX-Plus-Introduction_en.xmind
├── JavaFX-Plus-LifeCycle.pptx
└── JavaFX-Plus-LifeCycle_en.pptx
├── pom.xml
└── src
├── main
├── java
│ └── cn
│ │ └── edu
│ │ └── scau
│ │ └── biubiusuisui
│ │ ├── annotation
│ │ ├── FXBind.java
│ │ ├── FXController.java
│ │ ├── FXData.java
│ │ ├── FXEntity.java
│ │ ├── FXField.java
│ │ ├── FXReceiver.java
│ │ ├── FXRedirect.java
│ │ ├── FXScan.java
│ │ ├── FXSender.java
│ │ ├── FXValue.java
│ │ └── FXWindow.java
│ │ ├── config
│ │ ├── FXMLLoaderPlus.java
│ │ └── FXPlusApplication.java
│ │ ├── entity
│ │ ├── FXBaseController.java
│ │ ├── FXFieldWrapper.java
│ │ ├── FXMethodEntity.java
│ │ ├── FXPlusContext.java
│ │ ├── FXPlusLocale.java
│ │ └── FXRedirectParam.java
│ │ ├── example
│ │ ├── bindDemo
│ │ │ ├── BindDemo.java
│ │ │ ├── MainController.java
│ │ │ ├── Profile.java
│ │ │ ├── User.java
│ │ │ └── UserPropertyEntity.java
│ │ ├── firstDemo
│ │ │ ├── FirstDemo.java
│ │ │ ├── MainController.java
│ │ │ └── Student.java
│ │ ├── languageDemo
│ │ │ ├── ChineseController.java
│ │ │ ├── EnglishController.java
│ │ │ ├── KoreanController.java
│ │ │ └── LanguageDemo.java
│ │ ├── lifeDemo
│ │ │ ├── DialogController.java
│ │ │ ├── LifeDemo.java
│ │ │ ├── MainController.java
│ │ │ └── SubController.java
│ │ ├── listDemo
│ │ │ ├── ListDemo.java
│ │ │ ├── MainController.java
│ │ │ └── User.java
│ │ ├── logDemo
│ │ │ └── LogDemo.java
│ │ ├── mqDemo
│ │ │ ├── MQDemo.java
│ │ │ ├── MainController.java
│ │ │ └── TopBarController.java
│ │ ├── redirectDemo
│ │ │ ├── DialogController.java
│ │ │ ├── LoginController.java
│ │ │ ├── RedirectDemo.java
│ │ │ ├── RegisterController.java
│ │ │ ├── SuccessController.java
│ │ │ └── UserEntity.java
│ │ └── resizableDemo
│ │ │ ├── MainController.java
│ │ │ └── ResizableDemo.java
│ │ ├── exception
│ │ ├── InvalidURLException.java
│ │ ├── NoSuchChangeMethod.java
│ │ ├── NotFXWindowException.java
│ │ └── ProtocolNotSupport.java
│ │ ├── expression
│ │ ├── BindParser.java
│ │ ├── action
│ │ │ └── ChangeParser.java
│ │ └── data
│ │ │ ├── ExpFunction.java
│ │ │ ├── ExpressionParser.java
│ │ │ ├── FunctionExpression.java
│ │ │ ├── MyBeanAdapter.java
│ │ │ └── MyExpressionValue.java
│ │ ├── factory
│ │ ├── BeanBuilder.java
│ │ ├── FXBuilder.java
│ │ ├── FXControllerFactory.java
│ │ └── FXEntityFactory.java
│ │ ├── function
│ │ ├── DragWindowHandlerImpl.java
│ │ ├── Draggale.java
│ │ └── FXWindowParser.java
│ │ ├── log
│ │ ├── FXPlusLogger.java
│ │ ├── FXPlusLoggerContext.java
│ │ ├── FXPlusLoggerFactory.java
│ │ └── IFXPlusLogger.java
│ │ ├── messageQueue
│ │ └── MessageQueue.java
│ │ ├── proxy
│ │ ├── FXControllerProxy.java
│ │ └── FXEntityProxy.java
│ │ ├── stage
│ │ └── StageManager.java
│ │ └── utils
│ │ ├── BeanUtil.java
│ │ ├── ClassUtil.java
│ │ ├── FileUtil.java
│ │ ├── LogUtil.java
│ │ ├── PathUtil.java
│ │ ├── ResourceBundleUtil.java
│ │ └── StringUtil.java
└── resources
│ ├── applicationContext.xml
│ ├── banner.txt
│ ├── fxml
│ ├── Main.fxml
│ ├── Main2.fxml
│ ├── SpringExpressionDemo.fxml
│ ├── bindDemo
│ │ └── bindDemo.fxml
│ ├── firstDemo
│ │ └── firstDemo.fxml
│ ├── index.js
│ ├── languageDemo
│ │ ├── languageDemo.fxml
│ │ ├── languageDemo_en.properties
│ │ ├── languageDemo_ko.properties
│ │ └── languageDemo_zh_CN.properties
│ ├── lifeDemo
│ │ ├── dialog.fxml
│ │ ├── dialog_en.properties
│ │ ├── dialog_zh_CN.properties
│ │ ├── lifeMain.fxml
│ │ ├── lifeMain_en.properties
│ │ ├── lifeMain_zh_CN.properties
│ │ ├── subBar.fxml
│ │ ├── subBar_en.properties
│ │ └── subBar_zh_CN.properties
│ ├── listDemo
│ │ └── listDemo.fxml
│ ├── moveDemo.fxml
│ ├── mqDemo
│ │ ├── main.fxml
│ │ └── topBar.fxml
│ ├── redirectDemo
│ │ ├── dialog.fxml
│ │ ├── login.fxml
│ │ ├── register.css
│ │ ├── register.fxml
│ │ └── success.fxml
│ ├── resizableDemo
│ │ └── resizableDemo.fxml
│ ├── springDemo.fxml
│ └── springDemo2.fxml
│ ├── image
│ └── icon.png
│ ├── language
│ ├── javafxplus_en.properties
│ └── javafxplus_zh_CN.properties
│ └── log4j.properties
└── test
└── java
├── MainTest.java
└── cn
└── edu
└── scau
└── biubiusuisui
├── expression
├── ExpressionParserTest.java
└── data
│ └── ExpressionParserTest.java
├── factory
└── FXEntityFactoryTest.java
└── utils
└── ClassUtilsTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Biubiu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.en/JavaFX-Plus-LifeCycle_en/JavaFX-Plus-LifeCycle_en_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/JavaFX-Plus-LifeCycle_en/JavaFX-Plus-LifeCycle_en_01.png
--------------------------------------------------------------------------------
/README.en/JavaFX-Plus-LifeCycle_en/JavaFX-Plus-LifeCycle_en_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/JavaFX-Plus-LifeCycle_en/JavaFX-Plus-LifeCycle_en_02.png
--------------------------------------------------------------------------------
/README.en/JavaFX-Plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/JavaFX-Plus.png
--------------------------------------------------------------------------------
/README.en/JavaFX-Plus_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/JavaFX-Plus_en.png
--------------------------------------------------------------------------------
/README.en/Resizable_en.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/Resizable_en.gif
--------------------------------------------------------------------------------
/README.en/actionDemo/20191210-175409-actionDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/actionDemo/20191210-175409-actionDemo.gif
--------------------------------------------------------------------------------
/README.en/bindhow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/bindhow.gif
--------------------------------------------------------------------------------
/README.en/controllerConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/controllerConfig.png
--------------------------------------------------------------------------------
/README.en/demo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/demo1.png
--------------------------------------------------------------------------------
/README.en/draggable_en.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/draggable_en.gif
--------------------------------------------------------------------------------
/README.en/expression.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/expression.gif
--------------------------------------------------------------------------------
/README.en/expressionV2V.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/expressionV2V.gif
--------------------------------------------------------------------------------
/README.en/helloWorldDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/helloWorldDemo.gif
--------------------------------------------------------------------------------
/README.en/language_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/language_demo.gif
--------------------------------------------------------------------------------
/README.en/language_demo_en.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/language_demo_en.gif
--------------------------------------------------------------------------------
/README.en/lifeDemo/lifeDemo_en.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/lifeDemo/lifeDemo_en.gif
--------------------------------------------------------------------------------
/README.en/lifeDemo/lifeDemo_pkg_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/lifeDemo/lifeDemo_pkg_en.png
--------------------------------------------------------------------------------
/README.en/lifeDemo/life_demo01_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/lifeDemo/life_demo01_en.png
--------------------------------------------------------------------------------
/README.en/lifeDemo/life_demo_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/lifeDemo/life_demo_en.png
--------------------------------------------------------------------------------
/README.en/log_demo_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/log_demo_en.png
--------------------------------------------------------------------------------
/README.en/modulesAction.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/modulesAction.gif
--------------------------------------------------------------------------------
/README.en/moveable.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/moveable.gif
--------------------------------------------------------------------------------
/README.en/mqDemo/20191208-194336-signalshow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/mqDemo/20191208-194336-signalshow.gif
--------------------------------------------------------------------------------
/README.en/redirectDemo/20191208-125511-not_close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/redirectDemo/20191208-125511-not_close.gif
--------------------------------------------------------------------------------
/README.en/redirectDemo/20191208-125739-close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/redirectDemo/20191208-125739-close.gif
--------------------------------------------------------------------------------
/README.en/redirect_with_data_en.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/redirect_with_data_en.gif
--------------------------------------------------------------------------------
/README.en/resizeAble.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/resizeAble.gif
--------------------------------------------------------------------------------
/README.en/template_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/template_en.png
--------------------------------------------------------------------------------
/README.en/template_incude_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/template_incude_en.png
--------------------------------------------------------------------------------
/README.en/wrap_JavaBean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README.en/wrap_JavaBean.png
--------------------------------------------------------------------------------
/README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_01.png
--------------------------------------------------------------------------------
/README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/JavaFX-Plus-LifeCycle/JavaFX-Plus-LifeCycle_02.png
--------------------------------------------------------------------------------
/README/JavaFX-Plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/JavaFX-Plus.png
--------------------------------------------------------------------------------
/README/JavaFX-Plus_en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/JavaFX-Plus_en.png
--------------------------------------------------------------------------------
/README/Resizable.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/Resizable.gif
--------------------------------------------------------------------------------
/README/actionDemo/20191210-175409-actionDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/actionDemo/20191210-175409-actionDemo.gif
--------------------------------------------------------------------------------
/README/bindhow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/bindhow.gif
--------------------------------------------------------------------------------
/README/controllerConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/controllerConfig.png
--------------------------------------------------------------------------------
/README/demo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/demo1.png
--------------------------------------------------------------------------------
/README/draggable.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/draggable.gif
--------------------------------------------------------------------------------
/README/expression.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/expression.gif
--------------------------------------------------------------------------------
/README/expressionV2V.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/expressionV2V.gif
--------------------------------------------------------------------------------
/README/helloWorldDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/helloWorldDemo.gif
--------------------------------------------------------------------------------
/README/image-20200407003220469.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/image-20200407003220469.png
--------------------------------------------------------------------------------
/README/language_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/language_demo.gif
--------------------------------------------------------------------------------
/README/lifeDemo/lifeDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/lifeDemo/lifeDemo.gif
--------------------------------------------------------------------------------
/README/lifeDemo/lifeDemo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/lifeDemo/lifeDemo.png
--------------------------------------------------------------------------------
/README/lifeDemo/lifeDemo_pkg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/lifeDemo/lifeDemo_pkg.png
--------------------------------------------------------------------------------
/README/lifeDemo/life_demo01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/lifeDemo/life_demo01.png
--------------------------------------------------------------------------------
/README/log_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/log_demo.png
--------------------------------------------------------------------------------
/README/modulesAction.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/modulesAction.gif
--------------------------------------------------------------------------------
/README/moveable.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/moveable.gif
--------------------------------------------------------------------------------
/README/mqDemo/20191208-194336-signalshow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/mqDemo/20191208-194336-signalshow.gif
--------------------------------------------------------------------------------
/README/redirectDemo/20191208-125511-not_close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/redirectDemo/20191208-125511-not_close.gif
--------------------------------------------------------------------------------
/README/redirectDemo/20191208-125739-close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/redirectDemo/20191208-125739-close.gif
--------------------------------------------------------------------------------
/README/redirect_with_data.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/redirect_with_data.gif
--------------------------------------------------------------------------------
/README/resizeAble.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/resizeAble.gif
--------------------------------------------------------------------------------
/README/template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/template.png
--------------------------------------------------------------------------------
/README/template_incude.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/template_incude.png
--------------------------------------------------------------------------------
/README/wrap_JavaBean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/README/wrap_JavaBean.png
--------------------------------------------------------------------------------
/doc/JavaFX-Plus-Introduction.xmind:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/doc/JavaFX-Plus-Introduction.xmind
--------------------------------------------------------------------------------
/doc/JavaFX-Plus-Introduction_en.xmind:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/doc/JavaFX-Plus-Introduction_en.xmind
--------------------------------------------------------------------------------
/doc/JavaFX-Plus-LifeCycle.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/doc/JavaFX-Plus-LifeCycle.pptx
--------------------------------------------------------------------------------
/doc/JavaFX-Plus-LifeCycle_en.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/doc/JavaFX-Plus-LifeCycle_en.pptx
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | javafx-plus
7 |
8 | com.gitee.Biubiuyuyu
9 | javafx-plus
10 | 1.2.0-RELEASE
11 | pom
12 |
13 |
14 |
15 | org.sonatype.oss
16 | oss-parent
17 | 7
18 |
19 |
20 | this is javafx framework that simplified coding
21 |
22 |
23 |
24 | javafx-plus
25 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
26 |
27 |
28 | javafx-plus
29 | https://oss.sonatype.org/content/repositories/snapshots
30 |
31 |
32 |
33 |
34 |
35 |
36 | cglib
37 | cglib
38 | 3.1
39 |
40 |
41 |
42 | junit
43 | junit
44 | 4.11
45 | test
46 |
47 |
48 |
49 |
50 | org.slf4j
51 | slf4j-log4j12
52 | 1.7.21
53 |
54 |
55 | org.apache.tomcat.embed
56 | tomcat-embed-core
57 | 9.0.35
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | org.apache.maven.plugins
66 | maven-compiler-plugin
67 |
68 | 1.8
69 | 1.8
70 |
71 |
72 | -Xlint:deprecation
73 |
74 |
75 |
76 |
77 |
79 | ${java.home}/lib/rt.jar:${java.home}/lib/jce.jar
80 |
81 |
82 |
83 |
84 | maven-assembly-plugin
85 |
86 |
87 | jar-with-dependencies
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | release
97 |
98 |
99 |
100 |
101 | org.apache.maven.plugins
102 | maven-source-plugin
103 | 2.2.1
104 |
105 |
106 | package
107 |
108 | jar-no-fork
109 |
110 |
111 |
112 |
113 |
114 |
115 | org.apache.maven.plugins
116 | maven-javadoc-plugin
117 | 2.9.1
118 |
119 |
120 | package
121 |
122 | jar
123 |
124 |
125 | -Xdoclint:none
126 |
127 |
128 |
129 |
130 |
131 |
132 | org.apache.maven.plugins
133 | maven-gpg-plugin
134 | 1.5
135 |
136 |
137 | sign-artifacts
138 | verify
139 |
140 | sign
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | GNU Lesser General Public License Version 3
153 | http://www.gnu.org/licenses/lgpl.txt
154 | repo
155 |
156 |
157 |
158 | master
159 | https://gitee.com/Biubiuyuyu/JavaFX-Plus.git
160 | scm:git:https://gitee.com/Biubiuyuyu/JavaFX-Plus.git
161 | scm:git:https://gitee.com/Biubiuyuyu/JavaFX-Plus.git
162 |
163 |
164 |
165 | Zhu zhanbiao
166 | 747441355@qq.com
167 | cn.edu.scau
168 |
169 |
170 |
171 | Yang suiyu
172 | 498870048@qq.com
173 | cn.edu.scau
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXBind.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @version 1.0
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Target(ElementType.FIELD)
11 | @Inherited
12 | public @interface FXBind {
13 | String[] value();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
4 |
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * This is use for marking A controller as FX-Plus Controller
9 | *
10 | * @author jack
11 | * @author suisui
12 | * @version 1.0
13 | * @date 2019/6/25 1:34
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target(ElementType.TYPE)
18 | @Inherited
19 | public @interface FXController {
20 | String path();
21 |
22 | double preWidth() default 0.0;
23 |
24 | double preHeight() default 0.0;
25 |
26 | /**
27 | * @return
28 | * @description 程序语言,默认不设置
29 | * @version 1.2
30 | */
31 | FXPlusLocale locale() default FXPlusLocale.NONE;
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXData.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author jack
7 | * @version 1.0
8 | * @date 2019/6/25 1:36
9 | * @since JavaFX2.0 JDK1.8
10 | */
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.FIELD)
13 | @Inherited
14 | public @interface FXData {
15 | String fx_id() default "";
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXEntity.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author jack
7 | * @version 1.0
8 | * @date 2019/6/25 1:35
9 | * @since JavaFX2.0 JDK1.8
10 | */
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.TYPE)
13 | @Inherited
14 | public @interface FXEntity {
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXField.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author jack
10 | * @version 1.0
11 | * @date 2019/6/27 20:10
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | @Retention(RetentionPolicy.RUNTIME)
15 | @Target(ElementType.FIELD)
16 | public @interface FXField {
17 | boolean readOnly() default false;
18 |
19 | String setter() default "";
20 |
21 | String add() default "";
22 |
23 | String delete() default "";
24 |
25 | String edit() default "";
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXReceiver.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author jack
7 | * @version 1.0
8 | * @date 2019/6/25 13:06
9 | * @since JavaFX2.0 JDK1.8
10 | */
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Inherited
13 | @Target(ElementType.METHOD)
14 | public @interface FXReceiver {
15 | String name();
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXRedirect.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author suisui
7 | * @version 1.1
8 | * @description 重定向的注解
9 | * @date 2019/12/3 12:53
10 | * @since JavaFX2.0 JDK1.8
11 | */
12 |
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Target(ElementType.METHOD)
15 | @Inherited
16 | public @interface FXRedirect {
17 | boolean close() default true;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXScan.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author jack
10 | * @date 2019/6/25 2:55
11 | * @since JavaFX2.0 JDK1.8
12 | */
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Target(ElementType.TYPE)
15 | public @interface FXScan {
16 | String[] base() default ".";
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXSender.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * This cn.edu.scau.biubiusuisui.annotation is used for a method which can send a signal to all consumer
10 | * And FXSender has a name which is used for identifying different method
11 | * It is legal to use same method which has same name because JavaFX-Plus will identify a method with its full class name
12 | * In addition ,name is optional , default name will be the class name and method name
13 | * you can use this cn.edu.scau.biubiusuisui.annotation as the following cn.edu.scau.biubiusuisui.example
14 | *
15 | * \@FXSender
16 | * public class A{
17 | * public void test(){
18 | *
19 | * }
20 | * }
21 | * name will be A.name(It will only contain base class name and this name)
22 | * or you can use
23 | *
24 | * @author jack
25 | * @version 1.0
26 | * @FXSernder("testDemo") public class A{
27 | * public void test(){
28 | *
29 | * }
30 | * }
31 | * name will be A.testDemo
32 | * @date 2019/6/25 13:02
33 | * @since JavaFX2.0 JDK1.8
34 | */
35 | @Retention(RetentionPolicy.RUNTIME)
36 | @Target(ElementType.METHOD)
37 | public @interface FXSender {
38 | String name() default "";
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * @author jack
7 | * @version 1.0
8 | * @date 2019/7/27 3:06
9 | * @since JavaFX2.0 JDK1.8
10 | */
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target(ElementType.PARAMETER)
13 | @Inherited
14 | public @interface FXValue {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/annotation/FXWindow.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.annotation;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
4 | import javafx.stage.StageStyle;
5 |
6 | import java.lang.annotation.*;
7 | import java.util.Locale;
8 |
9 | /**
10 | * @author jack
11 | * @author suisui
12 | * @version 1.0
13 | * @date 2019/6/25 1:36
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target(ElementType.TYPE)
18 | @Inherited
19 | public @interface FXWindow {
20 | double preWidth() default 0.0;
21 |
22 | double preHeight() default 0.0;
23 |
24 | double minWidth() default 0.0;
25 |
26 | double minHeight() default 0.0;
27 |
28 | boolean resizable() default false;
29 |
30 | boolean draggable() default false;
31 |
32 | boolean mainStage() default false;
33 |
34 | StageStyle style() default StageStyle.DECORATED;
35 |
36 | String title();
37 |
38 | /**
39 | * @description 图标URL
40 | * @version 1.2
41 | */
42 | String icon() default "";
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/config/FXPlusApplication.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.config;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
6 | import cn.edu.scau.biubiusuisui.factory.FXBuilder;
7 | import cn.edu.scau.biubiusuisui.factory.FXControllerFactory;
8 | import cn.edu.scau.biubiusuisui.function.FXWindowParser;
9 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
10 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
11 | import cn.edu.scau.biubiusuisui.utils.ClassUtil;
12 | import cn.edu.scau.biubiusuisui.utils.FileUtil;
13 | import cn.edu.scau.biubiusuisui.utils.LogUtil;
14 |
15 | import java.lang.annotation.Annotation;
16 | import java.util.HashSet;
17 | import java.util.List;
18 | import java.util.Set;
19 |
20 | /**
21 | * @author jack
22 | * @version 1.0
23 | * @date 2019/6/25 2:54
24 | * @since JavaFX2.0 JDK1.8
25 | */
26 | public class FXPlusApplication {
27 | private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXPlusApplication.class);
28 | // Application
29 |
30 | private static FXWindowParser windowAnnotationParser = new FXWindowParser();
31 |
32 | private static BeanBuilder DEFAULT_BEAN_FACTORY = new FXBuilder();
33 |
34 | private static BeanBuilder beanBuilder;
35 |
36 | public static boolean IS_SCENE_BUILDER = true;
37 |
38 | public static void start(Class clazz, BeanBuilder beanBuilder) {
39 | logger.info("starting JavaFX-Plus Application");
40 | logger.info("\n" + FileUtil.readFileFromResources("banner.txt"));
41 | // 初始化日志路径
42 | LogUtil.initLog4jBase();
43 |
44 | IS_SCENE_BUILDER = false;
45 | FXPlusApplication.beanBuilder = beanBuilder;
46 | Annotation[] annotations = clazz.getDeclaredAnnotations();
47 | logger.info("starting to scanning and registering controllers");
48 | for (Annotation annotation : annotations) {
49 | if (FXScan.class.equals(annotation.annotationType())) {
50 | String[] dirs = ((FXScan) annotation).base();
51 | Set sets = new HashSet<>();
52 | for (String dir : dirs) {
53 | sets.add(dir);
54 | }
55 | Set classNames = new HashSet<>();
56 | for (String dir : sets) {
57 | logger.info("scanning directory: " + dir);
58 | ClassUtil classUtil = new ClassUtil();
59 | List temps = classUtil.scanAllClassName(dir);
60 | for (String className : temps) {
61 | try {
62 | logger.info("loading class: " + className);
63 | loadFXPlusClass(className, beanBuilder);
64 | } catch (ClassNotFoundException e) {
65 | logger.error(e.getMessage());
66 | e.printStackTrace();
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
74 | public static void start(Class clazz) {
75 | start(clazz, DEFAULT_BEAN_FACTORY);
76 | }
77 |
78 | private static void loadFXPlusClass(String className, BeanBuilder beanBuilder) throws ClassNotFoundException {
79 | Class clazz = Class.forName(className);
80 | // 是窗口,需要初始化Stage
81 | if (clazz.getAnnotation(FXWindow.class) != null) {
82 | logger.info("loading stage of class: " + className);
83 | FXControllerFactory.loadStage(clazz, beanBuilder);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/entity/FXFieldWrapper.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.entity;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXField;
4 | import javafx.beans.property.Property;
5 |
6 | /**
7 | * 将Controller中的JavaFX的field包装成FXFieldWrapper
8 | *
9 | * @author jack
10 | * @version 1.0
11 | * @date 2019/6/28 10:03
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | public class FXFieldWrapper {
15 |
16 | private FXField fxField;
17 | private Class type;
18 |
19 | private Property property;
20 |
21 | public FXFieldWrapper() {
22 | }
23 |
24 | public FXFieldWrapper(FXField fxField, Class type) {
25 | this.fxField = fxField;
26 | this.type = type;
27 | }
28 |
29 | public Class getType() {
30 | return type;
31 | }
32 |
33 | public void setType(Class type) {
34 | this.type = type;
35 | }
36 |
37 | public FXField getFxField() {
38 | return fxField;
39 | }
40 |
41 | public void setFxField(FXField fxField) {
42 | this.fxField = fxField;
43 | }
44 |
45 | public Property getProperty() {
46 | return property;
47 | }
48 |
49 | public void setProperty(Property property) {
50 | this.property = property;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/entity/FXMethodEntity.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.entity;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | /**
6 | * This class is base cn.edu.scau.biubiusuisui.entity for queue message(or signal)
7 | * you mush save the instance and method which means who will run this method
8 | *
9 | * @author jack
10 | * @version 1.0
11 | * @date 2019/6/26 15:39
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | public class FXMethodEntity {
15 |
16 | private FXBaseController fxBaseController;
17 |
18 | private Method method;
19 |
20 | public FXMethodEntity(FXBaseController fxBaseController, Method method) {
21 | this.fxBaseController = fxBaseController;
22 | this.method = method;
23 | }
24 |
25 | public FXBaseController getFxBaseController() {
26 | return fxBaseController;
27 | }
28 |
29 | public void setFxBaseController(FXBaseController fxBaseController) {
30 | this.fxBaseController = fxBaseController;
31 | }
32 |
33 | public Method getMethod() {
34 | return method;
35 | }
36 |
37 | public void setMethod(Method method) {
38 | this.method = method;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/entity/FXPlusContext.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.entity;
2 |
3 | import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
4 | import javafx.beans.property.Property;
5 |
6 | import java.util.LinkedList;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.concurrent.ConcurrentHashMap;
10 |
11 | /**
12 | * Context is use for storing Controller
13 | * In addition,you can store an instance into Session to use it everywhere
14 | *
15 | * @author jack
16 | * @version 1.0
17 | * @date 2019/6/26 12:28
18 | * @since JavaFX2.0 JDK1.8
19 | */
20 | public class FXPlusContext {
21 |
22 | private FXPlusContext() {
23 | }
24 |
25 | private static Map> controllerContext = new ConcurrentHashMap<>(); //FXController控制器注册表
26 |
27 | private static Map beanMap = new ConcurrentHashMap<>(); // Object注册为FXEntityObject
28 |
29 |
30 | public static void registerController(FXBaseController fxBaseController) {
31 | List controllers = controllerContext.get(fxBaseController.getName());
32 | if (controllers == null) {
33 | controllers = new LinkedList<>();
34 | }
35 | controllers.add(fxBaseController);
36 | }
37 |
38 |
39 | public static FXEntityProxy getProxyByBeanObject(Object object) {
40 | return beanMap.get(object);
41 | }
42 |
43 | public static void setProxyByBeanObject(Object object, FXEntityProxy fxEntityProxy) {
44 | beanMap.put(object, fxEntityProxy);
45 | }
46 |
47 | public static List getControllers(String key) {
48 | return controllerContext.get(key);
49 | }
50 |
51 | public static Property getEntityPropertyByName(Object object, String fieldName) {
52 | return getProxyByBeanObject(object).getPropertyByFieldName(fieldName);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/entity/FXPlusLocale.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.entity;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description JavaFX的Locale枚举类型
7 | * @date 2020/5/3 10:47
8 | * @since JDK1.8 JavaFX2.0
9 | */
10 | public enum FXPlusLocale {
11 | /**
12 | * 不设置
13 | */
14 | NONE,
15 |
16 | /**
17 | * 简体中文
18 | */
19 | SIMPLIFIED_CHINESE,
20 |
21 | /**
22 | * 繁体中文
23 | */
24 | TRADITIONAL_CHINESE,
25 |
26 |
27 | /**
28 | * English 英语
29 | */
30 | ENGLISH,
31 |
32 |
33 | /**
34 | * American 美语
35 | */
36 | AMERICAN,
37 |
38 |
39 | /**
40 | * Le français 法语
41 | */
42 | FRANCE,
43 |
44 |
45 | /**
46 | * Deutsch 德语
47 | */
48 | GERMANY,
49 |
50 |
51 | /**
52 | * lingua italiana 意大利语
53 | */
54 | ITALIAN,
55 |
56 |
57 | /**
58 | * 日本人 日语
59 | */
60 | JAPANESE,
61 |
62 |
63 | /**
64 | * 한국어 韩语
65 | */
66 | KOREAN,
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/entity/FXRedirectParam.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.entity;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author suisui
8 | * @version 1.2
9 | * @description 跳转窗口携带的参数
10 | * @date 2020/4/6 18:06
11 | * @since JavaFX2.0 JDK1.8
12 | */
13 | public class FXRedirectParam {
14 | private String toController;
15 | private Map query = new HashMap<>();
16 | private Map params = new HashMap<>();
17 |
18 | public FXRedirectParam(String toController) {
19 | this.toController = toController;
20 | }
21 |
22 | public String getToController() {
23 | return toController;
24 | }
25 |
26 | public void setToController(String toController) {
27 | this.toController = toController;
28 | }
29 |
30 | public Map getParams() {
31 | return params;
32 | }
33 |
34 | public Map getQueryMap() {
35 | return query;
36 | }
37 |
38 |
39 | public void addParam(String key, Object param) {
40 | this.params.put(key, param);
41 | }
42 |
43 | public Object getParam(String key) {
44 | return this.params.get(key);
45 | }
46 |
47 | public void addQuery(String key, Object param) {
48 | this.query.put(key, param);
49 | }
50 |
51 | public Object getOneQuery(String key) {
52 | return this.query.get(key);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/bindDemo/BindDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.bindDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author jack
10 | * @author suisui
11 | * @version 1.2
12 | * @date 2020/5/1 1:43
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.bindDemo")
16 | public class BindDemo extends Application {
17 | @Override
18 | public void start(Stage primaryStage) throws Exception {
19 | FXPlusApplication.start(BindDemo.class);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/bindDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.bindDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXBind;
4 | import cn.edu.scau.biubiusuisui.annotation.FXController;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import javafx.beans.value.ChangeListener;
8 | import javafx.beans.value.ObservableValue;
9 | import javafx.fxml.FXML;
10 | import javafx.fxml.Initializable;
11 | import javafx.scene.control.*;
12 |
13 | import java.net.URL;
14 | import java.util.ResourceBundle;
15 |
16 | /**
17 | * @author jack
18 | * @author suisui
19 | * @version 1.2
20 | * @date 2020/5/1 1:43
21 | * @since JavaFX2.0 JDK1.8
22 | */
23 | @FXController(path = "fxml/bindDemo/bindDemo.fxml")
24 | @FXWindow(title = "bindDemo", mainStage = true)
25 | // TODO 待完善
26 | public class MainController extends FXBaseController implements Initializable {
27 | // View bind to View
28 | @FXML
29 | @FXBind("text=${inputTF.text}")
30 | private Label inputLabel;
31 |
32 | @FXML
33 | private TextField inputTF;
34 |
35 | // View bind to a Java Bean
36 | @FXML
37 | private Label usernameLabel;
38 |
39 | @FXML
40 | private Label userPswLabel;
41 |
42 | @FXML
43 | private Label ageLabel;
44 |
45 | @FXML
46 | private Label enableLabel;
47 |
48 | @FXML
49 | private TextField usernameTF;
50 |
51 | @FXML
52 | private PasswordField pswPF;
53 |
54 | @FXML
55 | private TextField ageTF;
56 |
57 | @FXML
58 | private ToggleGroup enableButtons;
59 |
60 | //
61 | // @FXData
62 | // @FXBind({
63 | // "name=${usernameTF.text}",
64 | // "password=${pswPF.text}",
65 | // "age=${ageTF.text}",
66 | // "isEnable=${enableButtons.getSelectedToggle().getUserData()}"
67 | // })
68 | // private User user = new User();
69 | private UserPropertyEntity user = new UserPropertyEntity();
70 |
71 | // View bind to Expression
72 | @FXML
73 | private TextField money;
74 |
75 | @FXML
76 | @FXBind("text=${@toUs(money.text)}")
77 | private Label us;
78 |
79 | @FXML
80 | @FXBind("text=${@toJp(money.text)}")
81 | private Label jp;
82 |
83 | @FXML
84 | @FXBind("text=${@toUk(money.text)}")
85 | private Label uk;
86 |
87 | @Override
88 | public void initialize(URL location, ResourceBundle resources) {
89 | money.setText("0");
90 | money.textProperty().addListener(new ChangeListener() {
91 | @Override
92 | public void changed(ObservableValue extends String> observable, String oldValue, String newValue) {
93 | if (null == newValue || "".equals(newValue)) {
94 | money.setText("0");
95 | } else if (!newValue.matches("^[0-9]*$")) {
96 | money.setText(oldValue);
97 | }
98 | }
99 | });
100 | }
101 |
102 | @FXML
103 | public void clickToShowInfo() {
104 | RadioButton button = (RadioButton) enableButtons.getSelectedToggle();
105 | System.out.println(button.getText());
106 | usernameLabel.setText(user.getName());
107 | userPswLabel.setText(user.getPassword());
108 | ageLabel.setText(Integer.toString(user.getAge()));
109 | enableLabel.setText(Boolean.toString(user.getEnable()));
110 | }
111 |
112 | public String toUs(String value) {
113 | double money = Double.valueOf(value);
114 | double percent = 0.1454;
115 | return String.valueOf(money * percent);
116 | }
117 |
118 | public String toJp(String value) {
119 | double money = Double.valueOf(value);
120 | double percent = 15.797;
121 | return String.valueOf(money * percent);
122 | }
123 |
124 | public String toUk(String value) {
125 | double money = Double.valueOf(value);
126 | double percent = 0.1174;
127 | return String.valueOf(money * percent);
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/bindDemo/Profile.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.bindDemo;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description 详细信息
7 | * @date 2020/4/6 00:29
8 | * @since JavaFX2.0 JDK1.8
9 | */
10 | public class Profile {
11 | private String birthday;
12 | private String address;
13 | private String avatar;
14 |
15 | public String getBirthday() {
16 | return birthday;
17 | }
18 |
19 | public void setBirthday(String birthday) {
20 | this.birthday = birthday;
21 | }
22 |
23 | public String getAddress() {
24 | return address;
25 | }
26 |
27 | public void setAddress(String address) {
28 | this.address = address;
29 | }
30 |
31 | public String getAvatar() {
32 | return avatar;
33 | }
34 |
35 | public void setAvatar(String avatar) {
36 | this.avatar = avatar;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/bindDemo/User.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.bindDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXEntity;
4 | import cn.edu.scau.biubiusuisui.annotation.FXField;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.2
11 | * @date 2020/4/5 12:19
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | @FXEntity
15 | public class User {
16 | @FXField
17 | private String name;
18 | @FXField
19 | private String password;
20 | @FXField
21 | private Integer age;
22 | @FXField
23 | private List scores;
24 | @FXField
25 | private Double gpa;//平均分
26 | @FXField
27 | private Profile profile;
28 | @FXField
29 | private boolean isEnable;
30 |
31 | public String getName() {
32 | return name;
33 | }
34 |
35 | public void setName(String name) {
36 | this.name = name;
37 | }
38 |
39 | public String getPassword() {
40 | return password;
41 | }
42 |
43 | public void setPassword(String password) {
44 | this.password = password;
45 | }
46 |
47 | public Integer getAge() {
48 | return age;
49 | }
50 |
51 | public void setAge(Integer age) {
52 | this.age = age;
53 | }
54 |
55 | public List getScores() {
56 | return scores;
57 | }
58 |
59 | public void addScore(double score) {
60 | this.scores.add(score);
61 | }
62 |
63 | public Profile getProfile() {
64 | return profile;
65 | }
66 |
67 | public void setProfile(Profile profile) {
68 | this.profile = profile;
69 | }
70 |
71 | public boolean isEnable() {
72 | return isEnable;
73 | }
74 |
75 | public void setEnable(boolean enable) {
76 | isEnable = enable;
77 | }
78 |
79 | public double getGpa() {
80 | double sum = 0;
81 | for (double score : scores) {
82 | sum += score;
83 | }
84 | gpa = sum / scores.size();
85 | return gpa;
86 | }
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/bindDemo/UserPropertyEntity.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.bindDemo;
2 |
3 | import javafx.beans.property.*;
4 | import javafx.collections.ObservableList;
5 |
6 | /**
7 | * @author suisui
8 | * @version 1.2
9 | * @description User的JavaFXBean
10 | * @date 2020/4/6 14:30
11 | * @since JavaFX2.0 JDK1.8
12 | */
13 | public class UserPropertyEntity {
14 | private SimpleStringProperty name;
15 | private SimpleStringProperty password;
16 | private SimpleIntegerProperty age;
17 | private SimpleListProperty scores;
18 | private SimpleDoubleProperty gpa;//平均分
19 | private SimpleObjectProperty profile;
20 | private SimpleBooleanProperty enable;
21 |
22 | public String getName() {
23 | return name.get();
24 | }
25 |
26 | public SimpleStringProperty nameProperty() {
27 | return name;
28 | }
29 |
30 | public void setName(String name) {
31 | this.name.set(name);
32 | }
33 |
34 | public String getPassword() {
35 | return password.get();
36 | }
37 |
38 | public SimpleStringProperty passwordProperty() {
39 | return password;
40 | }
41 |
42 | public void setPassword(String password) {
43 | this.password.set(password);
44 | }
45 |
46 | public int getAge() {
47 | return age.get();
48 | }
49 |
50 | public SimpleIntegerProperty ageProperty() {
51 | return age;
52 | }
53 |
54 | public void setAge(int age) {
55 | this.age.set(age);
56 | }
57 |
58 | public ObservableList getScores() {
59 | return scores.get();
60 | }
61 |
62 | public SimpleListProperty scoresProperty() {
63 | return scores;
64 | }
65 |
66 | public void setScores(ObservableList scores) {
67 | this.scores.set(scores);
68 | }
69 |
70 | public double getGpa() {
71 | return gpa.get();
72 | }
73 |
74 | public SimpleDoubleProperty gpaProperty() {
75 | return gpa;
76 | }
77 |
78 | public void setGpa(double gpa) {
79 | this.gpa.set(gpa);
80 | }
81 |
82 | public Profile getProfile() {
83 | return profile.get();
84 | }
85 |
86 | public SimpleObjectProperty profileProperty() {
87 | return profile;
88 | }
89 |
90 | public void setProfile(Profile profile) {
91 | this.profile.set(profile);
92 | }
93 |
94 | public boolean getEnable() {
95 | return enable.get();
96 | }
97 |
98 | public SimpleBooleanProperty enableProperty() {
99 | return enable;
100 | }
101 |
102 | public void setEnable(boolean enable) {
103 | this.enable.set(enable);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/firstDemo/FirstDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.firstDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author jack
10 | * @author suisui
11 | * @version 1.0
12 | * @description 第一个示例
13 | * @date 2020/1/1 23:06
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | @FXScan(base = {"cn.edu.scau.biubiusuisui.example.firstDemo"}) //会扫描带FXController和FXEntity的类进行初始化
17 | public class FirstDemo extends Application {
18 | @Override
19 | public void start(Stage primaryStage) throws Exception {
20 | FXPlusApplication.start(FirstDemo.class); //其他配置和JavaFX相同,这里要调用FXPlusAppcalition的start方法,开始FX-plus加强
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/firstDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.firstDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 | import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
7 | import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
8 | import javafx.beans.property.Property;
9 | import javafx.event.ActionEvent;
10 | import javafx.fxml.FXML;
11 | import javafx.fxml.Initializable;
12 | import javafx.scene.control.Button;
13 | import javafx.scene.control.ListView;
14 |
15 | import java.net.URL;
16 | import java.util.ResourceBundle;
17 |
18 | /**
19 | * @author jack
20 | * @author suisui
21 | * @version 1.0
22 | * @description 示例的主窗口
23 | * @date 2020/1/1 23:06
24 | * @since JavaFX2.0 JDK1.8
25 | */
26 | @FXController(path = "fxml/firstDemo/firstDemo.fxml")
27 | @FXWindow(title = "firstDemo", mainStage = true)
28 | public class MainController extends FXBaseController implements Initializable {
29 |
30 | @FXML
31 | private Button addHelloButton;
32 | @FXML
33 | private Button deleteHelloButton;
34 |
35 | @FXML
36 | private ListView list;
37 |
38 | private Student student;
39 |
40 | @FXML
41 | void addWord(ActionEvent event) {
42 | student.addList("hello");
43 | }
44 |
45 | @FXML
46 | void delWord(ActionEvent event) {
47 | student.delList("hello");
48 | }
49 |
50 | @Override
51 | public void initialize(URL location, ResourceBundle resources) {
52 | student = (Student) FXEntityFactory.wrapFXBean(Student.class); // 从工厂中拿到将JavaBean转换得到的JavaFXBean
53 | Property listProperty = FXPlusContext.getEntityPropertyByName(student, "list");
54 | list.itemsProperty().bind(listProperty);
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/firstDemo/Student.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.firstDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXEntity;
4 | import cn.edu.scau.biubiusuisui.annotation.FXField;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author suisui
11 | * @version 1.0
12 | * @description
13 | * @date 2020/1/1 23:07
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 |
17 | @FXEntity
18 | public class Student {
19 |
20 | @FXField //标记该属性是否被生成对应的Property
21 | private int age = 0;
22 |
23 | @FXField
24 | private List list = new ArrayList<>();
25 |
26 | public void addList(String word) {
27 | list.add(word);
28 | }
29 |
30 | public void delList(String word) {
31 | list.remove(word);
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/languageDemo/ChineseController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.languageDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
8 | import javafx.fxml.FXML;
9 |
10 |
11 | /**
12 | * @author suisui
13 | * @description 中文界面
14 | * @date 2020/5/3 16:23
15 | * @since JDK1.8
16 | */
17 | @FXWindow(mainStage = true, title = "languageDemo")
18 | @FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
19 | public class ChineseController extends FXBaseController {
20 | @FXML
21 | public void clickToChinese() {
22 | redirect("ChineseController");
23 | }
24 |
25 | @FXML
26 | public void clickToEnglish() {
27 | redirect("EnglishController");
28 | }
29 |
30 | @FXML
31 | public void clickToKorean() {
32 | redirect("KoreanController");
33 | }
34 |
35 | @FXRedirect
36 | public String redirect(String name) {
37 | return name;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/languageDemo/EnglishController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.languageDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
8 | import javafx.fxml.FXML;
9 |
10 | /**
11 | * @author suisui
12 | * @description 英文界面
13 | * @date 2020/5/3 19:54
14 | * @since JDK1.8
15 | */
16 | @FXWindow(mainStage = false, title = "languageDemo")
17 | @FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
18 | public class EnglishController extends FXBaseController {
19 | @FXML
20 | public void clickToChinese() {
21 | redirect("ChineseController");
22 | }
23 |
24 | @FXML
25 | public void clickToEnglish() {
26 | redirect("EnglishController");
27 | }
28 |
29 | @FXML
30 | public void clickToKorean() {
31 | redirect("KoreanController");
32 | }
33 |
34 | @FXRedirect
35 | public String redirect(String name) {
36 | return name;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/languageDemo/KoreanController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.languageDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
8 | import javafx.fxml.FXML;
9 |
10 | /**
11 | * @author suisui
12 | * @description 法语界面
13 | * @date 2020/5/4 14:01
14 | * @since JDK1.8
15 | */
16 | @FXWindow(mainStage = false, title = "languageDemo")
17 | @FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.KOREAN)
18 | public class KoreanController extends FXBaseController {
19 | @FXML
20 | public void clickToChinese() {
21 | redirect("ChineseController");
22 | }
23 |
24 | @FXML
25 | public void clickToEnglish() {
26 | redirect("EnglishController");
27 | }
28 |
29 | @FXML
30 | public void clickToKorean() {
31 | redirect("KoreanController");
32 | }
33 |
34 | @FXRedirect
35 | public String redirect(String name) {
36 | return name;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/languageDemo/LanguageDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.languageDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author suisui
10 | * @description 测试语言国际化的Demo
11 | * @date 2020/5/3 09:57
12 | * @since JDK1.8
13 | */
14 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.languageDemo")
15 | public class LanguageDemo extends Application {
16 | @Override
17 | public void start(Stage primaryStage) throws Exception {
18 | FXPlusApplication.start(getClass());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/lifeDemo/DialogController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.lifeDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
7 | import cn.edu.scau.biubiusuisui.log.FXPlusLogger;
8 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
9 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
10 |
11 | /**
12 | * @author suisui
13 | * @version 1.2
14 | * @description 弹窗
15 | * @date 2020/5/1 13:49
16 | * @since JavaFX2.0 JDK1.8
17 | */
18 | @FXWindow(title = "Dialog")
19 | @FXController(path = "fxml/lifeDemo/dialog.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
20 |
21 | public class DialogController extends FXBaseController {
22 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(DialogController.class);
23 |
24 | @Override
25 | public void initialize() throws Exception {
26 | logger.info("DialogController----initialize");
27 | }
28 |
29 | @Override
30 | public void onLoad() throws Exception {
31 | logger.info("DialogController----onLoad");
32 | }
33 |
34 | @Override
35 | public void onShow() throws Exception {
36 | logger.info("DialogController----onShow");
37 | }
38 |
39 | @Override
40 | public void onClose() throws Exception {
41 | logger.info("DialogController----onClose");
42 | }
43 |
44 | @Override
45 | public void onHide() throws Exception {
46 | logger.info("DialogController----onHide");
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/lifeDemo/LifeDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.lifeDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
6 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
7 | import cn.edu.scau.biubiusuisui.utils.LogUtil;
8 | import javafx.application.Application;
9 | import javafx.application.Platform;
10 | import javafx.stage.Stage;
11 |
12 |
13 | /**
14 | * @author suisui
15 | * @version 1.2
16 | * @description 测试生命周期的Demo
17 | * @date 2020/5/1 11:50
18 | * @since JavaFX2.0 JDK1.8
19 | */
20 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.lifeDemo")
21 | public class LifeDemo extends Application {
22 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LifeDemo.class);
23 |
24 | @Override
25 | public void start(Stage primaryStage) throws Exception {
26 | logger.info("LifeDemo---start");
27 | // Platform.setImplicitExit(false); //设置当关闭最后一个Stage时,JavaFX应用程序不会自动退出
28 | FXPlusApplication.start(getClass());
29 | }
30 |
31 | @Override
32 | public void init() throws Exception {
33 | logger.info("LifeDemo---init");
34 | }
35 |
36 | @Override
37 | public void stop() throws Exception {
38 | logger.info("LifeDemo---stop");
39 | }
40 |
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/lifeDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.lifeDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.annotation.FXController;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
8 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
9 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
10 | import javafx.fxml.FXML;
11 | import javafx.scene.input.Clipboard;
12 |
13 | /**
14 | * @author suisui
15 | * @version 1.2
16 | * @description 主窗口
17 | * @date 2020/5/1 11:53
18 | * @since JavaFX2.0 JDK1.8
19 | */
20 | @FXWindow(mainStage = true, title = "lifeDemo", icon = "image/icon.png")
21 | @FXController(path = "fxml/lifeDemo/lifeMain.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
22 | public class MainController extends FXBaseController {
23 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBaseController.class);
24 |
25 | @Override
26 | public void initialize() throws Exception {
27 | logger.info("MainController----initialize");
28 | }
29 |
30 | @Override
31 | public void onShow() throws Exception {
32 | logger.info("MainController----onShow");
33 | }
34 |
35 | @Override
36 | public void onLoad() throws Exception {
37 | logger.info("MainController----onLoad");
38 | }
39 |
40 | @Override
41 | public void onClose() throws Exception {
42 | logger.info("MainController----onClose");
43 | }
44 |
45 | @Override
46 | public void onHide() throws Exception {
47 | logger.info("MainController----onHide");
48 | }
49 |
50 | @FXML
51 | public void go() {
52 | redirectToDialog();
53 | }
54 |
55 | @FXML
56 | public void goAndClose() {
57 | redirectToDialogAndClose();
58 | }
59 |
60 | /**
61 | * 弹窗不关闭窗口
62 | */
63 | @FXRedirect(close = false)
64 | public String redirectToDialog() {
65 | return "DialogController";
66 | }
67 |
68 | /**
69 | * 弹窗并关闭本窗口
70 | */
71 | @FXRedirect()
72 | public String redirectToDialogAndClose() {
73 | return "DialogController";
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/lifeDemo/SubController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.lifeDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
5 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
6 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
7 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
8 |
9 | /**
10 | * @author suisui
11 | * @version 1.2
12 | * @description 子组件
13 | * @date 2020/5/1 13:48
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | @FXController(path = "fxml/lifeDemo/subBar.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
17 | public class SubController extends FXBaseController {
18 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(SubController.class);
19 |
20 | @Override
21 | public void initialize() throws Exception {
22 | logger.info("SubController----initialize");
23 | }
24 |
25 | @Override
26 | public void onShow() throws Exception {
27 | logger.info("SubController----onShow");
28 | }
29 |
30 | @Override
31 | public void onLoad() throws Exception {
32 | logger.info("SubController----onLoad");
33 | }
34 |
35 | @Override
36 | public void onClose() throws Exception {
37 | logger.info("SubController----onClose");
38 | }
39 |
40 | @Override
41 | public void onHide() throws Exception {
42 | logger.info("SubController----onHide");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/listDemo/ListDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.listDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author jack
10 | * @version 1.0
11 | * @date 2019/7/27 1:43
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.listDemo")
15 | public class ListDemo extends Application {
16 | @Override
17 | public void start(Stage primaryStage) throws Exception {
18 | FXPlusApplication.start(getClass());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/listDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.listDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXBind;
4 | import cn.edu.scau.biubiusuisui.annotation.FXController;
5 | import cn.edu.scau.biubiusuisui.annotation.FXData;
6 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
7 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
8 | import javafx.collections.FXCollections;
9 | import javafx.collections.ObservableList;
10 | import javafx.fxml.FXML;
11 | import javafx.scene.control.ListView;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * @author jack
17 | * @version 1.0
18 | * @date 2019/7/27 1:43
19 | * @since JavaFX2.0 JDK1.8
20 | */
21 | @FXController(path = "fxml/listDemo/listDemo.fxml")
22 | @FXWindow(title = "listDemo", mainStage = true)
23 | public class MainController extends FXBaseController {
24 |
25 | private static int count = 0;
26 |
27 | @FXData
28 | User user = new User();
29 |
30 | @FXML
31 | @FXBind("items=${@toList(user.names)}")
32 | private ListView userNameListView;
33 |
34 |
35 | @FXML
36 | public void addUserName() {
37 | user.addNames("Jack\t" + (count++));
38 | }
39 |
40 | public ObservableList toList(List list) {
41 | if (list == null) {
42 | return null;
43 | }
44 | return FXCollections.observableList(list);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/listDemo/User.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.listDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXEntity;
4 | import cn.edu.scau.biubiusuisui.annotation.FXField;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author jack
11 | * @version 1.0
12 | * @date 2019/7/27 12:19
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXEntity
16 | public class User {
17 | @FXField
18 | private String name;
19 |
20 | @FXField
21 | private String password;
22 |
23 | @FXField
24 | private List names = new ArrayList<>();
25 |
26 |
27 | public User() {
28 | // names.add("hello ");
29 | // names.add("test");
30 | }
31 |
32 |
33 | public void addNames(String name) {
34 | names.add(name);
35 | }
36 |
37 | public String getName() {
38 | return name;
39 | }
40 |
41 | public void setName(String name) {
42 | this.name = name;
43 | }
44 |
45 | public String getPassword() {
46 | return password;
47 | }
48 |
49 | public void setPassword(String password) {
50 | this.password = password;
51 | }
52 |
53 | public List getNames() {
54 | return names;
55 | }
56 |
57 | public void setNames(ArrayList names) {
58 | this.names = names;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/logDemo/LogDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.logDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.example.lifeDemo.LifeDemo;
4 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
5 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
6 | import cn.edu.scau.biubiusuisui.utils.LogUtil;
7 |
8 | /**
9 | * @author suisui
10 | * @description 测试日志的Demo
11 | * @date 2020/5/2 19:58
12 | * @since JDK1.8
13 | */
14 | public class LogDemo {
15 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(LogDemo.class);
16 |
17 | public void testLogger() {
18 | logger.info("info");
19 | logger.error("error");
20 | logger.debug("debug");
21 | logger.warn("warn");
22 | }
23 |
24 | public void testLogUtil() {
25 | LogUtil.info("info");
26 | LogUtil.error("error");
27 | LogUtil.debug("debug");
28 | LogUtil.warn("warn");
29 | }
30 |
31 | public static void main(String[] args) {
32 | LogDemo demo = new LogDemo();
33 | demo.testLogger();
34 | demo.testLogUtil();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/mqDemo/MQDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.mqDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.1
11 | * @description
12 | * @date 2019/12/8 13:17
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.mqDemo")
16 | public class MQDemo extends Application {
17 |
18 | @Override
19 | public void init() throws Exception {
20 | System.out.println("application init");
21 | }
22 |
23 | @Override
24 | public void start(Stage primaryStage) throws Exception {
25 | System.out.println("application start");
26 | FXPlusApplication.start(MQDemo.class);
27 | }
28 |
29 | @Override
30 | public void stop() throws Exception {
31 | System.out.println("application stop");
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/mqDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.mqDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXReceiver;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import javafx.fxml.FXML;
8 | import javafx.scene.control.TextArea;
9 |
10 | /**
11 | * @author suisui
12 | * @version 1.2
13 | * @description 主界面
14 | * @date 2019/12/8 13:17
15 | * @since JavaFX2.0 JDK1.8
16 | */
17 | @FXController(path = "fxml/mqDemo/main.fxml")
18 | @FXWindow(mainStage = true, title = "MQDemo")
19 | public class MainController extends FXBaseController {
20 |
21 | @FXML
22 | private TextArea outTA;
23 |
24 | /**
25 | * 接收者必须指定要订阅的[发送者类名:方法名]
26 | * 发送函数的返回值会注入到接收函数的参数中
27 | *
28 | * @param msg
29 | */
30 | @FXReceiver(name = "TopBarController:sendToMain")
31 | public void handleTopBar(String msg) {
32 | // 处理导航栏的点击事件
33 | outTA.appendText(msg + "\n");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/mqDemo/TopBarController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.mqDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXSender;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 | import javafx.fxml.FXML;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.1
11 | * @description 导航栏示例
12 | * @date 2019/12/8 13:17
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXController(path = "fxml/mqDemo/topBar.fxml")
16 | public class TopBarController extends FXBaseController {
17 |
18 | @FXML
19 | public void indexClick() {
20 | sendToMain("点击[首页]");
21 | }
22 |
23 | @FXML
24 | public void scoreClick() {
25 | sendToMain("点击[积分中心]");
26 | }
27 |
28 | @FXML
29 | public void questionClick() {
30 | sendToMain("点击[问答中心]");
31 | }
32 |
33 | @FXML
34 | public void selfClick() {
35 | sendToMain("点击[个人中心]");
36 | }
37 |
38 | /**
39 | * 系统会通过发射信号,调用所有订阅这个发射信号函数的方法,从而响应信号
40 | *
41 | * @param msg
42 | * @return
43 | */
44 | @FXSender //标注为信号发射函数
45 | public String sendToMain(String msg) {
46 | return msg;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/DialogController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 |
7 | /**
8 | * @author suisui
9 | * @version 1.1
10 | * @description
11 | * @date 2019/12/4 21:00
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | @FXController(path = "fxml/redirectDemo/dialog.fxml")
15 | @FXWindow(title = "弹窗")
16 | public class DialogController extends FXBaseController {
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/LoginController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXRedirectParam;
8 | import javafx.fxml.FXML;
9 | import javafx.scene.control.PasswordField;
10 | import javafx.scene.control.TextField;
11 |
12 | import java.util.Date;
13 |
14 | /**
15 | * @author suisui
16 | * @version 1.1
17 | * @description
18 | * @date 2019/12/3 11:53
19 | * @since JavaFX2.0 JDK1.8
20 | */
21 | @FXController(path = "fxml/redirectDemo/login.fxml")
22 | @FXWindow(title = "redirectDemo", mainStage = true)
23 | public class LoginController extends FXBaseController {
24 |
25 | @FXML
26 | private TextField usernameTF;
27 |
28 | @FXML
29 | private PasswordField passwordPF;
30 |
31 | @FXML
32 | public void registerClick() {
33 | redirectToRegister();
34 | }
35 |
36 | @FXRedirect
37 | public String redirectToRegister() {
38 | return "RegisterController";
39 | }
40 |
41 | @FXML
42 | @FXRedirect(close = false) //弹窗
43 | public String redirectToDialog() {
44 | return "DialogController";
45 | }
46 |
47 | @FXML
48 | @FXRedirect //登录成功 Query方式
49 | public String redirectToSuccessWithQuery() {
50 | return "SuccessController?showType=0&username=" + usernameTF.getText() + "&password=" + passwordPF.getText();
51 | }
52 |
53 | @FXML
54 | @FXRedirect //登录成功 Param方式
55 | public FXRedirectParam redirectToSuccessWithParam() {
56 | FXRedirectParam params = new FXRedirectParam("SuccessController");
57 | params.addParam("username", usernameTF.getText());
58 | params.addParam("password", passwordPF.getText());
59 | params.addQuery("showType", "0");
60 | return params;
61 | }
62 |
63 | @FXML
64 | @FXRedirect
65 | public FXRedirectParam redirectToSuccessWithAll() {
66 | FXRedirectParam params = new FXRedirectParam("SuccessController");
67 | params.addParam("username", usernameTF.getText());
68 | params.addParam("password", passwordPF.getText());
69 |
70 | params.addQuery("token", new Date().toString());
71 | params.addQuery("showType", "0");
72 | return params;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/RedirectDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.1
11 | * @description 测试重定向功能的Application
12 | * @date 2019/12/3 11:52
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.redirectDemo")
16 | public class RedirectDemo extends Application {
17 |
18 | @Override
19 | public void start(Stage primaryStage) throws Exception {
20 | FXPlusApplication.start(RedirectDemo.class);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/RegisterController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import cn.edu.scau.biubiusuisui.entity.FXRedirectParam;
8 | import javafx.fxml.FXML;
9 | import javafx.scene.control.Alert;
10 | import javafx.scene.control.PasswordField;
11 | import javafx.scene.control.TextField;
12 |
13 | /**
14 | * @author suisui
15 | * @version 1.1
16 | * @description
17 | * @date 2019/12/4 00:07
18 | * @since JavaFX2.0 JDK1.8
19 | */
20 | @FXController(path = "fxml/redirectDemo/register.fxml")
21 | @FXWindow(title = "register")
22 | public class RegisterController extends FXBaseController {
23 | @FXML
24 | private TextField usernameTF;
25 |
26 | @FXML
27 | private TextField emailTF;
28 |
29 | @FXML
30 | private PasswordField passwordPF;
31 |
32 | @FXML
33 | private PasswordField confirmPasswordPF;
34 |
35 | @FXML
36 | public void registerClick() {
37 | if (validate()) {
38 | UserEntity userEntity = new UserEntity();
39 | userEntity.setUsername(usernameTF.getText());
40 | userEntity.setPassword(passwordPF.getText());
41 | userEntity.setEmail(emailTF.getText());
42 | redirectToRegisterSuccess(userEntity);
43 | }
44 | }
45 |
46 | @FXML
47 | public void loginClick() {
48 | redirectToLogin();
49 | }
50 |
51 | @FXRedirect
52 | public String redirectToLogin() {
53 | return "LoginController";
54 | }
55 |
56 | @FXRedirect
57 | public FXRedirectParam redirectToRegisterSuccess(UserEntity userEntity) {
58 | FXRedirectParam fxRedirectParam = new FXRedirectParam("SuccessController");
59 | fxRedirectParam.addQuery("showType", "1");
60 | fxRedirectParam.addParam("user", userEntity);
61 | return fxRedirectParam;
62 | }
63 |
64 | // 校验
65 | private boolean validate() {
66 | boolean retCode = false;
67 | if (null != passwordPF.getText() && null != confirmPasswordPF.getText()) {
68 | if (!passwordPF.getText().equals(confirmPasswordPF.getText())) {
69 | retCode = false;
70 | new Alert(Alert.AlertType.ERROR, "两次密码不一致");
71 | } else {
72 | retCode = true;
73 | }
74 | } else if (null == usernameTF.getText()) {
75 | retCode = false;
76 | new Alert(Alert.AlertType.ERROR, "用户名不能为空");
77 | } else if (null == emailTF.getText()) {
78 | retCode = false;
79 | new Alert(Alert.AlertType.ERROR, "邮箱不能为空");
80 | }
81 | return retCode;
82 | }
83 |
84 | private void clearAllInput() {
85 | usernameTF.setText("");
86 | emailTF.setText("");
87 | passwordPF.setText("");
88 | confirmPasswordPF.setText("");
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/SuccessController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
5 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
6 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
7 | import javafx.fxml.FXML;
8 | import javafx.scene.control.Label;
9 |
10 | /**
11 | * @author suisui
12 | * @version 1.1
13 | * @description 登录成功的Controller
14 | * @date 2019/12/3 12:43
15 | * @since JavaFX2.0 JDK1.8
16 | */
17 | @FXController(path = "fxml/redirectDemo/success.fxml")
18 | @FXWindow(title = "success")
19 | public class SuccessController extends FXBaseController {
20 |
21 | @FXML
22 | private Label title;
23 |
24 | @FXML
25 | private Label usernameLabel;
26 |
27 | @FXML
28 | private Label passwordLabel;
29 |
30 | @FXML
31 | private Label tokenLabel;
32 |
33 | @FXML
34 | @FXRedirect
35 | public String redirectToLogin() {
36 | return "LoginController";
37 | }
38 |
39 | @Override
40 | public void onShow() {
41 | try {
42 | super.onShow();
43 | } catch (Exception e) {
44 | e.printStackTrace();
45 | }
46 | if (this.getQuery().get("showType") != null) {
47 | String showType = (String) this.getQuery().get("showType");
48 | if (showType.equals("1")) { //注册
49 | title.setText("注册成功");
50 | if (this.getParam().get("user") != null) {
51 | UserEntity userEntity = (UserEntity) this.getParam().get("user");
52 | usernameLabel.setText(userEntity.getUsername());
53 | passwordLabel.setText(userEntity.getPassword());
54 | }
55 | } else { //登录
56 | title.setText("登录成功");
57 | // 此处为演示多种方式数据传递才进行多次赋值,实际应用时应根据数据API进行相应的数据获取操作
58 | if (this.getQuery().size() > 1) { //query方式传递
59 | usernameLabel.setText(String.valueOf(this.getQuery().get("username")));
60 | passwordLabel.setText(String.valueOf(this.getQuery().get("password")));
61 | tokenLabel.setText(String.valueOf(this.getQuery().get("token")));
62 | }
63 | if (this.getParam().size() > 1) { //param方式传递
64 | usernameLabel.setText(String.valueOf(this.getParam().get("username")));
65 | passwordLabel.setText(String.valueOf(this.getParam().get("password")));
66 | }
67 | }
68 | }
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/redirectDemo/UserEntity.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.redirectDemo;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.1
6 | * @description 简单的用户实体
7 | * @date 2020/1/14 22:39
8 | * @since JavaFX2.0 JDK1.8
9 | */
10 | public class UserEntity {
11 | private String username;
12 | private String password;
13 | private String email;
14 |
15 |
16 | public String getUsername() {
17 | return username;
18 | }
19 |
20 | public void setUsername(String username) {
21 | this.username = username;
22 | }
23 |
24 | public String getPassword() {
25 | return password;
26 | }
27 |
28 | public void setPassword(String password) {
29 | this.password = password;
30 | }
31 |
32 | public String getEmail() {
33 | return email;
34 | }
35 |
36 | public void setEmail(String email) {
37 | this.email = email;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/resizableDemo/MainController.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.resizableDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXController;
4 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 | import javafx.fxml.FXML;
7 | import javafx.stage.StageStyle;
8 |
9 | /**
10 | * @author suisui
11 | * @version 1.2
12 | * @description 主控制器
13 | * @date 2020/4/5 00:05
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | @FXController(path = "fxml/resizableDemo/resizableDemo.fxml")
17 | @FXWindow(mainStage = true, title = "resizableDemo", draggable = true, resizable = true, style = StageStyle.UNDECORATED)
18 | public class MainController extends FXBaseController {
19 |
20 | @FXML
21 | public void closeWindowClick() {
22 | this.closeStage();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/example/resizableDemo/ResizableDemo.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.example.resizableDemo;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXScan;
4 | import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
5 | import javafx.application.Application;
6 | import javafx.stage.Stage;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.0
11 | * @description 缩放和拖拽的示例
12 | * @date 2020/4/5 00:04
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | @FXScan(base = "cn.edu.scau.biubiusuisui.example.resizableDemo")
16 | public class ResizableDemo extends Application {
17 | @Override
18 | public void start(Stage primaryStage) throws Exception {
19 | FXPlusApplication.start(ResizableDemo.class);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/exception/InvalidURLException.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.exception;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description 不合法URL
7 | * @date 2020/4/6 15:59
8 | * @since JavaFX2.0 JDK1.8
9 | */
10 | public class InvalidURLException extends Exception {
11 | public InvalidURLException() {
12 | super("the url is invalid");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/exception/NoSuchChangeMethod.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.exception;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/7/27 3:00
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | public class NoSuchChangeMethod extends Exception {
10 |
11 | public NoSuchChangeMethod() {
12 | super("No such change method");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/exception/NotFXWindowException.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.exception;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description 某Controller不是窗口的错误
7 | * @date 2020/4/6 17:10
8 | * @since JavaFX2.0 JDK1.8
9 | */
10 | public class NotFXWindowException extends Exception {
11 | public NotFXWindowException() {
12 | super("the controller is not a window");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/exception/ProtocolNotSupport.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.exception;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/6/25 7:23
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | public class ProtocolNotSupport extends Exception {
10 | public ProtocolNotSupport() {
11 | super("protocolNotSupport");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/BindParser.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/7/27 2:02
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | public interface BindParser {
10 | public void parse(Object target, String expression);
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/action/ChangeParser.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.action;
2 |
3 | import cn.edu.scau.biubiusuisui.expression.BindParser;
4 |
5 | /**
6 | * @author jack
7 | * @version 1.0
8 | * @date 2019/7/27 2:03
9 | * @since JavaFX2.0 JDK1.8
10 | */
11 | public class ChangeParser implements BindParser {
12 |
13 | @Override
14 | public void parse(Object target, String expression) {
15 |
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/data/ExpFunction.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/7/27 20:03
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | @FunctionalInterface
10 | public interface ExpFunction {
11 | R apply(T t, U u);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/data/ExpressionParser.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 |
4 | import cn.edu.scau.biubiusuisui.annotation.FXValue;
5 | import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
6 | import com.sun.istack.internal.NotNull;
7 | import com.sun.javafx.fxml.expression.Expression;
8 | import javafx.beans.property.Property;
9 |
10 | import java.lang.reflect.InvocationTargetException;
11 | import java.lang.reflect.Method;
12 | import java.lang.reflect.Parameter;
13 |
14 | /**
15 | * 将FXBind中表达式建立绑定
16 | * 格式如下
17 | * 语法如下:
18 | * FXBind("S")
19 | * S -> left=right
20 | * left -> property
21 | * right -> ${expression}
22 | * expression -> bean.field
23 | *
24 | * FXBind("text=${bean.field})
25 | * textProperty 通过 adapter.getModelProperty --> textProperty实例
26 | * bean 通过namespace 获取,因为bean有FXEntity标签,所以返回包装过后的bean的property
27 | * 最后
28 | * left.bind(right)
29 | *
30 | * @author jack
31 | * @version 1.0
32 | * @date 2019/7/23 15:05
33 | * @since JavaFX2.0 JDK1.8
34 | */
35 | public class ExpressionParser {
36 |
37 | private Object namespace;
38 | private Object targetController;
39 | private static final String BIND_PREFIX = "${";
40 | private static final String BIND_SUFIX = "}";
41 | private static final String PROEPRTY = "Property";
42 |
43 | public enum ExpressionType {
44 | DataExpression,
45 | ActionExpression
46 | }
47 |
48 | public ExpressionParser(Object namespace, Object targetController) {
49 | this.namespace = namespace;
50 | this.targetController = targetController;
51 | }
52 |
53 | public ExpressionParser(Object namespace) {
54 | this.namespace = namespace;
55 | }
56 |
57 | private Property getLeftProperty(MyBeanAdapter myBeanAdapter, String key) {
58 | return (Property) myBeanAdapter.getPropertyModel(key);
59 | }
60 |
61 | private static final String FUNCTION_PREFIX = "@";
62 |
63 | private MyExpressionValue getRightExpression(MyBeanAdapter myBeanAdapter, String key, String rightExpression) {
64 | Expression expression = null;
65 | if (rightExpression.startsWith(FUNCTION_PREFIX)) {
66 | expression = getFunctionExpression(rightExpression);
67 | } else {
68 | expression = Expression.valueOf(rightExpression);
69 | }
70 | Class clazz = myBeanAdapter.getType(key);
71 | MyExpressionValue myExpressionValue = new MyExpressionValue(namespace, expression, clazz);
72 | return myExpressionValue;
73 | }
74 |
75 | private Expression getFunctionExpression(String rightExpression) {
76 | Expression expression = null;
77 | int indexLeft = rightExpression.indexOf("(");
78 | String methodName = rightExpression.substring(1, indexLeft);
79 | int indexRight = rightExpression.indexOf(")");
80 | String argString = rightExpression.substring(indexLeft + 1, indexRight);
81 | String[] args = null;
82 | if (!"".equals(argString.trim())) {
83 | args = argString.split(",");
84 | }
85 | Class targetClazz = targetController.getClass();
86 | Method[] methods = targetClazz.getMethods();
87 | Expression[] expressionArgs = null;
88 | if (args != null) {
89 | expressionArgs = new Expression[args.length];
90 | for (int i = 0; i < args.length; i++) {
91 | if (!"".equals(args[i].trim())) {
92 | expressionArgs[i] = Expression.valueOf(args[i]);
93 | }
94 | }
95 | }
96 | for (Method method : methods) {
97 | if (method.getName().equals(methodName)) {
98 | expression = new FunctionExpression(method, targetController, expressionArgs);
99 | }
100 | }
101 | return expression;
102 | }
103 |
104 | public void parse(Object object, @NotNull String expression) throws NoSuchChangeMethod {
105 | //check expression
106 | int index = expression.indexOf("=");
107 | if (index == -1) {
108 | return;
109 | }
110 | String[] items = expression.split("=");
111 | if (items.length != 2) {
112 | return;
113 | }
114 | String left = items[0];
115 | String right = items[1];
116 | if (left == null || right == null) {
117 | return;
118 | }
119 | right = right.trim();
120 | ExpressionType expressionType;
121 | if (right.startsWith(BIND_PREFIX) && right.endsWith(BIND_SUFIX)) {
122 | int length = right.length();
123 | right = right.substring(2, length - 1); //已经去掉“${”的表达式
124 | expressionType = ExpressionType.DataExpression;
125 | } else {
126 | right = right.substring(1); //#changeMethod -> changeMethod
127 | expressionType = ExpressionType.ActionExpression;
128 | }
129 | MyBeanAdapter myBeanAdapter = new MyBeanAdapter(object);
130 | Property leftProperty = getLeftProperty(myBeanAdapter, left);
131 | switch (expressionType) {
132 | case DataExpression:
133 | bindDataExpression(left, right, myBeanAdapter, leftProperty);
134 | break;
135 | case ActionExpression:
136 | bindActionExpression(right, leftProperty);
137 | }
138 | }
139 |
140 | /**
141 | * @param right
142 | * @param leftProperty
143 | * @throws NoSuchChangeMethod
144 | * @Description 鼠标事件或键盘事件绑定
145 | */
146 | private void bindActionExpression(String right, Property leftProperty) throws NoSuchChangeMethod {
147 | Class clazz = targetController.getClass();
148 | Method[] methods = clazz.getMethods();
149 | for (Method method : methods) {
150 | if (method.getName().equals(right)) {
151 | leftProperty.addListener((observable, oldValue, newValue) -> {
152 | try {
153 | Object[] objects = getArgs(method, observable, newValue, oldValue);
154 | method.invoke(targetController, objects);
155 | } catch (IllegalAccessException e) {
156 | e.printStackTrace();
157 | } catch (InvocationTargetException e) {
158 | e.printStackTrace();
159 | }
160 | });
161 | }
162 | }
163 | }
164 |
165 | /**
166 | * @param left
167 | * @param right
168 | * @param myBeanAdapter
169 | * @param leftProperty
170 | * @Description 数据绑定
171 | */
172 | private void bindDataExpression(String left, String right, MyBeanAdapter myBeanAdapter, Property leftProperty) {
173 | MyExpressionValue rightProperty = getRightExpression(myBeanAdapter, left, right);
174 | leftProperty.bind(rightProperty);
175 | }
176 |
177 | public Object[] getArgs(Method method, Object... args) {
178 | Parameter[] parameters = method.getParameters();
179 | Object[] objects = new Object[parameters.length];
180 | for (int i = 0; i < parameters.length; i++) {
181 | FXValue annotation = parameters[i].getAnnotation(FXValue.class);
182 | switch (annotation.value()) {
183 | case "target":
184 | objects[i] = args[0];
185 | break;
186 | case "newValue":
187 | objects[i] = args[1];
188 | break;
189 | case "oldValue":
190 | objects[i] = args[2];
191 | break;
192 | }
193 | }
194 | return objects;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/data/FunctionExpression.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 | import com.sun.javafx.fxml.expression.Expression;
4 | import com.sun.javafx.fxml.expression.KeyPath;
5 |
6 | import java.lang.reflect.InvocationTargetException;
7 | import java.lang.reflect.Method;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * @author jack
13 | * @version 1.0
14 | * @date 2019/7/27 20:00
15 | * @since JavaFX2.0 JDK1.8
16 | */
17 | public class FunctionExpression extends Expression {
18 |
19 | private Method method;
20 | private Object target;
21 | private Expression[] args;
22 |
23 | public FunctionExpression(Method method, Object target, Expression[] expressions) {
24 | this.method = method;
25 | this.target = target;
26 | this.args = expressions;
27 | }
28 |
29 | @Override
30 | public List getArguments() {
31 | List list = new ArrayList<>();
32 | if (args != null) {
33 | for (Expression expression : args) {
34 | list.addAll(expression.getArguments());
35 | }
36 | }
37 | return list;
38 | }
39 |
40 | @Override
41 | public Object evaluate(Object namespace) {
42 | Object result = null;
43 | if (args != null) {
44 | Object[] values = new Object[args.length];
45 | for (int i = 0; i < args.length; i++) {
46 | values[i] = args[i].evaluate(namespace);
47 | }
48 | try {
49 | result = method.invoke(target, values);
50 | } catch (IllegalAccessException e) {
51 | e.printStackTrace();
52 | } catch (InvocationTargetException e) {
53 | e.printStackTrace();
54 | }
55 | return result;
56 | } else {
57 | try {
58 | result = method.invoke(target);
59 | } catch (IllegalAccessException e) {
60 | e.printStackTrace();
61 | } catch (InvocationTargetException e) {
62 | e.printStackTrace();
63 | }
64 | }
65 | return result;
66 | }
67 |
68 | @Override
69 | public void update(Object namespace, Object value) {
70 |
71 | }
72 |
73 | @Override
74 | public boolean isDefined(Object namespace) {
75 | return false;
76 | }
77 |
78 | @Override
79 | public boolean isLValue() {
80 | return false;
81 | }
82 |
83 | @Override
84 | protected void getArguments(List arguments) {
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/data/MyBeanAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXEntity;
4 | import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
5 | import cn.edu.scau.biubiusuisui.utils.BeanUtil;
6 | import com.sun.javafx.fxml.BeanAdapter;
7 | import javafx.beans.value.ObservableValue;
8 |
9 | /**
10 | * @author jack
11 | * @version 1.0
12 | * @date 2019/7/23 15:16
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | public class MyBeanAdapter extends BeanAdapter {
16 |
17 | private Object object;
18 |
19 | /**
20 | * Creates a new Bean adapter.
21 | *
22 | * @param bean The Bean object to wrap.
23 | */
24 | public MyBeanAdapter(Object bean) {
25 | super(bean);
26 | this.object = bean;
27 | }
28 |
29 | @Override
30 | public ObservableValue getPropertyModel(String key) {
31 | if (object.getClass().getAnnotation(FXEntity.class) == null) {
32 | return super.getPropertyModel(key);
33 | } else {
34 | return BeanUtil.getPropertyByName(object, key);
35 | }
36 | }
37 |
38 | public String valueOf(String value) {
39 | return value;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/expression/data/MyExpressionValue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 | import com.sun.javafx.fxml.BeanAdapter;
4 | import com.sun.javafx.fxml.expression.Expression;
5 | import com.sun.javafx.fxml.expression.KeyPath;
6 | import javafx.beans.InvalidationListener;
7 | import javafx.beans.value.ChangeListener;
8 | import javafx.beans.value.ObservableValue;
9 | import javafx.beans.value.ObservableValueBase;
10 | import javafx.collections.ListChangeListener;
11 | import javafx.collections.MapChangeListener;
12 | import javafx.collections.ObservableList;
13 | import javafx.collections.ObservableMap;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Iterator;
17 | import java.util.List;
18 |
19 | /**
20 | * @author jack
21 | * @version 1.0
22 | * @since JavaFX2.0 JDK1.8
23 | */
24 | public class MyExpressionValue extends ObservableValueBase {
25 |
26 | // Monitors a namespace for changes along a key path
27 | private class KeyPathMonitor {
28 | private String key;
29 | private KeyPathMonitor next;
30 |
31 | private Object namespace = null;
32 |
33 | private ListChangeListener listChangeListener = new ListChangeListener() {
34 | @Override
35 | public void onChanged(Change extends Object> change) {
36 | while (change.next()) {
37 | int index = Integer.parseInt(key);
38 |
39 | if (index >= change.getFrom() && index < change.getTo()) {
40 | fireValueChangedEvent();
41 | remonitor();
42 | }
43 | }
44 | }
45 | };
46 |
47 | private MapChangeListener mapChangeListener = new MapChangeListener() {
48 | @Override
49 | public void onChanged(Change extends String, ? extends Object> change) {
50 | if (key.equals(change.getKey())) {
51 | fireValueChangedEvent();
52 | remonitor();
53 | }
54 | }
55 | };
56 |
57 | private ChangeListener propertyChangeListener = new ChangeListener() {
58 | @Override
59 | public void changed(ObservableValue extends Object> observable, Object oldValue, Object newValue) {
60 | fireValueChangedEvent();
61 | remonitor();
62 | }
63 | };
64 |
65 | public KeyPathMonitor(Iterator keyPathIterator) {
66 | this.key = keyPathIterator.next();
67 |
68 | if (keyPathIterator.hasNext()) {
69 | next = new KeyPathMonitor(keyPathIterator);
70 | } else {
71 | next = null;
72 | }
73 | }
74 |
75 | @SuppressWarnings("unchecked")
76 | public void monitor(Object namespace) {
77 | if (namespace instanceof ObservableList>) {
78 | ((ObservableList) namespace).addListener(listChangeListener);
79 | } else if (namespace instanceof ObservableMap, ?>) {
80 | ((ObservableMap) namespace).addListener(mapChangeListener);
81 | } else {
82 |
83 | MyBeanAdapter namespaceAdapter = new MyBeanAdapter(namespace);
84 | ObservableValue propertyModel = namespaceAdapter.getPropertyModel(key);
85 |
86 | if (propertyModel != null) {
87 | propertyModel.addListener(propertyChangeListener);
88 | }
89 |
90 | namespace = namespaceAdapter;
91 | }
92 |
93 | this.namespace = namespace;
94 |
95 | if (next != null) {
96 | Object value = Expression.get(namespace, key);
97 | if (value != null) {
98 | next.monitor(value);
99 | }
100 | }
101 | }
102 |
103 | @SuppressWarnings("unchecked")
104 | public void unmonitor() {
105 | if (namespace instanceof ObservableList>) {
106 | ((ObservableList) namespace).removeListener(listChangeListener);
107 | } else if (namespace instanceof ObservableMap, ?>) {
108 | ((ObservableMap) namespace).removeListener(mapChangeListener);
109 | } else if (namespace != null) {
110 | MyBeanAdapter namespaceAdapter = (MyBeanAdapter) namespace;
111 | ObservableValue propertyModel = namespaceAdapter.getPropertyModel(key);
112 |
113 | if (propertyModel != null) {
114 | propertyModel.removeListener(propertyChangeListener);
115 | }
116 | }
117 |
118 | namespace = null;
119 |
120 | if (next != null) {
121 | next.unmonitor();
122 | }
123 | }
124 |
125 | public void remonitor() {
126 | if (next != null) {
127 | next.unmonitor();
128 | Object value = Expression.get(namespace, key);
129 | if (value != null) {
130 | next.monitor(value);
131 | }
132 | }
133 | }
134 | }
135 |
136 | private Object namespace;
137 | private Expression expression;
138 | private Class> type;
139 |
140 | private ArrayList argumentMonitors;
141 |
142 | private int listenerCount = 0;
143 |
144 | public MyExpressionValue(Object namespace, Expression expression, Class> type) {
145 | if (namespace == null) {
146 | throw new NullPointerException();
147 | }
148 |
149 | if (expression == null) {
150 | throw new NullPointerException();
151 | }
152 |
153 | if (type == null) {
154 | throw new NullPointerException();
155 | }
156 |
157 | this.namespace = namespace;
158 | this.expression = expression;
159 | this.type = type;
160 |
161 | List arguments = expression.getArguments();
162 | argumentMonitors = new ArrayList(arguments.size());
163 |
164 | for (KeyPath argument : arguments) {
165 | argumentMonitors.add(new KeyPathMonitor(argument.iterator()));
166 | }
167 | }
168 |
169 | @Override
170 | public Object getValue() {
171 | return BeanAdapter.coerce(expression.evaluate(namespace), type);
172 | }
173 |
174 | @Override
175 | public void addListener(InvalidationListener listener) {
176 | if (listenerCount == 0) {
177 | monitorArguments();
178 | }
179 |
180 | super.addListener(listener);
181 | listenerCount++;
182 | }
183 |
184 | @Override
185 | public void removeListener(InvalidationListener listener) {
186 | super.removeListener(listener);
187 | listenerCount--;
188 |
189 | if (listenerCount == 0) {
190 | unmonitorArguments();
191 | }
192 | }
193 |
194 | @Override
195 | public void addListener(ChangeListener super Object> listener) {
196 | if (listenerCount == 0) {
197 | monitorArguments();
198 | }
199 |
200 | super.addListener(listener);
201 | listenerCount++;
202 | }
203 |
204 | @Override
205 | public void removeListener(ChangeListener super Object> listener) {
206 | super.removeListener(listener);
207 | listenerCount--;
208 |
209 | if (listenerCount == 0) {
210 | unmonitorArguments();
211 | }
212 | }
213 |
214 | private void monitorArguments() {
215 | for (KeyPathMonitor argumentMonitor : argumentMonitors) {
216 | argumentMonitor.monitor(namespace);
217 | }
218 | }
219 |
220 | private void unmonitorArguments() {
221 | for (KeyPathMonitor argumentMonitor : argumentMonitors) {
222 | argumentMonitor.unmonitor();
223 | }
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/factory/BeanBuilder.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.factory;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/7/4 11:16
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | public interface BeanBuilder {
10 | /**
11 | * 万能工厂方法
12 | *
13 | * @param type 类型
14 | * @return 实例对象
15 | */
16 | Object getBean(Class type);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/factory/FXBuilder.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.factory;
2 |
3 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
4 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
5 |
6 | /**
7 | * @author jack
8 | * @version 1.0
9 | * @date 2019/7/4 11:13
10 | * @since JavaFX2.0 JDK1.8
11 | */
12 | public class FXBuilder implements BeanBuilder {
13 | private IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBuilder.class);
14 |
15 | @Override
16 | public Object getBean(Class type) {
17 | Object object = null;
18 | try {
19 | object = type.newInstance();
20 | } catch (InstantiationException e) {
21 | logger.error(e.getMessage());
22 | e.printStackTrace();
23 | } catch (IllegalAccessException e) {
24 | logger.error(e.getMessage());
25 | e.printStackTrace();
26 | }
27 | return object;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/factory/FXEntityFactory.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.factory;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXField;
4 | import cn.edu.scau.biubiusuisui.entity.FXFieldWrapper;
5 | import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
6 | import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
7 | import cn.edu.scau.biubiusuisui.utils.ClassUtil;
8 | import javafx.beans.property.*;
9 | import javafx.collections.FXCollections;
10 |
11 | import java.lang.annotation.Annotation;
12 | import java.lang.reflect.Field;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | /**
18 | * @author jack
19 | * @version 1.0
20 | * @date 2019/6/28 1:12
21 | * @since JavaFX2.0 JDK1.8
22 | */
23 | public class FXEntityFactory {
24 |
25 | private FXEntityFactory() {
26 | }
27 |
28 | public static Object wrapFXBean(Class clazz) {
29 | return wrapFXBean(clazz, new FXBuilder());
30 | }
31 |
32 | public static Object wrapFXBean(Class clazz, BeanBuilder beanBuilder) {
33 | Object object = null;
34 | object = beanBuilder.getBean(clazz);
35 | if (object != null) {
36 | return wrapFXBean(object);
37 | } else {
38 | return null;
39 | }
40 | }
41 |
42 | /**
43 | * @param object 被转换的对象
44 | * @return
45 | */
46 | public static Object wrapFXBean(Object object) {
47 | FXEntityProxy fxEntityProxy = new FXEntityProxy();
48 | Object proxyObject = null;
49 | try {
50 | proxyObject = fxEntityProxy.getInstance(object); // 初始化代理类
51 | processFXEntityProxyFields(object, proxyObject, fxEntityProxy); //处理FXEntity上的@FXField
52 | FXPlusContext.setProxyByBeanObject(proxyObject, fxEntityProxy);
53 | } catch (IllegalAccessException e) {
54 | e.printStackTrace();
55 | }
56 | return proxyObject;
57 | }
58 |
59 | /**
60 | * @param entityObject 被转换的原Entity对象
61 | * @param proxyObject 被转换对象的FXEntityProxy对象
62 | * @param fxEntityProxy 被转换对象的FXEntityProxy类
63 | * @throws IllegalAccessException
64 | * @Description 处理FXEntity中的FXField注解,1. 添加监听 2.赋值FXEntityProxy中的fxFieldWrapperMap
65 | */
66 | private static void processFXEntityProxyFields(Object entityObject, Object proxyObject, FXEntityProxy fxEntityProxy) throws IllegalAccessException {
67 | Map fxFieldWrapperMap = new HashMap<>();
68 | Field[] fields = entityObject.getClass().getDeclaredFields();
69 | for (Field field : fields) {
70 | Annotation annotation = ClassUtil.getAnnotationInList(FXField.class, field.getDeclaredAnnotations());
71 | if (annotation != null) {
72 | Property property = null;
73 | field.setAccessible(true);
74 | FXField fxField = (FXField) annotation;
75 | FXFieldWrapper fieldWrapper = new FXFieldWrapper(fxField, field.getType());
76 | if (field.get(entityObject) == null) { //没有初始值
77 | property = getFieldDefaultProperty(field);
78 | } else { //有初始值
79 | property = getFieldProperty(entityObject, field);
80 | }
81 | if (property != null) {
82 | // 监听
83 | property.addListener((object, oldVal, newVal) -> {
84 | if (!fxField.readOnly()) {
85 | // 判断field.getType()是否为List类型
86 | if (!List.class.isAssignableFrom(field.getType())) {
87 | try {
88 | field.set(proxyObject, newVal);//赋值
89 | } catch (IllegalAccessException e) {
90 | e.printStackTrace();
91 | }
92 | }
93 | }
94 | });
95 | }
96 | // 设置属性
97 | fieldWrapper.setProperty(property);
98 | fxFieldWrapperMap.put(field.getName(), fieldWrapper);
99 | }
100 | }
101 | fxEntityProxy.setFXFieldWrapperMap(fxFieldWrapperMap);
102 | }
103 |
104 | /**
105 | * @param entityObject
106 | * @param field
107 | * @return
108 | * @throws IllegalAccessException
109 | * @Description 某一属性中有初始值时
110 | */
111 | private static Property getFieldProperty(Object entityObject, Field field) throws IllegalAccessException {
112 | Class type = field.getType();
113 | Object value = field.get(entityObject);
114 | Property property = null;
115 |
116 | if (Boolean.class.equals(type) || boolean.class.equals(type)) {
117 | property = new SimpleBooleanProperty((Boolean) value);
118 | } else if (Double.class.equals(type) || double.class.equals(type)) {
119 | property = new SimpleDoubleProperty((Double) value);
120 | } else if (Float.class.equals(type) || float.class.equals(type)) {
121 | property = new SimpleFloatProperty((Float) value);
122 | } else if (Integer.class.equals(type) || int.class.equals(type)) {
123 | property = new SimpleIntegerProperty((Integer) value);
124 | } else if (Long.class.equals(type) || long.class.equals(type)) {
125 | property = new SimpleLongProperty((Long) value);
126 | } else if (String.class.equals(type)) {
127 | property = new SimpleStringProperty((String) value);
128 | } else if (List.class.isAssignableFrom(type)) {
129 | property = new SimpleListProperty(FXCollections.observableList((List) value));
130 | } else if (Object.class.isAssignableFrom(type)) {
131 | property = new SimpleObjectProperty(value);
132 | }
133 | return property;
134 | }
135 |
136 | /**
137 | * @param field
138 | * @return
139 | * @throws IllegalAccessException
140 | * @Description 某一属性中无初始值
141 | */
142 | private static Property getFieldDefaultProperty(Field field) throws IllegalAccessException {
143 | Class type = field.getType();
144 | Property property = null;
145 |
146 | if (Boolean.class.equals(type) || boolean.class.equals(type)) {
147 | property = new SimpleBooleanProperty();
148 | } else if (Double.class.equals(type) || double.class.equals(type)) {
149 | property = new SimpleDoubleProperty();
150 | } else if (Float.class.equals(type) || float.class.equals(type)) {
151 | property = new SimpleFloatProperty();
152 | } else if (Integer.class.equals(type) || int.class.equals(type)) {
153 | property = new SimpleIntegerProperty();
154 | } else if (Long.class.equals(type) || long.class.equals(type)) {
155 | property = new SimpleLongProperty();
156 | } else if (String.class.equals(type)) {
157 | property = new SimpleStringProperty();
158 | } else if (List.class.isAssignableFrom(type)) {
159 | property = new SimpleListProperty();
160 | } else if (Object.class.isAssignableFrom(type)) {
161 | property = new SimpleObjectProperty();
162 | }
163 | return property;
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/function/DragWindowHandlerImpl.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.function;
2 |
3 | import javafx.event.EventHandler;
4 | import javafx.scene.Cursor;
5 | import javafx.scene.input.MouseEvent;
6 | import javafx.scene.layout.Pane;
7 | import javafx.stage.Stage;
8 |
9 | /**
10 | * @author jack
11 | * @version 1.0
12 | * @date 2019/6/30 10:11
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | public class DragWindowHandlerImpl implements EventHandler {
16 | //参考
17 | private Stage stage; //primaryStage为start方法头中的Stage
18 | private double oldStageX;
19 | private double oldStageY;
20 | private double oldScreenX;
21 | private double oldScreenY;
22 | final int RESIZE_WIDTH = 5;// 判定是否为调整窗口状态的范围与边界距离
23 | private double MIN_WIDTH = 300;// 窗口最小宽度
24 | private double MIN_HEIGHT = 250;// 窗口最小高度
25 | boolean isRight;// 是否处于右边界调整窗口状态
26 | boolean isBottomRight;// 是否处于右下角调整窗口状态
27 | boolean isBottom;// 是否处于下边界调整窗口状态
28 | private Pane pane;
29 | private boolean resizable; //是否拉伸
30 | private boolean draggable; //是否拖拽
31 |
32 |
33 | public DragWindowHandlerImpl(Stage primaryStage, Pane pane, boolean draggable, boolean resizable) { //构造器
34 | this.stage = primaryStage;
35 | this.pane = pane;
36 | this.draggable = draggable;
37 | this.resizable = resizable;
38 | }
39 |
40 | public DragWindowHandlerImpl(Stage stage, double MIN_WIDTH, double MIN_HEIGHT, Pane pane, boolean draggable, boolean resizable) {
41 | this.stage = stage;
42 | this.MIN_WIDTH = MIN_WIDTH;
43 | this.MIN_HEIGHT = MIN_HEIGHT;
44 | this.pane = pane;
45 | this.draggable = draggable;
46 | this.resizable = resizable;
47 | }
48 |
49 | @Override
50 | public void handle(MouseEvent e) {
51 |
52 | if (e.getEventType() == MouseEvent.MOUSE_PRESSED) { //鼠标按下的事件
53 | //鼠标按下时记录坐标
54 | this.oldStageX = this.stage.getX();
55 | this.oldStageY = this.stage.getY();
56 | this.oldScreenX = e.getScreenX();
57 | this.oldScreenY = e.getScreenY();
58 | } else if (e.getEventType() == MouseEvent.MOUSE_DRAGGED) { //鼠标拖动的事件
59 | double nextX = stage.getX();
60 | double nextY = stage.getY();
61 | double nextWidth = stage.getWidth();
62 | double nextHeight = stage.getHeight();
63 |
64 | double x = e.getSceneX();
65 | double y = e.getSceneY();
66 | // 保存窗口改变后的x、y坐标和宽度、高度,用于预判是否会小于最小宽度、最小高度
67 | if (isRight || isBottomRight) {// 所有右边调整窗口状态
68 | nextWidth = x;
69 | }
70 | if (isBottomRight || isBottom) {// 所有下边调整窗口状态
71 | nextHeight = y;
72 | }
73 | if (nextWidth <= MIN_WIDTH) {// 如果窗口改变后的宽度小于最小宽度,则宽度调整到最小宽度
74 | nextWidth = MIN_WIDTH;
75 | }
76 | if (nextHeight <= MIN_HEIGHT) {// 如果窗口改变后的高度小于最小高度,则高度调整到最小高度
77 | nextHeight = MIN_HEIGHT;
78 | }
79 |
80 | // 最后统一改变窗口的x、y坐标和宽度、高度,可以防止刷新频繁出现的屏闪情况
81 | if (draggable) {
82 | if (isBottom || isBottomRight || isRight) {
83 | stage.setX(nextX);
84 | stage.setY(nextY);
85 | } else {
86 | this.stage.setX(e.getScreenX() - this.oldScreenX + this.oldStageX);
87 | this.stage.setY(e.getScreenY() - this.oldScreenY + this.oldStageY);
88 | }
89 | }
90 | if (resizable) {
91 | stage.setWidth(nextWidth);
92 | stage.setHeight(nextHeight);
93 | }
94 | } else if (e.getEventType() == MouseEvent.MOUSE_MOVED) { //鼠标移动
95 | e.consume();
96 | double x = e.getSceneX();
97 | double y = e.getSceneY();
98 | double width = stage.getWidth();
99 | double height = stage.getHeight();
100 | Cursor cursorType = Cursor.DEFAULT;// 鼠标光标初始为默认类型,若未进入调整窗口状态,保持默认类型
101 | // 先将所有调整窗口状态重置
102 | isRight = isBottomRight = isBottom = false;
103 |
104 | if (resizable) {
105 | if (y >= height - RESIZE_WIDTH) {
106 | if (x <= RESIZE_WIDTH) {// 左下角调整窗口状态
107 |
108 | } else if (x >= width - RESIZE_WIDTH) {// 右下角调整窗口状态
109 | isBottomRight = true;
110 | cursorType = Cursor.SE_RESIZE;
111 | } else {// 下边界调整窗口状态
112 | isBottom = true;
113 | cursorType = Cursor.S_RESIZE;
114 | }
115 | } else if (x >= width - RESIZE_WIDTH) {// 右边界调整窗口状态
116 | isRight = true;
117 | cursorType = Cursor.E_RESIZE;
118 | }
119 | // 最后改变鼠标光标
120 | pane.setCursor(cursorType);
121 | }
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/function/Draggale.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.function;
2 |
3 | /**
4 | * @author jack
5 | * @version 1.0
6 | * @date 2019/7/27 1:54
7 | * @since JavaFX2.0 JDK1.8
8 | */
9 | public interface Draggale {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/function/FXWindowParser.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.function;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXWindow;
4 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
5 | import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
6 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
7 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
8 | import cn.edu.scau.biubiusuisui.utils.FileUtil;
9 | import cn.edu.scau.biubiusuisui.utils.StringUtil;
10 | import javafx.event.EventHandler;
11 | import javafx.scene.image.Image;
12 | import javafx.stage.Stage;
13 |
14 | import java.io.File;
15 | import java.net.URL;
16 |
17 | /**
18 | * @author jack
19 | * @version 1.0
20 | * @date 2019/6/30 10:40
21 | * @description 解析@FXWindow
22 | * @since JavaFX2.0 JDK1.8
23 | */
24 | public class FXWindowParser {
25 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXWindowParser.class);
26 |
27 | public void parse(Stage stage, FXBaseController fxControllerProxy, FXWindow fxWindow) {
28 | logger.info("parsing @FXWindow of class: " + fxControllerProxy.getName());
29 | // 处理 title
30 | stage.setTitle(fxWindow.title());
31 |
32 | // 处理 icon
33 | if (!"".equals(fxWindow.icon())) {
34 | try {
35 | URL iconUrl = new FileUtil().getFilePathFromResources(fxWindow.icon());
36 | if (iconUrl != null) {
37 | if (new File(StringUtil.getRootPath(iconUrl)).exists()) {
38 | stage.getIcons().add(new Image(fxWindow.icon()));
39 | } else {
40 | logger.warn("the icon file has not existed");
41 | }
42 | } else {
43 | logger.warn("the icon file has not existed");
44 | }
45 | } catch (ProtocolNotSupport protocolNotSupport) {
46 | logger.error(protocolNotSupport.getMessage(), protocolNotSupport);
47 | protocolNotSupport.printStackTrace();
48 | }
49 | }
50 |
51 | // fxWindow的resizable默认为false
52 | if (fxWindow.resizable()) {
53 | stage.setResizable(true);
54 | }
55 |
56 | // 处理draggable和resizable
57 | if (fxWindow.draggable() || fxWindow.resizable()) {
58 | EventHandler dragWindowHandler = new DragWindowHandlerImpl(stage, fxWindow.minWidth(), fxWindow.minHeight(), fxControllerProxy, fxWindow.draggable(), fxWindow.resizable());
59 | fxControllerProxy.setOnMousePressed(dragWindowHandler);
60 | fxControllerProxy.setOnMouseDragged(dragWindowHandler);
61 | fxControllerProxy.setOnMouseMoved(dragWindowHandler);
62 | }
63 | // 处理style
64 | stage.initStyle(fxWindow.style());
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/log/FXPlusLogger.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.log;
2 |
3 |
4 | import org.apache.log4j.Level;
5 | import org.apache.log4j.Logger;
6 |
7 | /**
8 | * @author suisui
9 | * @version 1.2
10 | * @description JavaPlus的日志类
11 | * @date 2020/5/1 10:55
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | public class FXPlusLogger implements IFXPlusLogger {
15 | private Logger logger;
16 | private String FQCN;
17 |
18 | public FXPlusLogger(Logger logger) {
19 | this.FQCN = FXPlusLogger.class.getName();
20 | this.logger = logger;
21 | }
22 |
23 | public FXPlusLogger(String fqcn, Logger logger) {
24 | this.FQCN = fqcn;
25 | this.logger = logger;
26 | }
27 |
28 | @Override
29 | public void debug(Object message) {
30 | logger.log(FQCN, Level.DEBUG, message, null);
31 | }
32 |
33 | @Override
34 | public void debug(Object message, Throwable t) {
35 | logger.log(FQCN, Level.DEBUG, message, t);
36 | }
37 |
38 | @Override
39 | public void info(Object message) {
40 | logger.log(FQCN, Level.INFO, message, null);
41 | }
42 |
43 | @Override
44 | public void info(Object message, Throwable t) {
45 | logger.log(FQCN, Level.INFO, message, t);
46 | }
47 |
48 | @Override
49 | public void warn(Object message) {
50 | logger.log(FQCN, Level.WARN, message, null);
51 | }
52 |
53 | @Override
54 | public void warn(Object message, Throwable t) {
55 | logger.log(FQCN, Level.WARN, message, t);
56 | }
57 |
58 | @Override
59 | public void error(Object message) {
60 | logger.log(FQCN, Level.ERROR, message, null);
61 | }
62 |
63 | @Override
64 | public void error(Object message, Throwable t) {
65 | logger.log(FQCN, Level.ERROR, message, t);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/log/FXPlusLoggerContext.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.log;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description 日志类上下文
7 | * @date 2020/5/1 10:56
8 | * @since JavaFX2.0 JDK1.8
9 | */
10 | public class FXPlusLoggerContext {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/log/FXPlusLoggerFactory.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.log;
2 |
3 | import cn.edu.scau.biubiusuisui.utils.LogUtil;
4 | import org.apache.log4j.Logger;
5 |
6 | /**
7 | * @author suisui
8 | * @version 1.2
9 | * @description 生成日志类的工厂
10 | * @date 2020/5/1 10:56
11 | * @since JavaFX2.0 JDK1.8
12 | */
13 | public class FXPlusLoggerFactory {
14 |
15 | private FXPlusLoggerFactory() {
16 |
17 | }
18 |
19 | public static IFXPlusLogger getLogger(Class> clazz) {
20 | LogUtil.initLog4jBase();
21 | Logger logger = Logger.getLogger(clazz);
22 | return new FXPlusLogger(logger);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/log/IFXPlusLogger.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.log;
2 |
3 |
4 | import org.slf4j.Logger;
5 |
6 | /**
7 | * @author suisui
8 | * @version 1.2
9 | * @description 日志接口
10 | * @date 2020/5/1 10:54
11 | * @since JavaFX2.0 JDK1.8
12 | */
13 | public interface IFXPlusLogger {
14 | void debug(Object message);
15 |
16 | void debug(Object message, Throwable t);
17 |
18 | void info(Object message);
19 |
20 | void info(Object message, Throwable t);
21 |
22 | void warn(Object message);
23 |
24 | void warn(Object message, Throwable t);
25 |
26 | void error(Object message);
27 |
28 | void error(Object message, Throwable t);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/messageQueue/MessageQueue.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.messageQueue;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXReceiver;
4 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
5 | import cn.edu.scau.biubiusuisui.entity.FXMethodEntity;
6 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
7 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
8 |
9 | import java.lang.annotation.Annotation;
10 | import java.lang.reflect.InvocationTargetException;
11 | import java.lang.reflect.Method;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Map;
15 | import java.util.concurrent.ConcurrentHashMap;
16 |
17 | /**
18 | * @author jack
19 | * @version 1.0
20 | * @date 2019/6/25 12:24
21 | * @since JavaFX2.0 JDK1.8
22 | */
23 |
24 | public class MessageQueue {
25 | private IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(MessageQueue.class);
26 |
27 | private static Map> receivers = new ConcurrentHashMap<>(); //Map<主题,订阅了主题的所有方法>
28 |
29 | private static MessageQueue messageQueue = null;
30 |
31 | private MessageQueue() {
32 | }
33 |
34 | public static synchronized MessageQueue getInstance() {
35 | if (messageQueue == null) {
36 | messageQueue = new MessageQueue();
37 | }
38 | return messageQueue;
39 | }
40 |
41 | /**
42 | * @param fxBaseController
43 | * @param fxBaseControllerProxy
44 | * @Description 注册消费者,即FXReceiver注解的method
45 | */
46 | public void registerConsumer(FXBaseController fxBaseController, FXBaseController fxBaseControllerProxy) {
47 | Class clazz = fxBaseController.getClass();
48 | Method[] methods = clazz.getDeclaredMethods();
49 | for (Method method : methods) {
50 | Annotation[] annotations = method.getDeclaredAnnotations();
51 | for (Annotation annotation : annotations) {
52 | if (FXReceiver.class.equals(annotation.annotationType())) {
53 | logger.info("registering consumer: " + fxBaseControllerProxy.getName());
54 | // System.out.println("FXReceiver");
55 | FXReceiver receiver = (FXReceiver) annotation;
56 | FXMethodEntity fxMethodEntity = new FXMethodEntity(fxBaseControllerProxy, method);
57 | List fxMethodEntities = receivers.get(receiver.name());
58 | if (fxMethodEntities == null) {
59 | fxMethodEntities = new ArrayList<>();
60 | }
61 | fxMethodEntities.add(fxMethodEntity);
62 | receivers.put(receiver.name(), fxMethodEntities);
63 | }
64 | }
65 | }
66 | }
67 |
68 | /**
69 | * @param id
70 | * @param msg
71 | * @Description 处理消息发送,id为topic,msg为消息
72 | */
73 | public void sendMsg(String id, Object msg) {
74 | List lists = receivers.get(id);
75 | if (lists != null) {
76 | for (FXMethodEntity fxMethodEntity : lists) {
77 | Method method = fxMethodEntity.getMethod();
78 | method.setAccessible(true);
79 | FXBaseController fxBaseController = fxMethodEntity.getFxBaseController();
80 | if (method.getParameterCount() == 0) {
81 | try {
82 | method.invoke(fxBaseController);
83 | } catch (IllegalAccessException e) {
84 | logger.error(e.getMessage());
85 | e.printStackTrace();
86 | } catch (InvocationTargetException e) {
87 | logger.error(e.getMessage());
88 | e.printStackTrace();
89 | }
90 | } else {
91 | try {
92 | // obj the object the underlying method is invoked from
93 | method.invoke(fxBaseController, msg);
94 | } catch (IllegalAccessException e) {
95 | logger.error(e.getMessage());
96 | e.printStackTrace();
97 | } catch (InvocationTargetException e) {
98 | logger.error(e.getMessage());
99 | e.printStackTrace();
100 | }
101 | }
102 | }
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/proxy/FXControllerProxy.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.proxy;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
4 | import cn.edu.scau.biubiusuisui.annotation.FXSender;
5 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
6 | import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
7 | import cn.edu.scau.biubiusuisui.stage.StageManager;
8 | import net.sf.cglib.proxy.Enhancer;
9 | import net.sf.cglib.proxy.MethodInterceptor;
10 | import net.sf.cglib.proxy.MethodProxy;
11 |
12 | import java.lang.annotation.Annotation;
13 | import java.lang.reflect.Field;
14 | import java.lang.reflect.Method;
15 |
16 | /**
17 | * This proxy class intercept Methods that has special annotation such as
18 | * FXSender which is a mark for message queue
19 | *
20 | * @author jack
21 | * @version 1.0
22 | * @date 2019/6/25 2:03
23 | * @since JavaFX2.0 JDK1.8
24 | */
25 | public class FXControllerProxy implements MethodInterceptor {
26 |
27 |
28 | FXBaseController target;
29 |
30 |
31 | public Object getInstance(FXBaseController target) {
32 | this.target = target;
33 | Enhancer enhancer = new Enhancer();
34 | enhancer.setSuperclass(this.target.getClass());
35 | enhancer.setCallback(this);
36 | Object proxy = enhancer.create();
37 | // target.* -> proxy.*
38 | inject(target, proxy);
39 | return proxy;
40 | }
41 |
42 | @Override
43 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
44 | Object o1 = methodProxy.invokeSuper(o, objects); //获取该方法运行后的结果
45 | Annotation[] annotations = method.getDeclaredAnnotations();
46 |
47 | for (Annotation annotation : annotations) {
48 | if (FXSender.class.equals(annotation.annotationType())) { // 拦截是否发送消息函数
49 | FXSender fxSender = (FXSender) annotation;
50 | // System.out.println("FXSender");
51 | String name = target.getName() + ":";
52 | // System.out.println("FXControllerProxy:" + name);
53 | if ("".equals(fxSender.name())) {
54 | name += method.getName();
55 | } else {
56 | name += fxSender.name();
57 | }
58 | MessageQueue.getInstance().sendMsg(name, o1);
59 | }
60 | if (FXRedirect.class.equals((annotation.annotationType()))) { //拦截是否重定向函数
61 | FXRedirect fxRedirect = (FXRedirect) annotation;
62 | if (fxRedirect.close()) { //关闭原窗口
63 | StageManager.getInstance().closeStage(target.getName());
64 | }
65 | StageManager.getInstance().redirectTo(o1);
66 | }
67 | }
68 | return o1;
69 | }
70 |
71 | private void inject(Object target, Object proxy) {
72 | Class clazz = target.getClass();
73 | Field[] fields = clazz.getDeclaredFields();
74 | for (Field field : fields) {
75 | field.setAccessible(true);
76 | try {
77 | Object value = field.get(target);
78 | field.set(proxy, value);
79 | } catch (IllegalAccessException e) {
80 | e.printStackTrace();
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/proxy/FXEntityProxy.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.proxy;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXFieldWrapper;
4 | import cn.edu.scau.biubiusuisui.utils.StringUtil;
5 | import javafx.beans.property.*;
6 | import net.sf.cglib.proxy.Enhancer;
7 | import net.sf.cglib.proxy.MethodInterceptor;
8 | import net.sf.cglib.proxy.MethodProxy;
9 |
10 | import java.lang.reflect.Method;
11 | import java.util.Map;
12 |
13 | /**
14 | * @author jack
15 | * @version 1.0
16 | * @date 2019/6/27 18:47
17 | * @since JavaFX2.0 JDK1.8
18 | */
19 | public class FXEntityProxy implements MethodInterceptor {
20 |
21 | Object target;
22 | private Map fxFieldWrapperMap;
23 |
24 | /**
25 | * @param target
26 | * @return
27 | * @Desciption 通过getInstance获取代理对象
28 | */
29 | public Object getInstance(Object target) {
30 | this.target = target;
31 | Enhancer enhancer = new Enhancer();
32 | enhancer.setSuperclass(this.target.getClass());
33 | enhancer.setCallback(this);
34 | return enhancer.create();
35 | }
36 |
37 | /**
38 | * intercept get and set method and
39 | *
40 | * @param proxy cglib生成的代理对象
41 | * @param method 被代理对象的方法
42 | * @param args 拦截的方法的入参
43 | * @param methodProxy 拦截方法的代理方法
44 | * @return
45 | * @throws Throwable
46 | * @Descripton 拦截getter, setter, del, cls, add方法
47 | */
48 |
49 | @Override
50 | public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
51 | Object revokeResult = methodProxy.invokeSuper(proxy, args); //获取该方法运行后的结果
52 | String methodName = method.getName();
53 | String fieldName = null;
54 | if (methodName.length() >= 3) {
55 | fieldName = StringUtil.toInstanceName(methodName.substring(3)); // 该method有可能是getter和setter方法,进行处理
56 | } else {
57 | return revokeResult;
58 | }
59 | FXFieldWrapper fxFieldWrapper = fxFieldWrapperMap.get(fieldName);
60 | Property property = getPropertyByFieldName(fieldName);
61 | if (fxFieldWrapper == null || property == null) { //非属性的getter或setter
62 | return revokeResult;
63 | }
64 | Class type = fxFieldWrapper.getType();
65 | if (methodName.startsWith("set")) {
66 | if (Boolean.class.equals(type) || boolean.class.equals(type)) {
67 | ((SimpleBooleanProperty) property).set((Boolean) args[0]);
68 | } else if (Double.class.equals(type) || double.class.equals(type)) {
69 | ((SimpleDoubleProperty) property).set((Double) args[0]);
70 | } else if (Float.class.equals(type) || float.class.equals(type)) {
71 | ((SimpleFloatProperty) property).set((Float) args[0]);
72 | } else if (Integer.class.equals(type) || int.class.equals(type)) {
73 | ((SimpleIntegerProperty) property).set((Integer) args[0]);
74 | } else if (Long.class.equals(type) || long.class.equals(type)) {
75 | ((SimpleLongProperty) property).set((Long) args[0]);
76 | } else if (String.class.equals(type)) {
77 | ((SimpleStringProperty) property).set((String) args[0]);
78 | }
79 | } else if (methodName.startsWith("add")) {
80 | ((SimpleListProperty) (property)).add(args[0]);
81 | } else if (methodName.startsWith("del")) {
82 | ((SimpleListProperty) (property)).remove(args[0]);
83 | } else if (methodName.startsWith("cls")) {
84 | ((SimpleListProperty) (property)).clear();
85 | }
86 | return revokeResult;
87 | }
88 |
89 | public Object getTarget() {
90 | return target;
91 | }
92 |
93 | public void setTarget(Object target) {
94 | this.target = target;
95 | }
96 |
97 | public Property getPropertyByFieldName(String name) {
98 | if (fxFieldWrapperMap.get(name) == null) {
99 | return null;
100 | }
101 | return fxFieldWrapperMap.get(name).getProperty();
102 | }
103 |
104 | public Map getFXFieldWrapperMap() {
105 | return fxFieldWrapperMap;
106 | }
107 |
108 | public void setFXFieldWrapperMap(Map fxFieldWrapperMap) {
109 | this.fxFieldWrapperMap = fxFieldWrapperMap;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/stage/StageManager.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.stage;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXBaseController;
4 | import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
5 | import cn.edu.scau.biubiusuisui.entity.FXRedirectParam;
6 | import cn.edu.scau.biubiusuisui.exception.InvalidURLException;
7 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
8 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
9 |
10 | import java.util.ArrayDeque;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.concurrent.ConcurrentHashMap;
14 |
15 | /**
16 | * @author suisui
17 | * @version 1.1
18 | * @description 舞台管理器
19 | * @date 2019/12/3 15:43
20 | * @since JavaFX2.0 JDK1.8
21 | */
22 | public class StageManager {
23 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(StageManager.class);
24 |
25 | private static StageManager stageManager = null;
26 | private static Map initWindows = new ConcurrentHashMap<>();
27 | private static Map windowClazz = new ConcurrentHashMap<>();
28 | /**
29 | * @author yangsuiyu
30 | * @description 1.2新增属性
31 | */
32 | private static ArrayDeque windowsStack = new ArrayDeque<>();
33 |
34 | private StageManager() {
35 |
36 | }
37 |
38 | /**
39 | * 单例
40 | *
41 | * @return
42 | */
43 | public static synchronized StageManager getInstance() {
44 | if (stageManager == null) {
45 | stageManager = new StageManager();
46 | }
47 | return stageManager;
48 | }
49 |
50 | /**
51 | * 注册FXWindow注解的Controller
52 | *
53 | * @param clazz
54 | * @param fxBaseControllerProxy
55 | */
56 | public void registerWindow(Class clazz, FXBaseController fxBaseControllerProxy) {
57 | fxBaseControllerProxy.getClass().getDeclaredAnnotations();
58 | initWindows.put(fxBaseControllerProxy.getName(), fxBaseControllerProxy);
59 | windowClazz.put(fxBaseControllerProxy.getName(), clazz);
60 | }
61 |
62 | /**
63 | * 关闭窗口
64 | *
65 | * @param controllerName
66 | */
67 | public void closeStage(String controllerName) {
68 | if (initWindows.get(controllerName) != null) {
69 | initWindows.get(controllerName).closeStage();
70 | }
71 | }
72 |
73 | /**
74 | * @param redirectParams
75 | * @Description 跳转
76 | */
77 | public void redirectTo(Object redirectParams) {
78 | FXRedirectParam fxRedirectParam = null;
79 | if (redirectParams instanceof String) {
80 | if (((String) redirectParams).contains("?")) { //有参数,query return "SuccessController?name=ss&psw=111"
81 | try {
82 | fxRedirectParam = getQueryParamsFromURL((String) redirectParams);
83 | } catch (InvalidURLException e) {
84 | logger.error(e.getMessage());
85 | e.printStackTrace();
86 | }
87 | } else { //无参数 return "SuccessController"
88 | fxRedirectParam = new FXRedirectParam((String) redirectParams);
89 | }
90 | } else if (redirectParams instanceof FXRedirectParam) { // return FXRedirectParam
91 | fxRedirectParam = (FXRedirectParam) redirectParams;
92 | }
93 | redirectWithParams(fxRedirectParam);
94 | }
95 |
96 | /**
97 | * @param fxRedirectParam
98 | * @Description 携带参数跳转
99 | */
100 | private void redirectWithParams(FXRedirectParam fxRedirectParam) {
101 | if (fxRedirectParam != null) {
102 | String toControllerStr = fxRedirectParam.getToController();
103 | FXBaseController toController = initWindows.get(toControllerStr);
104 | if (toController != null) {
105 | List controllers = FXPlusContext.getControllers(toController.getName());
106 | // if (controllers.size() > 0) {
107 | // FXBaseController newController = controllers.get(controllers.size() - 1);
108 | // toController = FXControllerFactory.getFXController(newController.getClass(), toControllerStr);
109 | //// registerWindow(, toController);
110 | // }
111 | logger.debug("redirecting to " + toController.getName());
112 | toController.setParam(fxRedirectParam.getParams());
113 | toController.setQuery(fxRedirectParam.getQueryMap());
114 | toController.showStage();
115 | }
116 | }
117 | }
118 |
119 | /**
120 | * RedirectController?num=10&name=suisui -> Map:{"num","10"},{"name","suisui"}
121 | *
122 | * @param url
123 | * @return
124 | */
125 | private FXRedirectParam getQueryParamsFromURL(String url) throws InvalidURLException {
126 | String[] items = url.split("\\?");
127 | if (items.length != 2) {
128 | throw new InvalidURLException();
129 | }
130 | String leftBase = items[0];
131 | String paramsStr = items[1];
132 | String[] paramsKV = paramsStr.split("&");
133 |
134 | FXRedirectParam fxRedirectParam = new FXRedirectParam(leftBase);
135 | for (int i = 0; i < paramsKV.length; i++) {
136 | String params[] = paramsKV[i].split("=");
137 | if (params.length != 2) {
138 | throw new InvalidURLException();
139 | } else {
140 | fxRedirectParam.addQuery(params[0], params[1]);
141 | }
142 | }
143 | return fxRedirectParam;
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/BeanUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
4 | import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
5 | import javafx.beans.property.Property;
6 |
7 | /**
8 | * @author jack
9 | * @version 1.0
10 | * @Date:2019/7/28 1:52
11 | * @Description:
12 | * @since JavaFX2.0 JDK1.8
13 | */
14 | public class BeanUtil {
15 | public static Property getPropertyByName(Object entity, String fieldName) {
16 | FXEntityProxy fxEntityProxy = FXPlusContext.getProxyByBeanObject(entity);
17 | if (fxEntityProxy == null) {
18 | return null;
19 | }
20 | return fxEntityProxy.getFXFieldWrapperMap().get(fieldName).getProperty();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/ClassUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.lang.annotation.Annotation;
6 | import java.lang.reflect.Field;
7 | import java.net.URL;
8 | import java.util.*;
9 | import java.util.jar.JarEntry;
10 | import java.util.jar.JarFile;
11 |
12 | /**
13 | * @author jack
14 | * @version 1.0
15 | * @date 2019/6/25 5:20
16 | * @since JavaFX2.0 JDK1.8
17 | */
18 | public class ClassUtil {
19 | private ClassLoader classLoader;
20 |
21 | public ClassUtil() {
22 | classLoader = getClass().getClassLoader();
23 | }
24 |
25 | private List getAllFXControllerClassName(String base, List nameList) {
26 | String splashPath = StringUtil.dotToSplash(base);
27 | URL url = classLoader.getResource(splashPath);
28 | String filePath = StringUtil.getRootPath(url);
29 | List names = null;
30 | if (filePath.endsWith("jar")) {
31 | nameList = readFromJarDirectory(filePath, base);
32 | } else {
33 | names = readFromDirectory(filePath);
34 | for (String name : names) {
35 | if (isClassFile(name)) {
36 | nameList.add(toFullyQualifiedName(name, base));
37 | } else if (isDirectory(name)) {
38 | nameList = getAllFXControllerClassName(base + "." + name, nameList);
39 | }
40 | }
41 | }
42 | return nameList;
43 | }
44 |
45 | public List scanAllClassName(String base) {
46 | return getAllFXControllerClassName(base, new LinkedList<>());
47 | }
48 |
49 | private static String toFullyQualifiedName(String shortName, String basePackage) {
50 | StringBuilder sb = new StringBuilder(basePackage);
51 | sb.append('.');
52 | sb.append(StringUtil.trimExtension(shortName));
53 | return sb.toString();
54 | }
55 |
56 | private static boolean isClassFile(String name) {
57 | return name.endsWith(".class");
58 | }
59 |
60 | private static boolean isDirectory(String name) {
61 | return !name.contains(".");
62 | }
63 |
64 | private static List readFromDirectory(String path) {
65 | if (path == null) return null;
66 | return readFromFileDirectory(path);
67 | }
68 |
69 | private static List readFromJarDirectory(String path, String packageName) {
70 | JarFile jarFile = null;
71 | try {
72 | jarFile = new JarFile(path);
73 | } catch (IOException e) {
74 | e.printStackTrace();
75 | }
76 | Enumeration entrys = jarFile.entries();
77 | List classNames = new ArrayList<>();
78 | while (entrys.hasMoreElements()) {
79 | JarEntry jarEntry = entrys.nextElement();
80 | if (!jarEntry.getName().endsWith(".class")) continue;
81 | int packageNameIndex = jarEntry.getName().indexOf("/");
82 | if ("".equals(packageName)) {
83 | classNames.add(jarEntry.getName());
84 | } else {
85 | if (packageNameIndex == -1) continue;
86 | String baseName = jarEntry.getName().substring(0, packageNameIndex);
87 | if (baseName.equals(packageName)) {
88 | classNames.add(StringUtil.trimExtension(jarEntry.getName()).replaceAll("/", "."));
89 | }
90 | }
91 | }
92 | return classNames;
93 | }
94 |
95 | private static List readFromFileDirectory(String path) {
96 | File file = new File(path);
97 | String[] names = file.list();
98 | if (null == names) {
99 | return null;
100 | } else {
101 | return Arrays.asList(names);
102 | }
103 | }
104 |
105 |
106 | public static boolean hasDeclaredAnnotation(Class clazz, Class annotation) {
107 | if (annotation == null) {
108 | return false;
109 | }
110 | if (hasAnnotationInList(annotation, clazz.getDeclaredAnnotations())) return true;
111 | return false;
112 | }
113 |
114 | public static boolean hasAnnotation(Class clazz, Class annotation) {
115 | if (annotation == null) {
116 | return false;
117 | }
118 | if (hasAnnotationInList(annotation, clazz.getAnnotations())) return true;
119 | return false;
120 | }
121 |
122 | public static boolean hasAnnotationInList(Class annotation, Annotation[] annotations2) {
123 | if (getAnnotationInList(annotation, annotations2) == null) {
124 | return false;
125 | } else {
126 | return true;
127 | }
128 | }
129 |
130 | public static Annotation getAnnotationInList(Class annotation, Annotation[] annotations) {
131 | if (annotations == null || annotation == null) {
132 | return null;
133 | }
134 | for (Annotation annotation1 : annotations) {
135 | if (annotation1.annotationType().equals(annotation)) {
136 | return annotation1;
137 | }
138 | }
139 | return null;
140 | }
141 |
142 | public static void copyField(Object target, Object base) {
143 | Class clazz = base.getClass();
144 | Class targetClass = target.getClass();
145 | Field[] fields = clazz.getDeclaredFields();
146 | for (Field field : fields) {
147 | field.setAccessible(true);
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/FileUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
4 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
5 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
6 |
7 | import java.io.*;
8 | import java.net.URL;
9 |
10 | /**
11 | * @author jack
12 | * @version 1.0
13 | * @date 2019/6/25 7:01
14 | * @since JavaFX2.0 JDK1.8
15 | */
16 | public class FileUtil {
17 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FileUtil.class);
18 |
19 | /**
20 | * @param filePath
21 | * @return
22 | * @throws ProtocolNotSupport
23 | * @decription 从resources文件夹中读取File
24 | * 输出如: file:/Users/suisui/workspace/Idea/JavaFX-Plus/target/classes/image/icon.png
25 | * @version 1.0
26 | */
27 | public URL getFilePathFromResources(String filePath) throws ProtocolNotSupport {
28 | return FileUtil.class.getClassLoader().getResource(filePath);
29 | }
30 |
31 | /**
32 | * @param filePath
33 | * @return
34 | * @description 读取resources文件夹下的file,相对于resources的文件路径,如 resources/config.conf 则只需 config.conf
35 | */
36 | public static String readFileFromResources(String filePath) {
37 | String path = StringUtil.getRootPath(FileUtil.class.getClassLoader().getResource(filePath));
38 | return readFile(path);
39 | }
40 |
41 | /**
42 | * @param filePath 绝对路径或相对路径
43 | * @return
44 | * @description 读取文件
45 | */
46 | public static String readFile(String filePath) {
47 | StringBuffer content = new StringBuffer();
48 | try (FileReader reader = new FileReader(filePath);
49 | BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
50 | ) {
51 | String temp;
52 | while ((temp = br.readLine()) != null) {
53 | // 一次读入一行数据
54 | content.append(temp + "\r\n");
55 | }
56 | } catch (IOException e) {
57 | logger.error(e.getMessage());
58 | e.printStackTrace();
59 | }
60 | return content.toString();
61 | }
62 |
63 | /**
64 | * @param filePath
65 | * @param content
66 | * @description 写文件
67 | */
68 | public static void writeFile(String filePath, String content) {
69 | try {
70 | File writeName = new File(filePath); // 相对路径,如果没有则要建立一个新的output.txt文件
71 | writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
72 | try (FileWriter writer = new FileWriter(writeName);
73 | BufferedWriter out = new BufferedWriter(writer)
74 | ) {
75 | out.write(content);
76 | out.flush(); // 把缓存区内容压入文件
77 | }
78 | } catch (IOException e) {
79 | logger.error(e.getMessage());
80 | e.printStackTrace();
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/LogUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 |
4 | import cn.edu.scau.biubiusuisui.log.FXPlusLogger;
5 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
6 | import org.apache.log4j.Logger;
7 |
8 | /**
9 | * @author suisui
10 | * @version 1.2
11 | * @description 日志工具类
12 | * @date 2020/5/1 10:54
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | public class LogUtil {
16 | private static final String FQCN = LogUtil.class.getName();
17 | private static IFXPlusLogger logger;
18 |
19 | static {
20 | initLog4jBase();
21 | logger = new FXPlusLogger(FQCN, Logger.getLogger(LogUtil.class));
22 | }
23 |
24 | public static void initLog4jBase() {
25 | if (System.getProperty("log.base") == null) {
26 | // 默认是当前目录下
27 | String projectPath = PathUtil.getCurrentPath();
28 | initLog4jBase(projectPath);
29 | }
30 | }
31 |
32 | public static void initLog4jBase(String base) {
33 | System.setProperty("log.base", base);
34 | }
35 |
36 | public static void debug(Object message) {
37 | logger.debug(message);
38 | }
39 |
40 | public static void debug(Object message, Throwable t) {
41 | logger.debug(message, t);
42 | }
43 |
44 | public static void info(Object message) {
45 | logger.info(message);
46 | }
47 |
48 | public static void info(Object message, Throwable t) {
49 | logger.debug(message, t);
50 | }
51 |
52 | public static void warn(Object message) {
53 | logger.warn(message);
54 | }
55 |
56 | public static void warn(Object message, Throwable t) {
57 | logger.warn(message, t);
58 | }
59 |
60 | public static void error(Object message) {
61 | logger.error(message);
62 | }
63 |
64 | public static void error(Object message, Throwable t) {
65 | logger.error(message, t);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/PathUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | /**
4 | * @author suisui
5 | * @version 1.2
6 | * @description 路径工具类
7 | * @date 2020/5/2 14:43
8 | * @since JDK1.8
9 | */
10 | public class PathUtil {
11 | public static String getCurrentPath() {
12 | return System.getProperty("user.dir");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/ResourceBundleUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
4 | import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
5 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
6 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
7 |
8 | import java.io.File;
9 | import java.util.Locale;
10 | import java.util.MissingResourceException;
11 | import java.util.ResourceBundle;
12 |
13 | /**
14 | * @author suisui
15 | * @version 1.2
16 | * @description 语言国际化工具类
17 | * @date 2020/5/1 11:15
18 | * @since JavaFX2.0 JDK1.8
19 | */
20 | public class ResourceBundleUtil {
21 | private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(ResourceBundleUtil.class);
22 |
23 | /**
24 | * @param baseName
25 | * @param fxPlusLocale
26 | * @return
27 | * @description 获取Java的ResourceBundle
28 | */
29 | public static ResourceBundle getResourceBundle(String baseName, FXPlusLocale fxPlusLocale) {
30 | baseName = StringUtil.trimExtension(baseName);
31 | baseName = StringUtil.splashToDot(baseName);
32 | Locale locale = ResourceBundleUtil.getLocale(fxPlusLocale);
33 |
34 | // logger.info(baseName);
35 | if (locale != null) {
36 | return ResourceBundle.getBundle(baseName, locale);
37 | }
38 | return null;
39 | }
40 |
41 | /**
42 | * @param fxPlusLocale
43 | * @return
44 | * @description 通过FXPlusLocale枚举类型获取Locale
45 | */
46 | private static Locale getLocale(FXPlusLocale fxPlusLocale) {
47 | switch (fxPlusLocale) {
48 | case SIMPLIFIED_CHINESE:
49 | return Locale.SIMPLIFIED_CHINESE;
50 | case FRANCE:
51 | return Locale.FRANCE;
52 | case KOREAN:
53 | return Locale.KOREAN;
54 | case ENGLISH:
55 | return Locale.UK;
56 | case GERMANY:
57 | return Locale.GERMANY;
58 | case ITALIAN:
59 | return Locale.ITALIAN;
60 | case AMERICAN:
61 | return Locale.US;
62 | case JAPANESE:
63 | return Locale.JAPAN;
64 | case TRADITIONAL_CHINESE:
65 | return Locale.TRADITIONAL_CHINESE;
66 | default:
67 | return null;
68 | }
69 | }
70 |
71 | /**
72 | * @param key
73 | * @return
74 | * @description 通过key获取String类型的value值,失败或不存在返回空字符串
75 | */
76 | public static String getStringValue(ResourceBundle resource, String key) {
77 | if ("".equals(key) || null == key) {
78 | return "";
79 | }
80 | try {
81 | return resource.getString(key);
82 | } catch (MissingResourceException | ClassCastException e) {
83 | logger.error(e.getMessage());
84 | // e.printStackTrace();
85 | return "";
86 | }
87 | }
88 |
89 | /**
90 | * @param key
91 | * @return
92 | * @description 通过key获取Integer类型的value值,失败或不存在返回-1
93 | */
94 | public static Integer getIntegerValue(ResourceBundle resource, String key) {
95 | if ("".equals(key) || null == key) {
96 | return -1;
97 | }
98 | try {
99 | return Integer.valueOf(resource.getString(key));
100 | } catch (MissingResourceException | NumberFormatException e) {
101 | logger.error(e.getMessage());
102 | // e.printStackTrace();
103 | return -1;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/cn/edu/scau/biubiusuisui/utils/StringUtil.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 | import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
4 | import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
5 |
6 | import java.net.URL;
7 |
8 | /**
9 | * @author jack
10 | * @author suisui
11 | * @version 1.0
12 | * @date 2019/6/25 3:46
13 | * @since JavaFX2.0 JDK1.8
14 | */
15 | public class StringUtil {
16 | private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(StringUtil.class);
17 |
18 | private StringUtil() {
19 |
20 | }
21 |
22 | /**
23 | * "file:/home/whf/cn/fh" -> "/home/whf/cn/fh"
24 | * "jar:file:/home/whf/foo.jar!cn/fh" -> "/home/whf/foo.jar"
25 | */
26 | public static String getRootPath(URL url) {
27 | String fileUrl = url.getFile();
28 | int pos = fileUrl.indexOf('!');
29 |
30 | if (-1 == pos) {
31 | return fileUrl;
32 | }
33 |
34 | return fileUrl.substring(5, pos);
35 | }
36 |
37 | /**
38 | * "cn.fh.lightning" -> "cn/fh/lightning"
39 | *
40 | * @param name
41 | * @return
42 | */
43 | public static String dotToSplash(String name) {
44 | return name.replaceAll("\\.", "/");
45 | }
46 |
47 | /**
48 | * "cn/fh/lightning" -> "cn.fh.lightning"
49 | *
50 | * @param name
51 | * @return
52 | */
53 | public static String splashToDot(String name) {
54 |
55 | return name.replaceAll("/", "\\.");
56 | }
57 |
58 | /**
59 | * "Apple.class" -> "Apple"
60 | */
61 | public static String trimExtension(String name) {
62 | int pos = name.lastIndexOf('.');
63 | if (-1 != pos) {
64 | return name.substring(0, pos);
65 | }
66 |
67 | return name;
68 | }
69 |
70 | /**
71 | * /application/home -> /home
72 | *
73 | * @param uri
74 | * @return
75 | */
76 | public static String trimURI(String uri) {
77 | String trimmed = uri.substring(1);
78 | int splashIndex = trimmed.indexOf('/');
79 |
80 | return trimmed.substring(splashIndex);
81 | }
82 |
83 | /**
84 | * MainController$receive -> MainController
85 | *
86 | * @param name
87 | * @return
88 | */
89 | public static String getBaseClassName(String name) {
90 | int index = name.indexOf("$");
91 | if (index == -1) {
92 | return name;
93 | }
94 | // System.out.println(name.substring(0, index));
95 | return name.substring(0, index);
96 | }
97 |
98 |
99 | /**
100 | * Object -> object ; Student -> student
101 | *
102 | * @param name
103 | * @return
104 | */
105 | public static String toInstanceName(String name) {
106 | String result = name.substring(0, 1).toLowerCase().concat(name.substring(1));
107 | return result;
108 | }
109 |
110 | /**
111 | * object -> Object ; student -> Student
112 | *
113 | * @param name
114 | * @return
115 | */
116 | public static String toClassName(String name) {
117 | String result = name.substring(0, 1).toUpperCase().concat(name.substring(1));
118 | return result;
119 | }
120 |
121 | /**
122 | * cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/languageDemo.fxml -> fxml/languageDemo/languageDemo.fxml
123 | *
124 | * @param name
125 | * @return
126 | * @description 获取相对于resources目录下的路径
127 | */
128 | public static String getFilePathInResources(String name) {
129 | String resources = "resources";
130 | int resIdx = name.indexOf(resources);
131 | if (resIdx == -1) {
132 | return name;
133 | }
134 | return name.substring(resIdx + resources.length() + 1);
135 | }
136 |
137 | /**
138 | * cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/languageDemo.fxml -> languageDemo
139 | *
140 | * @param name 文件名
141 | * @return
142 | * @version 1.2
143 | */
144 | public static String getFileBaseName(String name) {
145 | String result = "";
146 | String[] tempStrs = name.split("/");
147 | if (1 == tempStrs.length) { //只有文件名,即name: languageDemo.fxml
148 | result = StringUtil.trimExtension(name);
149 | } else {
150 | result = StringUtil.trimExtension(tempStrs[tempStrs.length - 1]);
151 | }
152 | return result;
153 | }
154 |
155 | }
--------------------------------------------------------------------------------
/src/main/resources/applicationContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | _ ________ __ _____ _
2 | | | | ____\ \ / / | __ \| |
3 | | | __ ___ ____ _| |__ \ V / _____ | |__) | |_ _ ___
4 | _ | |/ _` \ \ / / _` | __| > < _____ | ___/| | | | / __|
5 | | |__| | (_| |\ V / (_| | | / . \ | | | | |_| \__ \
6 | \____/ \__,_| \_/ \__,_|_| /_/ \_\ |_| |_|\__,_|___/
--------------------------------------------------------------------------------
/src/main/resources/fxml/Main.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/Main2.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/SpringExpressionDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/firstDemo/firstDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
11 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/index.js:
--------------------------------------------------------------------------------
1 | console.log('123123');
--------------------------------------------------------------------------------
/src/main/resources/fxml/languageDemo/languageDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/languageDemo/languageDemo_en.properties:
--------------------------------------------------------------------------------
1 | login=login
2 | login.username=Username
3 | login.password=Password
4 | login.button=Login
5 | register=Register
6 | register.username=Username
7 | register.password=password
8 | register.confirmPassword=Confirm Password
9 | register.phone=Phone
10 | register.email=Email
11 | password=Password
12 | email=Email
13 | phone=Phone
14 | korean=\ud55c\uad6d\uc5b4
15 | chinese=\u4e2d\u6587
16 | english=English
17 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/languageDemo/languageDemo_ko.properties:
--------------------------------------------------------------------------------
1 | login=\ub85c\uadf8\uc778
2 | login.username=\uc544\uc774\ub514
3 | login.password=\ube44\ubc00\ubc88\ud638
4 | login.button=\ub85c\uadf8\uc778
5 | register=\uac00\uc785
6 | register.username=\uc544\uc774\ub514
7 | register.password=\ube44\ubc00\ubc88\ud638
8 | register.confirmPassword=\ube44\ubc00\ubc88\ud638 \ud655\uc778
9 | register.phone=\ud734\ub300 \uc804\ud654
10 | register.email=\uc6b0\ud3b8\ud568
11 | password=\ube44\ubc00\ubc88\ud638
12 | email=\uc6b0\ud3b8\ud568
13 | phone=\ud734\ub300 \uc804\ud654
14 | korean=\ud55c\uad6d\uc5b4
15 | chinese=\u4e2d\u6587
16 | english=English
17 | #login=로그인
18 | #login.username=아이디
19 | #login.password=비밀번호
20 | #login.button=로그인
21 | #register=가입
22 | #register.username=아이디
23 | #register.password=비밀번호
24 | #register.confirmPassword=비밀번호 확인
25 | #register.phone=휴대 전화
26 | #register.email=우편함
27 | #password=비밀번호
28 | #email=우편함
29 | #phone=휴대 전화
30 | #korean=한국어
31 | #chinese=中文
32 | #english=English
--------------------------------------------------------------------------------
/src/main/resources/fxml/languageDemo/languageDemo_zh_CN.properties:
--------------------------------------------------------------------------------
1 | login=\u767b\u5f55
2 | login.username=\u7528\u6237\u540d
3 | login.password=\u5bc6\u7801
4 | login.button=\u70b9\u51fb\u767b\u5f55
5 | register=\u6ce8\u518c
6 | register.username=\u7528\u6237\u540d
7 | register.password=\u5bc6\u7801
8 | register.confirmPassword=\u786e\u8ba4\u5bc6\u7801
9 | register.email=\u90ae\u7bb1
10 | register.phone=\u624b\u673a
11 | password=\u5bc6\u7801
12 | email=\u90ae\u7bb1
13 | phone=\u624b\u673a
14 | korean=\ud55c\uad6d\uc5b4
15 | chinese=\u4e2d\u6587
16 | english=English
17 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/dialog.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/dialog_en.properties:
--------------------------------------------------------------------------------
1 | dialog=Dialog
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/dialog_zh_CN.properties:
--------------------------------------------------------------------------------
1 | dialog=弹窗
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/lifeMain.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/lifeMain_en.properties:
--------------------------------------------------------------------------------
1 | button.goAndClose=goto Dialog and close this window
2 | button.go=goto Dialog
3 | parentController=Parent Component
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/lifeMain_zh_CN.properties:
--------------------------------------------------------------------------------
1 | button.goAndClose=\u8df3\u8f6c\u5e76\u5173\u95ed\u6b64\u7a97\u53e3
2 | button.go=\u5f39\u7a97
3 | parentController=\u7236\u7ec4\u4ef6
4 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/subBar.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/subBar_en.properties:
--------------------------------------------------------------------------------
1 | childrenController=Children Component
--------------------------------------------------------------------------------
/src/main/resources/fxml/lifeDemo/subBar_zh_CN.properties:
--------------------------------------------------------------------------------
1 | childrenController=子组件
--------------------------------------------------------------------------------
/src/main/resources/fxml/listDemo/listDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/moveDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/mqDemo/main.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/mqDemo/topBar.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/redirectDemo/dialog.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/redirectDemo/login.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
55 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/redirectDemo/register.css:
--------------------------------------------------------------------------------
1 | #content {
2 | alignment: center;
3 | }
4 |
5 | #content .label {
6 | -fx-pref-height: 50;
7 | -fx-pref-width: 100;
8 | }
--------------------------------------------------------------------------------
/src/main/resources/fxml/redirectDemo/register.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/redirectDemo/success.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/resizableDemo/resizableDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | X
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/springDemo.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/springDemo2.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/resources/image/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BillKiller/JavaFX-Plus/ffc17362bde93677793c529b6bb557a3dae3819a/src/main/resources/image/icon.png
--------------------------------------------------------------------------------
/src/main/resources/language/javafxplus_en.properties:
--------------------------------------------------------------------------------
1 | login=login
2 | login.username=Username
3 | login.password=Password
4 | login.button=Login
5 | register=Register
6 | register.username=Username
7 | register.password=password
8 | register.confirmPassword=Confirm Password
9 | register.email=Email
10 | register.phone=Phone
11 | password=Password
12 | email=Email
13 | phone=Phone
--------------------------------------------------------------------------------
/src/main/resources/language/javafxplus_zh_CN.properties:
--------------------------------------------------------------------------------
1 | login=登录
2 | login.username=用户名
3 | login.password=密码
4 | login.button=点击登录
5 | register=注册
6 | register.username=用户名
7 | register.password=密码
8 | register.confirmPassword=确认密码
9 | register.email=邮箱
10 | password=密码
11 | email=邮箱
12 | phone=手机
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | ### 设置###
2 | log4j.rootLogger=debug,stdout,D,E
3 | ### 输出信息到控制台 ###
4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
5 | log4j.appender.stdout.Target=System.out
6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
7 | log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] - %m%n
8 | ### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
9 | log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
10 | ### Windowsy
11 | #log4j.appender.D.File = E://logs/debug/log.log
12 | # MacOS
13 | log4j.appender.D.File=${log.base}/logs/debug/javafxplus.log
14 | log4j.appender.D.Append=true
15 | log4j.appender.D.Threshold=DEBUG
16 | log4j.appender.D.layout=org.apache.log4j.PatternLayout
17 | log4j.appender.D.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
18 | ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
19 | log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
20 | ### Windows
21 | #log4j.appender.E.File = E://logs/error/log.log
22 | # MacOS
23 | log4j.appender.E.File=${log.base}/logs/error/javafxplus.log
24 | log4j.appender.E.Append=true
25 | log4j.appender.E.Threshold=ERROR
26 | log4j.appender.E.layout=org.apache.log4j.PatternLayout
27 | log4j.appender.E.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
--------------------------------------------------------------------------------
/src/test/java/MainTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.Test;
2 |
3 | import java.lang.reflect.Method;
4 | import java.lang.reflect.Parameter;
5 |
6 | /**
7 | * @Author jack
8 | * @Date:2019/6/25 2:11
9 | */
10 | public class MainTest {
11 |
12 | public void testMethod(String a,int b){
13 |
14 | }
15 | @Test
16 | public void test() throws NoSuchMethodException {
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/java/cn/edu/scau/biubiusuisui/expression/ExpressionParserTest.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression;
2 |
3 |
4 | import javafx.scene.control.cell.PropertyValueFactory;
5 | import javafx.stage.Stage;
6 |
7 | /**
8 | * @Author jack
9 | * @Date:2019/7/24 11:55
10 | */
11 | public class ExpressionParserTest {
12 |
13 | }
--------------------------------------------------------------------------------
/src/test/java/cn/edu/scau/biubiusuisui/expression/data/ExpressionParserTest.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.expression.data;
2 |
3 | import cn.edu.scau.biubiusuisui.annotation.FXValue;
4 | import org.junit.Before;
5 | import org.junit.Test;
6 |
7 | import java.lang.reflect.Method;
8 |
9 | import static org.junit.Assert.*;
10 |
11 | /**
12 | * @Author jack
13 | * @Date:2019/7/27 3:13
14 | */
15 | public class ExpressionParserTest {
16 |
17 | private ExpressionParser expressionParser;
18 | @Before
19 | public void init(){
20 | expressionParser = new ExpressionParser(null);
21 | }
22 | @Test
23 | public void parse() {
24 | }
25 |
26 | @Test
27 | public void getArgs() throws NoSuchMethodException {
28 |
29 | }
30 | }
--------------------------------------------------------------------------------
/src/test/java/cn/edu/scau/biubiusuisui/factory/FXEntityFactoryTest.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.factory;
2 |
3 | import org.junit.Test;
4 |
5 | /**
6 | * @Author jack
7 | * @Date:2019/6/28 1:32
8 | */
9 | public class FXEntityFactoryTest {
10 |
11 | @Test
12 | public void getClassProperty() {
13 | // Student student = new Student();
14 | // student.setName("Jack");
15 | // try {
16 | // Map entityProperty = FXEntityFactory.processFXEntityProxy(student,null);
17 | // entityProperty.forEach((k,v)->{
18 | // System.out.println("key" + k +" v" + v);
19 | // });
20 | // } catch (IllegalAccessException e) {
21 | // e.printStackTrace();
22 | // }
23 |
24 | }
25 |
26 | @Test
27 | public void getInstance() {
28 | }
29 |
30 | @Test
31 | public void createJavaBeanProxy() {
32 |
33 | }
34 |
35 | @Test
36 | public void createJavaBeanProxy2() throws InstantiationException, IllegalAccessException {
37 | // Student student1 = (Student) FXEntityFactory.warpFxBean(Student.class);
38 | // System.out.println(student1);
39 | // FXPlusContext.getProxyByBeanObject(student1).getStringPropertyMap().forEach((k, v)->{
40 | // System.out.println("k " +k +"v" + v);
41 | // });
42 | // student1.setName("Jack");
43 | }
44 |
45 | @Test
46 | public void getEntityProperty() {
47 | }
48 | }
--------------------------------------------------------------------------------
/src/test/java/cn/edu/scau/biubiusuisui/utils/ClassUtilsTest.java:
--------------------------------------------------------------------------------
1 | package cn.edu.scau.biubiusuisui.utils;
2 |
3 |
4 | import java.io.IOException;
5 | import java.util.ArrayList;
6 | import java.util.Enumeration;
7 | import java.util.List;
8 | import java.util.jar.JarEntry;
9 | import java.util.jar.JarFile;
10 |
11 | public class ClassUtilsTest {
12 |
13 | public static void main(String[] args) {
14 | JarFile jarFile = null;
15 | try {
16 | jarFile = new JarFile("/Users/Jack/test.jar");
17 | } catch (IOException e) {
18 | e.printStackTrace();
19 | }
20 | Enumeration entrys = jarFile.entries();
21 | List classNames = new ArrayList<>();
22 | while (entrys.hasMoreElements()) {
23 | JarEntry jarEntry = entrys.nextElement();
24 | classNames.add(jarEntry.getName());
25 | }
26 | classNames.forEach(System.out::println);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------