Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a542c6caa | ||
|
|
1eb81ed37e | ||
|
|
3c3c556a19 | ||
|
|
6d5f97767d | ||
|
|
8c264a6100 | ||
|
|
c0684c7501 | ||
|
|
5cc7e57a88 | ||
|
|
2596af27ed | ||
|
|
4c1cc13601 | ||
|
|
f731b73207 | ||
|
|
c74ea3039f | ||
|
|
bc421b87b9 | ||
|
|
dcf02d6565 | ||
|
|
986f43ad6d | ||
|
|
cacb8b154b | ||
|
|
7b5e56d6f7 | ||
|
|
48889c54a9 | ||
|
|
f715cced3d | ||
|
|
fcf17ac57f | ||
|
|
34ae7db92f | ||
|
|
6fcd94e94b | ||
|
|
7ce75c9206 | ||
|
|
deb5e7f3e8 | ||
|
|
bb53425b43 | ||
|
|
573f3e1c70 | ||
|
|
40b81fa8d8 | ||
|
|
5cd92e9e8f | ||
|
|
efd34fb512 | ||
|
|
059c5c8193 | ||
|
|
953c6b16ad | ||
|
|
a50ec834d1 |
12
.idea/artifacts/JavaFx_Plus_jar.xml
generated
12
.idea/artifacts/JavaFx_Plus_jar.xml
generated
@@ -1,12 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="JavaFx-Plus:jar">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/JavaFx_Plus_jar</output-path>
|
||||
<root id="archive" name="JavaFx-Plus.jar">
|
||||
<element id="module-output" name="JavaFx-Plus" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2.jar" path-in-jar="/" />
|
||||
<element id="library" level="project" name="Maven: cglib:cglib:3.1" />
|
||||
<element id="library" level="project" name="Maven: org.ow2.asm:asm:4.2" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
16
.idea/compiler.xml
generated
16
.idea/compiler.xml
generated
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="JavaFx-Plus" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="JavaFx-Plus" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/libraries/Maven__cglib_cglib_3_1.xml
generated
13
.idea/libraries/Maven__cglib_cglib_3_1.xml
generated
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: cglib:cglib:3.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
13
.idea/libraries/Maven__junit_junit_4_11.xml
generated
13
.idea/libraries/Maven__junit_junit_4_11.xml
generated
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: junit:junit:4.11">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: org.hamcrest:hamcrest-core:1.3">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
13
.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml
generated
13
.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml
generated
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: org.ow2.asm:asm:4.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
13
.idea/misc.xml
generated
13
.idea/misc.xml
generated
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/JavaFx-Plus.iml" filepath="$PROJECT_DIR$/JavaFx-Plus.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
124
.idea/uiDesigner.xml
generated
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
1409
.idea/workspace.xml
generated
1409
.idea/workspace.xml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Biubiu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
599
README.md
599
README.md
@@ -1,81 +1,75 @@
|
||||
# JavaFX-Plus
|
||||
|
||||
- [JavaFX-Plus](#javafx-plus)
|
||||
* [前言](#前言)
|
||||
+ [开发进程](#开发进程)
|
||||
* [Maven仓库地址](#Maven仓库地址)
|
||||
* [框架功能描述](#框架功能描述)
|
||||
+ [模块化开发](#模块化开发)
|
||||
- [介绍](#介绍)
|
||||
- [如何创建模块](#如何创建模块)
|
||||
- [scenebuilder中导入刚刚生成的上面的控件](#scenebuilder中导入刚刚生成的上面的控件)
|
||||
+ [与Spring的融合](#与Spring的融合)
|
||||
+ [信号机制](#信号机制)
|
||||
+ [JavaBean与JavaFXBean的转换](#JavaBean与JavaFXBean的转换)
|
||||
+ [可拔插功能](#可拔插功能)
|
||||
+ [数据绑定](#数据绑定)
|
||||
- [Bean和View绑定](#Bean和View绑定)
|
||||
- [View和View绑定](#View和View绑定)
|
||||
- [函数表达式绑定](#函数表达式绑定)
|
||||
+ [多窗口切换功能](#多窗口切换功能)
|
||||
* [框架的使用](#框架的使用)
|
||||
+ [内置注解](#内置注解)
|
||||
+ [两个工厂和一个context](#两个工厂和一个context)
|
||||
* [创建第一个程序](#创建第一个程序)
|
||||
|
||||
|
||||
**1.1 前言**
|
||||
|
||||
**1.1.1 为什么要出这个框架**
|
||||
## 前言
|
||||
|
||||

|
||||
这个框架不是UI美化框架,为了简化javaFX项目开发、为了减少项目之间组件耦合而打造的框架。目前框架主要功能如下图所示:
|
||||
|
||||
记得从刚开始学习Java就开始接触JavaFX,从一开始的代码编写图形到后来通过FXML编写界面,一步步的学习之中逐渐领悟JavaFX的强大与灵活,我对JavaFX这门生不逢时的技术有了独特的感情,可以说JavaFX的强大不被许多人了解。
|
||||

|
||||
### 开发进程
|
||||
2019年11月25日起项目暂停更新,将会下次发布将会升级为2.0版本,到时候将会提供更多数据绑定操作,以及优化性能。
|
||||
|
||||
随着不断深入,我也渐渐发现JavaFx的设计思想在很多时候是无法满足当代程序开发思想的,并且一些功能并不是特别容易被使用,所以特定开发了一套简化开发JavaFx开发过程的框架供大家使用,希望能够简化大家的操作将精力专注于主要业务。
|
||||
- [x] 模块化
|
||||
- [x] 与Spring的融合
|
||||
- [x] 信号机制
|
||||
- [x] JavaBean和JavaFXBean的转换
|
||||
- [x] 可拔插功能(窗口拖动等功能)
|
||||
- [x] 数据绑定
|
||||
- [x] Bean和View的绑定
|
||||
- [x] View和View的绑定
|
||||
- [x] 函数表达式绑定
|
||||
- [x] 多窗口切换功能
|
||||
- [ ] 事件注解绑定
|
||||
- [ ] 数据校验
|
||||
- [ ] 键盘事件绑定
|
||||
- [ ] 优化性能
|
||||
|
||||
下面是我在开发过程中遇到的一些问题,我也针对这些问题做了简化操作。
|
||||
## Maven仓库地址
|
||||
```xml
|
||||
|
||||
**1.1.2 FX缺点1 : 单一控制器臃肿**
|
||||
<dependency>
|
||||
<groupId>com.gitee.Biubiuyuyu</groupId>
|
||||
<artifactId>javafx-plus</artifactId>
|
||||
<version>1.0.0-RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
JavaFX中似乎都是一个Controller把所有的操作和控件囊括在里面,一个Controller有几百行甚至几千行,程序虽然不用考虑模块之间调用问题了,但是这几千行的代码却很难被管理。
|
||||
|
||||

|
||||
|
||||
图1 臃肿的controller
|
||||
|
||||
**1.1.3 FX缺点2 : 控制类控制能力弱**
|
||||
|
||||
JavaFX启动的Stage和Controller之间总是隔着远远的距离,并且由于Controller是由JavaFX注入生成的,所以很多非Controller的东西与Controller交流,导致了不得不得使用静态方法或者静态成员这类小技巧来实现交流,导致代码变"丑"
|
||||
|
||||
**1.1.4 FX缺点3 : JavaBean无法使用Property**
|
||||
|
||||
JavaFX的设计哲学是所有的JavaBean的属性都是property类型的,可是很多时候我们的JavaBean都是String,Integer这类基本类型,要重新修改类属性所带来的问题就足以让人让而却步了。
|
||||
|
||||
```java
|
||||
//普通JavaBean对象
|
||||
public class Student {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private String gender;
|
||||
|
||||
private String code;
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 框架功能描述
|
||||
|
||||
```java
|
||||
//简单的JavaFX bean对象
|
||||
class Bill {
|
||||
// 定义一个变量存储属性
|
||||
private DoubleProperty amountDue = new SimpleDoubleProperty();
|
||||
### 模块化开发
|
||||
|
||||
// 定义一个getter方法获取属性值
|
||||
public final double getAmountDue(){return amountDue.get();}
|
||||
#### 介绍
|
||||
|
||||
// 定义一个setter方法设置属性值
|
||||
public final void setAmountDue(double value){amountDue.set(value);}
|
||||
在Java开发过程中很多界面是相似或者重复的,如果能够将这些界面打包成为一个自定义控件,并且通过Scenebuilder拖动就能产生一个控件那将会大大提高我们的开发效率。所以我们提出将不同区域划分为不同的子模块,已达到减少耦合和加速并行开发。一般我们经常把界面分为顶部工具栏,左边导航栏,右侧的内容栏,如果全部内容都写在一个Controller那么将会导致十分臃肿,我们希望将不同的区域划分开来分而治之。
|
||||
|
||||
// 定义一个getter方法获取属性本身
|
||||
public DoubleProperty amountDueProperty() {return amountDue;}
|
||||
#### 如何创建模块
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
**1.1.5 总结**
|
||||
|
||||
为了解决上述问题,我开发了一套增强JavaFX功能的框架,来起到简化JavaFX开发过程的问题。
|
||||
|
||||
**1.2 特色一:模块化开发**
|
||||
|
||||
1.2.1 介绍
|
||||
|
||||
在Java开发过程中很多界面是相似或者重复的,如果能够将这些界面打包成为一个自定义控件,并且通过Scenebuilder拖动就能产生一个控件那将会大大提高我们的开发效率。所以我们提出将不同区域划分为不同的子模块,已达到减少耦合和加速并行开发。一般我们经常把界面分为顶部工具栏,左边导航栏,右侧的内容栏,如果全部内容都写在一个Controller那么将会导致十分臃肿,我们希望将不同的区域划分开来分而治之。
|
||||
|
||||
1.2.2 如何创建模块
|
||||
|
||||
只要新建一个类继承自FXBaseController,而FXBaseController是继承于Pane,这就是JavaFX-Plus的设计思想之一切皆为Pane。在类上标上FXController注解,提供FXML文件的地址。如果设置为FXWindow那么将会把这个Controller以单独的Window显示,这里仅仅几句代码就实现了一个简单的窗口程序。
|
||||
只要新建一个类继承自FXBaseController,而FXBaseController是继承于Pane,这就是JavaFX-Plus的设计思想之一切皆为Pane。在类上标上FXController注解,提供FXML文件的地址。如果设置为FXWindow那么将会把这个Controller以单独的Window显示,这里仅仅几句代码就实现了一个简单的窗口程序。
|
||||
|
||||

|
||||
|
||||
@@ -85,56 +79,112 @@ class Bill {
|
||||
|
||||
图3 显示结果
|
||||
|
||||
1.2.3 scenebuilder中导入刚刚生成的上面的控件
|
||||
#### scenebuilder中导入刚刚生成的上面的控件
|
||||
|
||||

|
||||
|
||||
图4 模块化操作
|
||||
|
||||
**1.3 特色2 :信号机制**
|
||||
|
||||
有两个主要标签一个是FXSender,这个标签作用在方法上,标记这个方法为信号发射方法。可以通过设置name修改这个信号发射方法的名称,默认是函数名字。
|
||||
|
||||
发射信号会被订阅这个发射函数的所有FXReceiver接收,并且发射函数的返回值会作为参数传进这个函数之中。而且这种发送和接受关系是全局的,只要是注册了的Controller都可以进行接受,不局限于同一个Controller。
|
||||
### 与Spring的融合
|
||||
|
||||
我们通过一个简单的代码来理解一下。
|
||||
可以快速支持Spring和这个框架的融合,只需要一行代码,就可将实例的生成控制转交给容器管理。
|
||||
代码如下:
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
|
||||
@FXML
|
||||
Button btn;
|
||||
|
||||
@FXML
|
||||
Label label;
|
||||
/**
|
||||
鼠标之后,系统通过会发射信号,调用所有订阅这个发射信号函数的方法响应信号
|
||||
*/
|
||||
@FXML //绑定鼠标点击事件
|
||||
@FXSender //标注为信号发射函数
|
||||
public String send(){
|
||||
System.out.println("before sending"); //输出 before sending
|
||||
return "sending msg";
|
||||
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.springDemo"})
|
||||
public class SpringDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //启动spring
|
||||
FXPlusApplication.start(SpringDemo.class, new BeanBuilder() {
|
||||
@Override
|
||||
public Object getBean(Class type) {
|
||||
return context.getBean(type); //接管FXPlus属性的创建
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
接受者必须指定要订阅的发送者类名+方法名
|
||||
而且发送函数的返回值会注入到接受函数的参数中
|
||||
*/
|
||||
@FXReceiver(name = "MainController:send")
|
||||
public void read(String msg){
|
||||
System.out.println("read " + msg); //输出 read sending msg
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
**1.4 特色3 :JavaBean 和 JavaFxBean**
|
||||
|
||||
一般我们写的JavaBean都是基本类型的,但是JavaFXBean的设计哲学是这些属性都应该是JavaFX定义的Property类型,这十分不利于我们的开发,我们如何在不修改JavaBean的条件下,使用到JavaFX的Property的一些优良方法呢?答案是我们通过反射获得基本类型对应的Property(目前仅限于boolean,double,integer,long,string,float等基本类型,不支持List等封装对象。)
|
||||
|
||||
### 信号机制
|
||||
|
||||
有两个主要标签一个是FXSender,这个标签作用在函数上,标记这个方法为信号发射函数。可以通过设置name修改这个信号发射函数的名称,默认是函数名字。
|
||||
|
||||
发射信号会被订阅了这个发射函数的所有FXReceiver接收,并且发射函数的返回值会作为参数传进这个函数之中。而且这种发送和接收关系是全局的,只要是注册了的Controller都可以进行接收,不局限于同一个Controller。
|
||||
|
||||
我们通过一个简单的代码来理解一下,主要实现自定义组件导航栏TopBar,主界面中包含该组件,当用户点击导航栏某些按钮时,能返回主界面相关信息。fxml文件详见resources下的mqDemo文件夹。
|
||||
|
||||
1. 利用JavaFX的模块化,我们设计一个简单的导航栏:
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/topBar.fxml")
|
||||
public class TopBarController extends FXBaseController {
|
||||
@FXML
|
||||
public void indexClick() {
|
||||
sendToMain("点击[首页]");
|
||||
}
|
||||
@FXML
|
||||
public void scoreClick() {
|
||||
sendToMain("点击[积分中心]");
|
||||
}
|
||||
@FXML
|
||||
public void questionClick() {
|
||||
sendToMain("点击[问答中心]");
|
||||
}
|
||||
@FXML
|
||||
public void selfClick() {
|
||||
sendToMain("点击[个人中心]");
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统会通过发射信号,调用所有订阅这个发射信号函数的方法,从而响应信号
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
@FXSender //标注为信号发射函数
|
||||
public String sendToMain(String msg) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
2. 再设计一个主界面,里面包含导航栏
|
||||
|
||||
```java
|
||||
@FXController(path = "mqDemo/main.fxml")
|
||||
@FXWindow(mainStage = true, title = "MQDemo")
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
private TextArea outTA;
|
||||
|
||||
/**
|
||||
* 接收者必须指定要订阅的[发送者类名:方法名]
|
||||
* 发送函数的返回值会注入到接收函数的参数中
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
@FXReceiver(name = "TopBarController:sendToMain")
|
||||
public void handleTopBar(String msg) {
|
||||
// TODO: 2019/12/8
|
||||
// 处理导航栏的点击事件
|
||||
outTA.appendText(msg + "\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### JavaBean与JavaFXBean的转换
|
||||
|
||||
一般我们写的JavaBean都是基本类型的,但是JavaFXBean的设计哲学是这些属性都应该是JavaFX定义的Property类型,这十分不利于我们的开发,我们如何在不修改JavaBean的条件下,使用到JavaFX的Property的一些优良方法呢?答案是我们通过反射获得基本类型对应的Property(目前仅限于boolean,double,integer,long,string,float,List等基本类型,不支持封装对象。)
|
||||
|
||||

|
||||
|
||||
@@ -242,37 +292,338 @@ public class Student {
|
||||
|
||||
直接操作JavaBean类,就会通过动态绑定修改界面,不需要讲JavaBean转换为JavaFX Bean可以减少开发中的类型转换。
|
||||
|
||||
### 可拔插功能
|
||||
|
||||
在本框架中实现了窗口可拖动和窗口可伸缩,在Javafx中如果一个窗口隐藏了标题栏那么这个窗口也就没办法拖动和伸缩了,在JavaFX-Plus中你就不需有这种烦恼,只需要在@FXWindow中设置
|
||||
|
||||
```java
|
||||
@FXWindow(title = "demo1",dragable = true,style = StageStyle.UNDECORATED)
|
||||
```
|
||||
就可以让这个没有标题的窗口可以被拖动而且能拉伸(默认打开,可以关闭)
|
||||
|
||||

|
||||
|
||||
|
||||
**2 如何使用这个框架**
|
||||

|
||||
|
||||
2.1 了解内置注解
|
||||
### 数据绑定
|
||||
|
||||
| 名字 | 作用 | 参数 | 要求 |
|
||||
| ------------- | ------------------------------------------------------------ | --------------------------------------- | -------------------- |
|
||||
| @FXScan | 扫描@FXEntity和@FXController注解标记的类 | 要扫描的目录 | 默认当前目录之下所有 |
|
||||
| @FXController | 标记这个类为控件 | fxml文件地址 | 无 |
|
||||
| @FXWindow | 标记这个控件要以单独窗口显示 | title是窗口名字,也可以设置窗口长度宽度 | 无 |
|
||||
| @FXEntity | 标记JavaBean系统会自动识别@FXField然后包装JavaBean为JavaFXBean | 重命名 | |
|
||||
| @FXField | 代表这个属性要映射为Property属性 | | |
|
||||
| @FXSender | 信号发送者 | name可以重命名信号 | |
|
||||
| @FXReceiver | 信号接收函数 | name是订阅的发射者函数名 | 不可空 |
|
||||
与之相关的注解有`@FXBind`,注解在JavaFX控件的字段上面,标明该变量的绑定方式和绑定属性,类似于Vue中的界面绑定。目前已实现Bean和View的绑定、View和View的绑定、函数表达式的绑定
|
||||
|
||||
2.2 两个工厂和一个context
|
||||
#### Bean和View绑定
|
||||
如下面代码,通过FXBind将Student的姓名与文本框输入内容绑定,学生的密码和密码框输入框内容绑定,完全简化了数据传递操作,代码中完全没有出现界面数据传输到控制器代码。
|
||||
例子:
|
||||
|
||||
```java
|
||||
@FXData
|
||||
@FXBind(
|
||||
{
|
||||
"name=${usr.text}",
|
||||
"password=${psw.text}"
|
||||
}
|
||||
)
|
||||
Student student = new Student();
|
||||
|
||||
@FXML
|
||||
private PasswordField psw;
|
||||
|
||||
@FXML
|
||||
private Label pswMsg;
|
||||
|
||||
@FXML
|
||||
void login(ActionEvent event) {
|
||||
System.out.println("user:" + student.getName());
|
||||
System.out.println("psw:" + student.getPassword());
|
||||
if ("admin".equals(student.getName()) && "admin".equals(student.getPassword())) {
|
||||
System.out.println("Ok");
|
||||
} else {
|
||||
System.out.println("fail");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
如图所示:
|
||||

|
||||
|
||||
|
||||
|
||||
#### View和View绑定
|
||||
|
||||
```java
|
||||
@FXBind("text=${psw.text}")
|
||||
@FXML
|
||||
private Label pswMsg;//任何psw中的内容都会同步到pswMsg中
|
||||
```
|
||||
如图所示
|
||||

|
||||
|
||||
|
||||
|
||||
#### 函数表达式绑定
|
||||
|
||||
示例代码可见`cn.edu.scau.biubiusuisui.example.listDemo`和 `cn.edu.scau.biubiusuisui.actionDemo`,以下举actionDemo为例。
|
||||
|
||||
1. 使用方法
|
||||
|
||||
使用在界面Controller类中的JavaFX控件上,与以上两种绑定类似,以`${}`为外部标识,当该绑定属于函数表达式绑定时,需要在函数名前加`@`。
|
||||
|
||||
```java
|
||||
@FXBind("text=${@toUs(time.text)}") // 将Label中的text和toUs()函数的返回值绑定
|
||||
private Label us;
|
||||
```
|
||||
|
||||
2. 示例代码
|
||||
|
||||
如以下代码,实现简单的汇率转换器。
|
||||
|
||||
```java
|
||||
@FXController(path = "actionDemo/actionDemo.fxml")
|
||||
@FXWindow(title = "actionDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@FXBind("text=${@toUs(time.text)}") // 将Label中的text和toUs()函数的返回值绑定
|
||||
private Label us;
|
||||
|
||||
@FXML
|
||||
@FXBind("text=${@toJp(time.text)}")
|
||||
private Label jp;
|
||||
|
||||
@FXML
|
||||
@FXBind("text=${@toUk(time.text)}")
|
||||
private Label uk;
|
||||
|
||||
@FXML
|
||||
private TextField time;
|
||||
|
||||
public String toUs(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 0.1454;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
|
||||
public String toJp(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 15.797;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
|
||||
public String toUk(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 0.1174;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. 动态演示
|
||||
|
||||
如图所示:
|
||||
|
||||

|
||||
|
||||
### 多窗口切换功能
|
||||
|
||||
#### 介绍
|
||||
|
||||
在JavaFX中常常需要多个窗口之间进行切换,比如登录窗口,点击登录后跳转至登录成功/失败窗口,网上部分有关多窗口切换的JavaFX教程实现过程为:在Controller中是实现FXML绑定,并通过外部调用某个show方法来切换窗口。由于本框架已经将FXML绑定这一功能封装,故通过在Controller内部直接初始化Stage并设置参数这一方法并不现实。因此,在本框架中,编写StageController类对Controller进行管理。
|
||||
|
||||
#### 涉及到的注解
|
||||
|
||||
`@FXController`:标记于类上,用于绑定FXML文件,需要注意的是标记了`FXController`只能标记这是一个控件。
|
||||
|
||||
`@FXWindow`:标记于类上,标记这个Controller需要以窗口显示,只有需要以单独窗口显示时才会被重定向。
|
||||
|
||||
`@FXRedirect`:标记于函数上,标记该函数用于处理重定向。
|
||||
|
||||
#### 规定
|
||||
|
||||
本框架规定,当需要使用`@FXRedirect`标记函数处理重定向时,函数必须是返回String类型的函数,且返回已注册的Controller名,如需要重定向至登录成功界面,控制器为`SuccessController`,则需要写上`return "SuccessController"。
|
||||
|
||||
#### 使用方法
|
||||
|
||||
1. `FXRedirect`注解的使用如下:
|
||||
|
||||
```java
|
||||
@FXRedirect
|
||||
public String redirectToRegister() {
|
||||
return "RegisterController";
|
||||
}
|
||||
|
||||
@FXML
|
||||
@FXRedirect(close = false) //测试弹窗
|
||||
public String redirectToDialog() {
|
||||
return "DialogController";
|
||||
}
|
||||
```
|
||||
|
||||
close是标明是否需要关闭当前的窗口,默认为true,即默认当跳转另一个窗口时关闭当前窗口。
|
||||
|
||||
2. 创建程序初始界面Controller,此处举例为登录界面
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/login.fxml")
|
||||
@FXWindow(title = "redirectDemo", mainStage = true)
|
||||
public class LoginController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
|
||||
@FXML
|
||||
private PasswordField passwordPF;
|
||||
|
||||
@FXML
|
||||
public void registerClick() {
|
||||
System.out.println("点击注册.....");
|
||||
redirectToRegister();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirectToRegister() {
|
||||
return "RegisterController";
|
||||
}
|
||||
|
||||
@FXML
|
||||
@FXRedirect(close = false) //测试弹窗
|
||||
public String redirectToDialog() {
|
||||
return "DialogController";
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
3. 编写需要跳转的界面Controller,比如登录时,尚无账号跳转至注册界面和测试弹窗的Controller
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/register.fxml")
|
||||
@FXWindow(title = "register")
|
||||
public class RegisterController extends FXBaseController {
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
@FXML
|
||||
private TextField emailTF;
|
||||
@FXML
|
||||
private PasswordField passwordPF;
|
||||
|
||||
@FXML
|
||||
private PasswordField confirmPasswordPF;
|
||||
|
||||
@FXML
|
||||
public void registerClick() {
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void loginClick() {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirectToLogin() {
|
||||
return "LoginController";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@FXController(path = "redirectDemo/dialog.fxml")
|
||||
@FXWindow(title = "弹窗")
|
||||
public class DialogController extends FXBaseController {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 示例演示
|
||||
|
||||
本次示例源码已存于`cn.edu.scau.biubiusuisui.example.redirectDemo`,fxml文件于resources下的redirectDemo文件夹中。
|
||||
|
||||
1. 跳转至另一个窗口(关闭原窗口)
|
||||
|
||||

|
||||
|
||||
2. 弹窗形式弹出窗口(不关闭原窗口)
|
||||
|
||||

|
||||
|
||||
#### 不足之处
|
||||
|
||||
暂未实现携带数据的窗口跳转,目前只实现纯粹跳转到另一个Controller。
|
||||
|
||||
|
||||
|
||||
## 框架的使用
|
||||
### 内置注解
|
||||
|
||||
| 名字 | 作用 | 参数 | 要求 |
|
||||
| ------------- | ------------------------------------------------------------ | --------------------------------------- | ---------------------------------------- |
|
||||
| @FXData | 标明这个普通bean要装配成javafxBean | fx_id | 重新命名 |
|
||||
| @FXScan | 扫描@FXEntity和@FXController注解标记的类 | 要扫描的目录 | 默认当前目录之下所有 |
|
||||
| @FXController | 标记这个类为控件 | path:fxml文件地址 | 无 |
|
||||
| @FXWindow | 标记这个控件要以单独窗口显示 | title是窗口名字,也可以设置窗口长度宽度 | 无 |
|
||||
| @FXEntity | 标记JavaBean系统会自动识别@FXField然后包装JavaBean为JavaFXBean | 重命名 | |
|
||||
| @FXField | 代表这个属性要映射为Property属性 | | |
|
||||
| @FXSender | 信号发送者 | name:重命名信号 | |
|
||||
| @FXReceiver | 信号接收函数 | name:订阅的发射者函数名 | 不可空 |
|
||||
| @FXRedirect | 标记函数为重定向函数 | close:是否关闭当前窗口 | 返回值为某个使用了FXView注解的Controller |
|
||||
|
||||
### 两个工厂和一个context
|
||||
|
||||
1. 两个工厂
|
||||
|
||||
在JavaFX-Plus中所有Controller对象和FXEnity对象都必须通过工厂创建。
|
||||
|
||||
```
|
||||
student = (Student) FXEntityFactory.getInstance().createJavaBeanProxy(Student.class); //工厂产生一个学生
|
||||
```java
|
||||
student = (Student) FXEntityFactory.getInstance().wrapFxBean(Student.class); //工厂产生一个学生
|
||||
```
|
||||
|
||||
通过工厂创建JavaBean,在创建同时工厂会对JavaBean代理并且包装对应的Property属性。
|
||||
通过工厂创建JavaBean,在创建的同时,工厂会对JavaBean代理并且包装对应的Property属性。
|
||||
|
||||
```
|
||||
```java
|
||||
MainController mainController = (MainController)FXFactory.getFXController(MainController.class);
|
||||
```
|
||||
|
||||
2.3 第一个Demo如何使用框架创建第一个程序
|
||||
2. 一个context
|
||||
|
||||
存储所有用@FXController注解后的Controller和FXEntity的代理类。
|
||||
|
||||
```java
|
||||
public class FXPlusContext {
|
||||
|
||||
private FXPlusContext(){}
|
||||
|
||||
private static Map<String, List<FXBaseController>> controllerContext = new ConcurrentHashMap<>(); //FXController控制器注册表
|
||||
|
||||
private static Map<Object, FXEntityProxy> beanMap = new ConcurrentHashMap<>(); // Object注册为FXEntityObject
|
||||
|
||||
|
||||
public static void addController(FXBaseController fxBaseController){
|
||||
List<FXBaseController> controllers = controllerContext.get(fxBaseController.getName());
|
||||
if(controllers == null){
|
||||
controllers = new LinkedList<>();
|
||||
}
|
||||
controllers.add(fxBaseController);
|
||||
}
|
||||
|
||||
public static List<FXBaseController> getControllers(String key){
|
||||
return controllerContext.get(key);
|
||||
}
|
||||
|
||||
public static FXEntityProxy getProxyByBeanObject(Object object){
|
||||
return beanMap.get(object);
|
||||
}
|
||||
|
||||
public static void setProxyByBeanObject(Object object,FXEntityProxy fxEntityProxy){
|
||||
beanMap.put(object,fxEntityProxy);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 创建第一个程序
|
||||
|
||||
1. 主程序类。
|
||||
|
||||
```java
|
||||
@FXScan(base = {"cn.edu.scau.biubiusuisui.example"}) //会扫描带FXController和FXEntity的类进行初始化
|
||||
@@ -282,26 +633,21 @@ public class Demo extends Application {
|
||||
FXPlusApplication.start(Demo.class); //其他配置和JavaFX相同,这里要调用FXPlusAppcalition的start方法,开始FX-plus加强
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
接下来我们生成FXML和Controller
|
||||
2. 接下来我们生成FXML和Controller
|
||||
|
||||
```java
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
|
||||
@FXML
|
||||
private ResourceBundle resources;
|
||||
|
||||
@FXML
|
||||
private URL location;
|
||||
|
||||
@FXML
|
||||
private Button addBtn;
|
||||
|
||||
@FXML
|
||||
private Button delBtn;
|
||||
|
||||
@FXML
|
||||
private ListView<String> list;
|
||||
|
||||
@@ -319,9 +665,9 @@ public class MainController extends FXBaseController{
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
student = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
|
||||
Property property = FXPlusContext.getEntityPropertyByName(student, "list");
|
||||
list.itemsProperty().bind(property);
|
||||
student = (Student) FXEntityFactory.wrapFxBean(Student.class); // 从工厂中拿到将JavaBean转换得到的JavaFXBean
|
||||
Property listProperty = FXPlusContext.getEntityPropertyByName(student, "list");
|
||||
list.itemsProperty().bind(listProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,11 +675,10 @@ public class MainController extends FXBaseController{
|
||||
Studen类的定义如下
|
||||
|
||||
```java
|
||||
|
||||
@FXEntity
|
||||
public class Student {
|
||||
|
||||
@FXField
|
||||
@FXField //标记该属性是否被生成对应的Property
|
||||
private String name;
|
||||
|
||||
@FXField
|
||||
@@ -348,6 +693,8 @@ public class Student {
|
||||
}
|
||||
```
|
||||
|
||||
请注意,FXML文件的根标签必须为`<fx:root>`。
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
@@ -362,10 +709,10 @@ public class Student {
|
||||
<ListView fx:id="list" layoutX="42.0" layoutY="51.0" prefHeight="275.0" prefWidth="334.0" />
|
||||
</children>
|
||||
</fx:root>
|
||||
|
||||
```
|
||||
|
||||
从我们代码可以看出,我们很少有操作界面的操作,并且我们操作的对象都是基本类型的对象,这样的操作十分有利于我们将普通的项目转换为JavaFX项目,最终运行起来将会是这样
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
BIN
doc/JavaFX-Plus.png
Normal file
BIN
doc/JavaFX-Plus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 451 KiB |
BIN
doc/actionDemo/20191210-175409-actionDemo.gif
Normal file
BIN
doc/actionDemo/20191210-175409-actionDemo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 MiB |
BIN
doc/mqDemo/20191208-194336-signalshow.gif
Normal file
BIN
doc/mqDemo/20191208-194336-signalshow.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 MiB |
BIN
doc/redirectDemo/20191208-125511-not_close.gif
Normal file
BIN
doc/redirectDemo/20191208-125511-not_close.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 MiB |
BIN
doc/redirectDemo/20191208-125739-close.gif
Normal file
BIN
doc/redirectDemo/20191208-125739-close.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 MiB |
Binary file not shown.
133
pom.xml
133
pom.xml
@@ -3,13 +3,33 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<name>javafx-plus</name>
|
||||
<groupId>com.gitee.Biubiuyuyu</groupId>
|
||||
<artifactId>javafx-plus</artifactId>
|
||||
<version>1.0.0-RELEASE</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<groupId>groupId</groupId>
|
||||
<artifactId>JavaFx-Plus</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
<artifactId>oss-parent</artifactId>
|
||||
<version>7</version>
|
||||
</parent>
|
||||
|
||||
<description>this is javafx framework that simplified coding</description>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>javafx-plus</id>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>javafx-plus</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
@@ -22,8 +42,6 @@
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -31,12 +49,113 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgs>
|
||||
<!-- 过期的方法的警告-->
|
||||
<arg>-Xlint:deprecation</arg>
|
||||
</compilerArgs>
|
||||
<compilerArguments>
|
||||
<!-- 是否输出所有的编译信息(包括类的加载等)-->
|
||||
<!--<verbose />-->
|
||||
<!-- 解决maven命令编译报错,因为rt.jar 和jce.jar在jre的lib下面,不在jdk的lib下面,
|
||||
导致maven找不到(java7以后会出现这个问题),将这2个jar包拷贝到jdk的lib下面估计也好使-->
|
||||
<bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Source -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Javadoc -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.9.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<additionalparam>-Xdoclint:none</additionalparam>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- GPG -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU Lesser General Public License Version 3</name>
|
||||
<url>http://www.gnu.org/licenses/lgpl.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<tag>master</tag>
|
||||
<url>https://gitee.com/Biubiuyuyu/JavaFX-Plus.git</url>
|
||||
<connection>scm:git:https://gitee.com/Biubiuyuyu/JavaFX-Plus.git</connection>
|
||||
<developerConnection>scm:git:https://gitee.com/Biubiuyuyu/JavaFX-Plus.git</developerConnection>
|
||||
</scm>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Zhu zhanbiao</name>
|
||||
<email>747441355@qq.com</email>
|
||||
<organization>cn.edu.scau</organization>
|
||||
</developer>
|
||||
|
||||
<developer>
|
||||
<name>Yang suiyu</name>
|
||||
<email>498870048@qq.com</email>
|
||||
<organization>cn.edu.scau</organization>
|
||||
</developer>
|
||||
</developers>
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Inherited
|
||||
public @interface FXBind {
|
||||
String [] value();
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* This is use for marking A controller as FX-Plus Controller
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:34
|
||||
@Author jack
|
||||
@Date:2019/6/25 1:34
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:36
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Inherited
|
||||
public @interface FXData {
|
||||
String fx_id() default "";
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
@@ -11,5 +8,6 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface FXEntity {
|
||||
}
|
||||
|
||||
@@ -13,8 +13,12 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface FXField {
|
||||
boolean readOnly() default false;
|
||||
|
||||
String setter() default "";
|
||||
|
||||
String add() default "";
|
||||
|
||||
String delete() default "";
|
||||
|
||||
String edit() default "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 重定向的注解
|
||||
* @date 2019/12/3 12:53
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Inherited
|
||||
public @interface FXRedirect {
|
||||
boolean close() default true;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 3:06
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Inherited
|
||||
public @interface FXValue {
|
||||
String value();
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:36
|
||||
*/
|
||||
public @interface FXView {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package cn.edu.scau.biubiusuisui.annotation;
|
||||
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
@@ -12,5 +14,11 @@ import java.lang.annotation.*;
|
||||
public @interface FXWindow {
|
||||
double preWidth() default 0.0;
|
||||
double preHeight()default 0.0;
|
||||
double minWidth() default 0.0;
|
||||
double minHeight() default 0.0;
|
||||
boolean resizable() default false;
|
||||
boolean draggable() default false;
|
||||
boolean mainStage() default false;
|
||||
StageStyle style() default StageStyle.DECORATED;
|
||||
String title () ;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,56 @@
|
||||
package cn.edu.scau.biubiusuisui.config;
|
||||
|
||||
import javafx.fxml.*;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.expression.data.MyBeanAdapter;
|
||||
import cn.edu.scau.biubiusuisui.expression.data.MyExpressionValue;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXControllerFactory;
|
||||
import com.sun.javafx.beans.IDProperty;
|
||||
import com.sun.javafx.fxml.BeanAdapter;
|
||||
import com.sun.javafx.fxml.LoadListener;
|
||||
import com.sun.javafx.fxml.ParseTraceElement;
|
||||
import com.sun.javafx.fxml.PropertyNotFoundException;
|
||||
import com.sun.javafx.fxml.expression.Expression;
|
||||
import com.sun.javafx.fxml.expression.KeyPath;
|
||||
import com.sun.javafx.util.Logging;
|
||||
import javafx.beans.DefaultProperty;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.*;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.fxml.JavaFXBuilderFactory;
|
||||
import javafx.fxml.LoadException;
|
||||
import javafx.util.Builder;
|
||||
import javafx.util.BuilderFactory;
|
||||
import javafx.util.Callback;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ConstructorUtil;
|
||||
import sun.reflect.misc.MethodUtil;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
import javax.script.*;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.util.StreamReaderDelegate;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.AccessController;
|
||||
import java.security.AllPermission;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
@@ -27,80 +77,9 @@ import javafx.fxml.*;
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import com.sun.javafx.util.Logging;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.AllPermission;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javafx.beans.DefaultProperty;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.*;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.util.Builder;
|
||||
import javafx.util.BuilderFactory;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.util.StreamReaderDelegate;
|
||||
|
||||
import com.sun.javafx.beans.IDProperty;
|
||||
import com.sun.javafx.fxml.BeanAdapter;
|
||||
import com.sun.javafx.fxml.LoadListener;
|
||||
import com.sun.javafx.fxml.ParseTraceElement;
|
||||
import com.sun.javafx.fxml.PropertyNotFoundException;
|
||||
import com.sun.javafx.fxml.expression.Expression;
|
||||
import com.sun.javafx.fxml.expression.ExpressionValue;
|
||||
import com.sun.javafx.fxml.expression.KeyPath;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ConstructorUtil;
|
||||
import sun.reflect.misc.MethodUtil;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Loads an object hierarchy from an XML document.
|
||||
*
|
||||
* @since JavaFX 2.0
|
||||
*/
|
||||
public class FXMLLoaderPlus {
|
||||
@@ -109,6 +88,16 @@ public class FXMLLoaderPlus {
|
||||
private static final RuntimePermission GET_CLASSLOADER_PERMISSION =
|
||||
new RuntimePermission("getClassLoader");
|
||||
|
||||
private boolean show = false;
|
||||
|
||||
public boolean isShow() {
|
||||
return show;
|
||||
}
|
||||
|
||||
public void setShow(boolean show) {
|
||||
this.show = show;
|
||||
}
|
||||
|
||||
// Abstract base class for elements
|
||||
private abstract class Element {
|
||||
public final cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.Element parent;
|
||||
@@ -152,14 +141,14 @@ public class FXMLLoaderPlus {
|
||||
// to that (coerce to the appropriate type)
|
||||
List<Object> list;
|
||||
if (value instanceof List<?>) {
|
||||
list = (List<Object>)value;
|
||||
list = (List<Object>) value;
|
||||
} else {
|
||||
Class<?> type = value.getClass();
|
||||
DefaultProperty defaultProperty = type.getAnnotation(DefaultProperty.class);
|
||||
String defaultPropertyName = defaultProperty.value();
|
||||
|
||||
// Get the list value
|
||||
list = (List<Object>)getProperties().get(defaultPropertyName);
|
||||
list = (List<Object>) getProperties().get(defaultPropertyName);
|
||||
|
||||
// Coerce the element to the list item type
|
||||
if (!Map.class.isAssignableFrom(type)) {
|
||||
@@ -205,7 +194,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getProperties() {
|
||||
return (isTyped()) ? getValueAdapter() : (Map<String, Object>)value;
|
||||
return (isTyped()) ? getValueAdapter() : (Map<String, Object>) value;
|
||||
}
|
||||
|
||||
public void processStartElement() throws IOException {
|
||||
@@ -241,7 +230,7 @@ public class FXMLLoaderPlus {
|
||||
}
|
||||
|
||||
public void processAttribute(String prefix, String localName, String value)
|
||||
throws IOException{
|
||||
throws IOException {
|
||||
if (prefix == null) {
|
||||
// Add the attribute to the appropriate list
|
||||
if (localName.startsWith(EVENT_HANDLER_PREFIX)) {
|
||||
@@ -314,12 +303,12 @@ public class FXMLLoaderPlus {
|
||||
expression = Expression.valueOf(value);
|
||||
|
||||
// Create the binding
|
||||
BeanAdapter targetAdapter = new BeanAdapter(this.value);
|
||||
MyBeanAdapter targetAdapter = new MyBeanAdapter(this.value);
|
||||
ObservableValue<Object> propertyModel = targetAdapter.getPropertyModel(attribute.name);
|
||||
Class<?> type = targetAdapter.getType(attribute.name);
|
||||
|
||||
if (propertyModel instanceof Property<?>) {
|
||||
((Property<Object>) propertyModel).bind(new ExpressionValue(namespace, expression, type));
|
||||
((Property<Object>) propertyModel).bind(new MyExpressionValue(namespace, expression, type));
|
||||
}
|
||||
}
|
||||
} else if (isBidirectionalBindingExpression(value)) {
|
||||
@@ -454,7 +443,7 @@ public class FXMLLoaderPlus {
|
||||
* the array becomes relative to document location.
|
||||
*/
|
||||
private Object populateArrayFromString(
|
||||
Class<?>type,
|
||||
Class<?> type,
|
||||
String stringValue) throws LoadException {
|
||||
|
||||
Object propertyValue = null;
|
||||
@@ -485,22 +474,22 @@ public class FXMLLoaderPlus {
|
||||
String listPropertyName,
|
||||
String stringValue) throws LoadException {
|
||||
// Split the string and add the values to the list
|
||||
List<Object> list = (List<Object>)valueAdapter.get(listPropertyName);
|
||||
List<Object> list = (List<Object>) valueAdapter.get(listPropertyName);
|
||||
Type listType = valueAdapter.getGenericType(listPropertyName);
|
||||
Type itemType = (Class<?>)BeanAdapter.getGenericListItemType(listType);
|
||||
Type itemType = (Class<?>) BeanAdapter.getGenericListItemType(listType);
|
||||
|
||||
if (itemType instanceof ParameterizedType) {
|
||||
itemType = ((ParameterizedType)itemType).getRawType();
|
||||
itemType = ((ParameterizedType) itemType).getRawType();
|
||||
}
|
||||
|
||||
if (stringValue.length() > 0) {
|
||||
String[] values = stringValue.split(ARRAY_COMPONENT_DELIMITER);
|
||||
|
||||
for (String aValue: values) {
|
||||
for (String aValue : values) {
|
||||
aValue = aValue.trim();
|
||||
list.add(
|
||||
BeanAdapter.coerce(resolvePrefixedValue(aValue),
|
||||
(Class<?>)itemType));
|
||||
(Class<?>) itemType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,7 +507,7 @@ public class FXMLLoaderPlus {
|
||||
}
|
||||
}
|
||||
|
||||
private Object getExpressionObject(String handlerValue) throws LoadException{
|
||||
private Object getExpressionObject(String handlerValue) throws LoadException {
|
||||
if (handlerValue.startsWith(EXPRESSION_PREFIX)) {
|
||||
handlerValue = handlerValue.substring(EXPRESSION_PREFIX.length());
|
||||
|
||||
@@ -535,13 +524,13 @@ public class FXMLLoaderPlus {
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> T getExpressionObjectOfType(String handlerValue, Class<T> type) throws LoadException{
|
||||
private <T> T getExpressionObjectOfType(String handlerValue, Class<T> type) throws LoadException {
|
||||
Object expression = getExpressionObject(handlerValue);
|
||||
if (expression != null) {
|
||||
if (type.isInstance(expression)) {
|
||||
return (T) expression;
|
||||
}
|
||||
throw constructLoadException("Error resolving \"" + handlerValue +"\" expression."
|
||||
throw constructLoadException("Error resolving \"" + handlerValue + "\" expression."
|
||||
+ "Does not point to a " + type.getName());
|
||||
}
|
||||
return null;
|
||||
@@ -625,7 +614,7 @@ public class FXMLLoaderPlus {
|
||||
}
|
||||
|
||||
private void processObservableListHandler(String handlerValue) throws LoadException {
|
||||
ObservableList list = (ObservableList)value;
|
||||
ObservableList list = (ObservableList) value;
|
||||
if (handlerValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
|
||||
cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.MethodHandler handler = getControllerMethodHandle(handlerValue, cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.LIST_CHANGE_LISTENER);
|
||||
if (handler != null) {
|
||||
@@ -647,7 +636,7 @@ public class FXMLLoaderPlus {
|
||||
}
|
||||
|
||||
private void processObservableMapHandler(String handlerValue) throws LoadException {
|
||||
ObservableMap map = (ObservableMap)value;
|
||||
ObservableMap map = (ObservableMap) value;
|
||||
if (handlerValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
|
||||
cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.MethodHandler handler = getControllerMethodHandle(handlerValue, cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.MAP_CHANGE_LISTENER);
|
||||
if (handler != null) {
|
||||
@@ -669,7 +658,7 @@ public class FXMLLoaderPlus {
|
||||
}
|
||||
|
||||
private void processObservableSetHandler(String handlerValue) throws LoadException {
|
||||
ObservableSet set = (ObservableSet)value;
|
||||
ObservableSet set = (ObservableSet) value;
|
||||
if (handlerValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
|
||||
cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.MethodHandler handler = getControllerMethodHandle(handlerValue, cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.SET_CHANGE_LISTENER);
|
||||
if (handler != null) {
|
||||
@@ -747,7 +736,8 @@ public class FXMLLoaderPlus {
|
||||
super.processStartElement();
|
||||
|
||||
updateValue(constructValue());
|
||||
|
||||
//如果是FXBaseController对象需要注入fxml
|
||||
//因为如果只是单纯反射不具有FXPlus功能只有FX功能
|
||||
if (value instanceof Builder<?>) {
|
||||
processInstancePropertyAttributes();
|
||||
} else {
|
||||
@@ -761,8 +751,9 @@ public class FXMLLoaderPlus {
|
||||
super.processEndElement();
|
||||
|
||||
// Build the value, if necessary
|
||||
|
||||
if (value instanceof Builder<?>) {
|
||||
Builder<Object> builder = (Builder<Object>)value;
|
||||
Builder<Object> builder = (Builder<Object>) value;
|
||||
updateValue(builder.build());
|
||||
|
||||
processValue();
|
||||
@@ -804,10 +795,10 @@ public class FXMLLoaderPlus {
|
||||
Type itemType = BeanAdapter.getGenericListItemType(listType);
|
||||
|
||||
if (itemType instanceof ParameterizedType) {
|
||||
itemType = ((ParameterizedType)itemType).getRawType();
|
||||
itemType = ((ParameterizedType) itemType).getRawType();
|
||||
}
|
||||
|
||||
value = BeanAdapter.coerce(value, (Class<?>)itemType);
|
||||
value = BeanAdapter.coerce(value, (Class<?>) itemType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,7 +869,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
if (valueAdapter.isReadOnly(defaultPropertyName)
|
||||
&& List.class.isAssignableFrom(valueAdapter.getType(defaultPropertyName))) {
|
||||
List<Object> list = (List<Object>)valueAdapter.get(defaultPropertyName);
|
||||
List<Object> list = (List<Object>) valueAdapter.get(defaultPropertyName);
|
||||
list.add(getListValue(this, defaultPropertyName, text));
|
||||
} else {
|
||||
valueAdapter.put(defaultPropertyName, text.trim());
|
||||
@@ -890,7 +881,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
@Override
|
||||
public void processAttribute(String prefix, String localName, String value)
|
||||
throws IOException{
|
||||
throws IOException {
|
||||
if (prefix != null
|
||||
&& prefix.equals(FX_NAMESPACE_PREFIX)) {
|
||||
if (localName.equals(FX_ID_ATTRIBUTE)) {
|
||||
@@ -988,13 +979,13 @@ public class FXMLLoaderPlus {
|
||||
} else if (factory != null) {
|
||||
Method factoryMethod;
|
||||
try {
|
||||
factoryMethod = MethodUtil.getMethod(type, factory, new Class[] {});
|
||||
factoryMethod = MethodUtil.getMethod(type, factory, new Class[]{});
|
||||
} catch (NoSuchMethodException exception) {
|
||||
throw constructLoadException(exception);
|
||||
}
|
||||
|
||||
try {
|
||||
value = MethodUtil.invoke(factoryMethod, null, new Object [] {});
|
||||
value = MethodUtil.invoke(factoryMethod, null, new Object[]{});
|
||||
} catch (IllegalAccessException exception) {
|
||||
throw constructLoadException(exception);
|
||||
} catch (InvocationTargetException exception) {
|
||||
@@ -1009,12 +1000,17 @@ public class FXMLLoaderPlus {
|
||||
|
||||
if (value == null) {
|
||||
try {
|
||||
value = ReflectUtil.newInstance(type);
|
||||
if (FXBaseController.class.isAssignableFrom(type)) {
|
||||
value = FXControllerFactory.getFXController(type, fx_id);
|
||||
} else {
|
||||
value = type.newInstance();
|
||||
}
|
||||
} catch (InstantiationException exception) {
|
||||
throw constructLoadException(exception);
|
||||
} catch (IllegalAccessException exception) {
|
||||
throw constructLoadException(exception);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,6 +1159,9 @@ public class FXMLLoaderPlus {
|
||||
if (fields != null) {
|
||||
try {
|
||||
for (Field f : fields) {
|
||||
if(baseController!=null) {
|
||||
f.set(baseController, value);
|
||||
}
|
||||
f.set(controller, value);
|
||||
}
|
||||
} catch (IllegalAccessException exception) {
|
||||
@@ -1247,7 +1246,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
Constructor<?> constructor = null;
|
||||
try {
|
||||
constructor = ConstructorUtil.getConstructor(sourceValueType, new Class[] { sourceValueType });
|
||||
constructor = ConstructorUtil.getConstructor(sourceValueType, new Class[]{sourceValueType});
|
||||
} catch (NoSuchMethodException exception) {
|
||||
// No-op
|
||||
}
|
||||
@@ -1552,7 +1551,7 @@ public class FXMLLoaderPlus {
|
||||
try {
|
||||
scriptReader = new InputStreamReader(location.openStream(), charset);
|
||||
engine.eval(scriptReader);
|
||||
} catch(ScriptException exception) {
|
||||
} catch (ScriptException exception) {
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
if (scriptReader != null) {
|
||||
@@ -1572,7 +1571,7 @@ public class FXMLLoaderPlus {
|
||||
if (value != null && !staticLoad) {
|
||||
// Evaluate the script
|
||||
try {
|
||||
scriptEngine.eval((String)value);
|
||||
scriptEngine.eval((String) value);
|
||||
} catch (ScriptException exception) {
|
||||
System.err.println(exception.getMessage());
|
||||
}
|
||||
@@ -1629,7 +1628,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
@Override
|
||||
public void processAttribute(String prefix, String localName, String value)
|
||||
throws LoadException{
|
||||
throws LoadException {
|
||||
throw constructLoadException("Element does not support attributes.");
|
||||
}
|
||||
}
|
||||
@@ -1683,7 +1682,7 @@ public class FXMLLoaderPlus {
|
||||
// Execute the script
|
||||
try {
|
||||
scriptEngine.eval(script);
|
||||
} catch (ScriptException exception){
|
||||
} catch (ScriptException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
@@ -1771,7 +1770,7 @@ public class FXMLLoaderPlus {
|
||||
if (type != cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.PARAMETERLESS) {
|
||||
MethodUtil.invoke(method, controller, params);
|
||||
} else {
|
||||
MethodUtil.invoke(method, controller, new Object[] {});
|
||||
MethodUtil.invoke(method, controller, new Object[]{});
|
||||
}
|
||||
} catch (InvocationTargetException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
@@ -1788,11 +1787,21 @@ public class FXMLLoaderPlus {
|
||||
|
||||
private Object root = null;
|
||||
private Object controller = null;
|
||||
private Object baseController = null;
|
||||
|
||||
private BuilderFactory builderFactory;
|
||||
|
||||
private Callback<Class<?>, Object> controllerFactory;
|
||||
private Charset charset;
|
||||
|
||||
public Object getBaseController() {
|
||||
return baseController;
|
||||
}
|
||||
|
||||
public void setBaseController(Object baseController) {
|
||||
this.baseController = baseController;
|
||||
}
|
||||
|
||||
private final LinkedList<cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus> loaders;
|
||||
|
||||
private ClassLoader classLoader = null;
|
||||
@@ -1849,6 +1858,7 @@ public class FXMLLoaderPlus {
|
||||
public static final String FX_VALUE_ATTRIBUTE = "value";
|
||||
/**
|
||||
* The tag name of 'fx:constant'
|
||||
*
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public static final String FX_CONSTANT_ATTRIBUTE = "constant";
|
||||
@@ -1903,11 +1913,13 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* The tag name of <fx:root>
|
||||
*
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public static final String ROOT_TAG = "root";
|
||||
/**
|
||||
* <fx:root> 'type' attribute
|
||||
*
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public static final String ROOT_TYPE_ATTRIBUTE = "type";
|
||||
@@ -1944,6 +1956,7 @@ public class FXMLLoaderPlus {
|
||||
* Escape prefix for escaping special characters inside attribute values.
|
||||
* Serves as an escape for {@link #ESCAPE_PREFIX}, {@link #RELATIVE_PATH_PREFIX},
|
||||
* {@link #RESOURCE_KEY_PREFIX, {@link #EXPRESSION_PREFIX}, {@link #BI_DIRECTIONAL_BINDING_PREFIX}
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public static final String ESCAPE_PREFIX = "\\";
|
||||
@@ -1970,29 +1983,34 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* Prefix for bidirectional-binding expression resolution
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public static final String BI_DIRECTIONAL_BINDING_PREFIX = "#{";
|
||||
/**
|
||||
* Suffix for bidirectional-binding expression resolution
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public static final String BI_DIRECTIONAL_BINDING_SUFFIX = "}";
|
||||
|
||||
/**
|
||||
* Delimiter for arrays as values
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public static final String ARRAY_COMPONENT_DELIMITER = ",";
|
||||
|
||||
/**
|
||||
* A key for location URL in namespace map
|
||||
*
|
||||
* @see #getNamespace()
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public static final String LOCATION_KEY = "location";
|
||||
/**
|
||||
* A key for ResourceBundle in namespace map
|
||||
*
|
||||
* @see #getNamespace()
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
@@ -2004,6 +2022,7 @@ public class FXMLLoaderPlus {
|
||||
public static final String CONTROLLER_METHOD_PREFIX = "#";
|
||||
/**
|
||||
* A key for controller in namespace map
|
||||
*
|
||||
* @see #getNamespace()
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
@@ -2011,6 +2030,7 @@ public class FXMLLoaderPlus {
|
||||
/**
|
||||
* A suffix for controllers of included fxml files.
|
||||
* The full key is stored in namespace map.
|
||||
*
|
||||
* @see #getNamespace()
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
@@ -2018,18 +2038,21 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* The name of initialize method
|
||||
*
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public static final String INITIALIZE_METHOD_NAME = "initialize";
|
||||
|
||||
/**
|
||||
* Contains the current javafx version
|
||||
*
|
||||
* @since JavaFX 8.0
|
||||
*/
|
||||
public static final String JAVAFX_VERSION;
|
||||
|
||||
/**
|
||||
* Contains the current fx namepsace version
|
||||
*
|
||||
* @since JavaFX 8.0
|
||||
*/
|
||||
public static final String FX_NAMESPACE_VERSION = "1";
|
||||
@@ -2047,7 +2070,7 @@ public class FXMLLoaderPlus {
|
||||
* Creates a new FXMLLoader instance.
|
||||
*/
|
||||
public FXMLLoaderPlus() {
|
||||
this((URL)null);
|
||||
this((URL) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2093,7 +2116,7 @@ public class FXMLLoaderPlus {
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public FXMLLoaderPlus(URL location, ResourceBundle resources, BuilderFactory builderFactory,
|
||||
Callback<Class<?>, Object> controllerFactory) {
|
||||
Callback<Class<?>, Object> controllerFactory) {
|
||||
this(location, resources, builderFactory, controllerFactory, Charset.forName(DEFAULT_CHARSET_NAME));
|
||||
}
|
||||
|
||||
@@ -2117,7 +2140,7 @@ public class FXMLLoaderPlus {
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public FXMLLoaderPlus(URL location, ResourceBundle resources, BuilderFactory builderFactory,
|
||||
Callback<Class<?>, Object> controllerFactory, Charset charset) {
|
||||
Callback<Class<?>, Object> controllerFactory, Charset charset) {
|
||||
this(location, resources, builderFactory, controllerFactory, charset,
|
||||
new LinkedList<cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus>());
|
||||
}
|
||||
@@ -2134,8 +2157,8 @@ public class FXMLLoaderPlus {
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public FXMLLoaderPlus(URL location, ResourceBundle resources, BuilderFactory builderFactory,
|
||||
Callback<Class<?>, Object> controllerFactory, Charset charset,
|
||||
LinkedList<cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus> loaders) {
|
||||
Callback<Class<?>, Object> controllerFactory, Charset charset,
|
||||
LinkedList<cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus> loaders) {
|
||||
setLocation(location);
|
||||
setResources(resources);
|
||||
setBuilderFactory(builderFactory);
|
||||
@@ -2189,7 +2212,7 @@ public class FXMLLoaderPlus {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getRoot() {
|
||||
return (T)root;
|
||||
return (T) root;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2198,8 +2221,7 @@ public class FXMLLoaderPlus {
|
||||
* must be called prior to loading the document when using
|
||||
* <tt><fx:root></tt>.
|
||||
*
|
||||
* @param root
|
||||
* The root of the object hierarchy.
|
||||
* @param root The root of the object hierarchy.
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public void setRoot(Object root) {
|
||||
@@ -2209,7 +2231,7 @@ public class FXMLLoaderPlus {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus) {
|
||||
cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus loader = (cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus)obj;
|
||||
cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus loader = (cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus) obj;
|
||||
if (location == null || loader.location == null) {
|
||||
return loader.location == location;
|
||||
}
|
||||
@@ -2236,7 +2258,7 @@ public class FXMLLoaderPlus {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getController() {
|
||||
return (T)controller;
|
||||
return (T) controller;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2246,8 +2268,7 @@ public class FXMLLoaderPlus {
|
||||
* controller event handlers when an <tt>fx:controller</tt> attribute is not
|
||||
* specified in the document.
|
||||
*
|
||||
* @param controller
|
||||
* The controller to associate with the root object.
|
||||
* @param controller The controller to associate with the root object.
|
||||
* @since JavaFX 2.2
|
||||
*/
|
||||
public void setController(Object controller) {
|
||||
@@ -2280,6 +2301,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* Returns the controller cn.edu.scau.biubiusuisui.factory used by this serializer.
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public Callback<Class<?>, Object> getControllerFactory() {
|
||||
@@ -2319,6 +2341,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* Returns the classloader used by this serializer.
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
@@ -2365,7 +2388,6 @@ public class FXMLLoaderPlus {
|
||||
* Sets the static load flag.
|
||||
*
|
||||
* @param staticLoad
|
||||
*
|
||||
* @treatAsPrivate
|
||||
* @deprecated
|
||||
*/
|
||||
@@ -2389,7 +2411,6 @@ public class FXMLLoaderPlus {
|
||||
* Sets this loader's load listener.
|
||||
*
|
||||
* @param loadListener
|
||||
*
|
||||
* @treatAsPrivate
|
||||
* @deprecated
|
||||
*/
|
||||
@@ -2403,8 +2424,7 @@ public class FXMLLoaderPlus {
|
||||
* the document will be loaded must have been set by a prior call to
|
||||
* {@link #setLocation(URL)}.
|
||||
*
|
||||
* @return
|
||||
* The loaded object hierarchy.
|
||||
* @return The loaded object hierarchy.
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
@@ -2417,11 +2437,8 @@ public class FXMLLoaderPlus {
|
||||
/**
|
||||
* Loads an object hierarchy from a FXML document.
|
||||
*
|
||||
* @param inputStream
|
||||
* An input stream containing the FXML data to load.
|
||||
*
|
||||
* @return
|
||||
* The loaded object hierarchy.
|
||||
* @param inputStream An input stream containing the FXML data to load.
|
||||
* @return The loaded object hierarchy.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public <T> T load(InputStream inputStream) throws IOException {
|
||||
@@ -2451,7 +2468,7 @@ public class FXMLLoaderPlus {
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "dep-ann", "unchecked" })
|
||||
@SuppressWarnings({"dep-ann", "unchecked"})
|
||||
private <T> T loadImpl(InputStream inputStream,
|
||||
Class<?> callerClass) throws IOException {
|
||||
if (inputStream == null) {
|
||||
@@ -2548,30 +2565,32 @@ public class FXMLLoaderPlus {
|
||||
|
||||
if (controller != null) {
|
||||
if (controller instanceof Initializable) {
|
||||
((Initializable)controller).initialize(location, resources);
|
||||
((Initializable) controller).initialize(location, resources);
|
||||
} else {
|
||||
// Inject controller fields
|
||||
Map<String, List<Field>> controllerFields =
|
||||
controllerAccessor.getControllerFields();
|
||||
if (!show) {
|
||||
Map<String, List<Field>> controllerFields =
|
||||
controllerAccessor.getControllerFields();
|
||||
|
||||
injectFields(LOCATION_KEY, location);
|
||||
injectFields(LOCATION_KEY, location);
|
||||
|
||||
injectFields(RESOURCES_KEY, resources);
|
||||
injectFields(RESOURCES_KEY, resources);
|
||||
|
||||
// Initialize the controller
|
||||
Method initializeMethod = controllerAccessor
|
||||
.getControllerMethods()
|
||||
.get(cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.PARAMETERLESS)
|
||||
.get(INITIALIZE_METHOD_NAME);
|
||||
// Initialize the controller
|
||||
Method initializeMethod = controllerAccessor
|
||||
.getControllerMethods()
|
||||
.get(cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.PARAMETERLESS)
|
||||
.get(INITIALIZE_METHOD_NAME);
|
||||
|
||||
if (initializeMethod != null) {
|
||||
try {
|
||||
MethodUtil.invoke(initializeMethod, controller, new Object [] {});
|
||||
} catch (IllegalAccessException exception) {
|
||||
// TODO Throw when Initializable is deprecated/removed
|
||||
// throw constructLoadException(cn.edu.scau.biubiusuisui.exception);
|
||||
} catch (InvocationTargetException exception) {
|
||||
throw constructLoadException(exception);
|
||||
if (initializeMethod != null) {
|
||||
try {
|
||||
MethodUtil.invoke(initializeMethod, controller, new Object[]{});
|
||||
} catch (IllegalAccessException exception) {
|
||||
// TODO Throw when Initializable is deprecated/removed
|
||||
// throw constructLoadException(cn.edu.scau.biubiusuisui.exception);
|
||||
} catch (InvocationTargetException exception) {
|
||||
throw constructLoadException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2588,7 +2607,7 @@ public class FXMLLoaderPlus {
|
||||
xmlStreamReader = null;
|
||||
}
|
||||
|
||||
return (T)root;
|
||||
return (T) root;
|
||||
}
|
||||
|
||||
private void clearImports() {
|
||||
@@ -2596,7 +2615,7 @@ public class FXMLLoaderPlus {
|
||||
classes.clear();
|
||||
}
|
||||
|
||||
private LoadException constructLoadException(String message){
|
||||
private LoadException constructLoadException(String message) {
|
||||
return new LoadException(message + constructFXMLTrace());
|
||||
}
|
||||
|
||||
@@ -2604,7 +2623,7 @@ public class FXMLLoaderPlus {
|
||||
return new LoadException(constructFXMLTrace(), cause);
|
||||
}
|
||||
|
||||
private LoadException constructLoadException(String message, Throwable cause){
|
||||
private LoadException constructLoadException(String message, Throwable cause) {
|
||||
return new LoadException(message + constructFXMLTrace(), cause);
|
||||
}
|
||||
|
||||
@@ -2628,8 +2647,8 @@ public class FXMLLoaderPlus {
|
||||
* Returns the current line number.
|
||||
*
|
||||
* @treatAsPrivate
|
||||
* @deprecated
|
||||
* @since JavaFX 2.2
|
||||
* @deprecated
|
||||
*/
|
||||
public int impl_getLineNumber() {
|
||||
return xmlStreamReader.getLocation().getLineNumber();
|
||||
@@ -2639,8 +2658,8 @@ public class FXMLLoaderPlus {
|
||||
* Returns the current parse trace.
|
||||
*
|
||||
* @treatAsPrivate
|
||||
* @deprecated
|
||||
* @since JavaFX 2.1
|
||||
* @deprecated
|
||||
*/
|
||||
// SB-dependency: RT-21475 has been filed to track this
|
||||
public ParseTraceElement[] impl_getParseTrace() {
|
||||
@@ -2921,7 +2940,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
private static enum SupportedType {
|
||||
PARAMETERLESS {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 0;
|
||||
@@ -2929,7 +2947,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
},
|
||||
EVENT {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 1 &&
|
||||
@@ -2938,7 +2955,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
},
|
||||
LIST_CHANGE_LISTENER {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 1 &&
|
||||
@@ -2947,7 +2963,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
},
|
||||
MAP_CHANGE_LISTENER {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 1 &&
|
||||
@@ -2956,7 +2971,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
},
|
||||
SET_CHANGE_LISTENER {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 1 &&
|
||||
@@ -2965,7 +2979,6 @@ public class FXMLLoaderPlus {
|
||||
|
||||
},
|
||||
PROPERTY_CHANGE_LISTENER {
|
||||
|
||||
@Override
|
||||
protected boolean methodIsOfType(Method m) {
|
||||
return m.getParameterTypes().length == 3 &&
|
||||
@@ -3001,9 +3014,7 @@ public class FXMLLoaderPlus {
|
||||
*
|
||||
* @param packageName
|
||||
* @param className
|
||||
*
|
||||
* @deprecated
|
||||
* This method now delegates to {@link #getDefaultClassLoader()}.
|
||||
* @deprecated This method now delegates to {@link #getDefaultClassLoader()}.
|
||||
*/
|
||||
public static Class<?> loadType(String packageName, String className) throws ClassNotFoundException {
|
||||
return loadType(packageName + "." + className.replace('.', '$'));
|
||||
@@ -3013,9 +3024,7 @@ public class FXMLLoaderPlus {
|
||||
* Loads a type using the default class loader.
|
||||
*
|
||||
* @param className
|
||||
*
|
||||
* @deprecated
|
||||
* This method now delegates to {@link #getDefaultClassLoader()}.
|
||||
* @deprecated This method now delegates to {@link #getDefaultClassLoader()}.
|
||||
*/
|
||||
public static Class<?> loadType(String className) throws ClassNotFoundException {
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
@@ -3060,6 +3069,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* Returns the default class loader.
|
||||
*
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
@@ -3074,8 +3084,7 @@ public class FXMLLoaderPlus {
|
||||
/**
|
||||
* Sets the default class loader.
|
||||
*
|
||||
* @param defaultClassLoader
|
||||
* The default class loader to use when loading classes.
|
||||
* @param defaultClassLoader The default class loader to use when loading classes.
|
||||
* @since JavaFX 2.1
|
||||
*/
|
||||
public static void setDefaultClassLoader(ClassLoader defaultClassLoader) {
|
||||
@@ -3124,7 +3133,7 @@ public class FXMLLoaderPlus {
|
||||
|
||||
private static <T> T loadImpl(URL location, ResourceBundle resources,
|
||||
Class<?> callerClass) throws IOException {
|
||||
return loadImpl(location, resources, null,
|
||||
return loadImpl(location, resources, null,
|
||||
callerClass);
|
||||
}
|
||||
|
||||
@@ -3219,10 +3228,11 @@ public class FXMLLoaderPlus {
|
||||
|
||||
/**
|
||||
* Utility method for comparing two JavaFX version strings (such as 2.2.5, 8.0.0-ea)
|
||||
*
|
||||
* @param rtVer String representation of JavaFX runtime version, including - or _ appendix
|
||||
* @param nsVer String representation of JavaFX version to compare against runtime version
|
||||
* @return number < 0 if runtime version is lower, 0 when both versions are the same,
|
||||
* number > 0 if runtime is higher version
|
||||
* number > 0 if runtime is higher version
|
||||
*/
|
||||
static int compareJFXVersions(String rtVer, String nsVer) {
|
||||
|
||||
@@ -3367,7 +3377,7 @@ public class FXMLLoaderPlus {
|
||||
Map<cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType, Map<String, Method>> getControllerMethods() {
|
||||
if (controllerMethods == null) {
|
||||
controllerMethods = new EnumMap<>(cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.class);
|
||||
for (cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType t: cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.values()) {
|
||||
for (cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType t : cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus.SupportedType.values()) {
|
||||
controllerMethods.put(t, new HashMap<String, Method>());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,50 @@
|
||||
package cn.edu.scau.biubiusuisui.config;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXFactory;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXBuilder;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXControllerFactory;
|
||||
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:54
|
||||
*/
|
||||
public class FXPlusApplication {
|
||||
|
||||
public class FXPlusApplication {
|
||||
private static FXWindowParser windowAnnotationParser = new FXWindowParser();
|
||||
|
||||
public static void start(Class clazz){
|
||||
Annotation []annotations = clazz.getDeclaredAnnotations();
|
||||
for(Annotation annotation : annotations){
|
||||
if(FXScan.class.equals(annotation.annotationType())){
|
||||
String []dirs = ((FXScan)annotation).base();
|
||||
private static BeanBuilder DEFALUT_BEAN_FACTORY = new FXBuilder();
|
||||
|
||||
private static BeanBuilder beanBuilder;
|
||||
|
||||
public static boolean IS_SCENE_BUILDER = true;
|
||||
|
||||
public static void start(Class clazz, BeanBuilder beanBuilder) {
|
||||
IS_SCENE_BUILDER = false;
|
||||
FXPlusApplication.beanBuilder = beanBuilder;
|
||||
Annotation[] annotations = clazz.getDeclaredAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
if (FXScan.class.equals(annotation.annotationType())) {
|
||||
String[] dirs = ((FXScan) annotation).base();
|
||||
Set<String> sets = new HashSet<>();
|
||||
for(String dir : dirs){
|
||||
for (String dir : dirs) {
|
||||
sets.add(dir);
|
||||
}
|
||||
Set<String> classNames = new HashSet<>();
|
||||
for(String dir:sets){
|
||||
for (String dir : sets) {
|
||||
ClassUtils classUtils = new ClassUtils();
|
||||
List<String> temps = classUtils.scanAllClassName(dir);
|
||||
for(String className:temps){
|
||||
for (String className : temps) {
|
||||
try {
|
||||
loadFXPlusClass(className);
|
||||
loadFXPlusClass(className, beanBuilder);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -42,8 +54,14 @@ public class FXPlusApplication {
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadFXPlusClass(String className) throws ClassNotFoundException {
|
||||
public static void start(Class clazz) {
|
||||
start(clazz, DEFALUT_BEAN_FACTORY);
|
||||
}
|
||||
|
||||
private static void loadFXPlusClass(String className, BeanBuilder beanBuilder) throws ClassNotFoundException {
|
||||
Class clazz = Class.forName(className);
|
||||
FXFactory.loadFXController(clazz);
|
||||
if (clazz.getAnnotation(FXWindow.class) != null) {
|
||||
FXControllerFactory.loadStage(clazz, beanBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package cn.edu.scau.biubiusuisui.entity;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.layout.Pane;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtils;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
@@ -17,27 +17,25 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
|
||||
/**
|
||||
* In JavaFX-Plus Framework Controller
|
||||
* We use MVC model
|
||||
* V means view which stand for fxml
|
||||
* C means controller which stand for FXBaseController instance
|
||||
* M means model which is base cn.edu.scau.biubiusuisui.entity in your program
|
||||
* Every BaseController has a name which is used for identifying different <strong>instance</strong>
|
||||
*
|
||||
* In JavaFX-Plus Framework Controller
|
||||
* We use MVC model
|
||||
* V means view which stand for fxml
|
||||
* C means controller which stand for FXBaseController instance
|
||||
* M means model which is base cn.edu.scau.biubiusuisui.entity in your program
|
||||
* Every BaseController has a name which is used for identifying different <strong>instance</strong>
|
||||
*/
|
||||
public class FXBaseController extends Pane {
|
||||
public class FXBaseController extends Pane {
|
||||
|
||||
protected String name = "";
|
||||
|
||||
private Stage stage;
|
||||
private boolean isController = false;
|
||||
private boolean isWindow = false;
|
||||
|
||||
private boolean isWindows = false;
|
||||
|
||||
public FXBaseController(String name){
|
||||
public FXBaseController(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public FXBaseController(){
|
||||
public FXBaseController() {
|
||||
FXController fxController = null;
|
||||
Annotation[] annotations = getClass().getAnnotations();
|
||||
// Find FXController cn.edu.scau.biubiusuisui.annotation
|
||||
@@ -46,34 +44,52 @@ public class FXBaseController extends Pane {
|
||||
fxController = (FXController) annotation;
|
||||
isController = true;
|
||||
}
|
||||
// 添加赋予是否为窗口的逻辑
|
||||
if (annotation.annotationType().equals(FXWindow.class)) {
|
||||
isWindow = true;
|
||||
}
|
||||
}
|
||||
//load fxml file to show panel in scene builder
|
||||
if(isController) {
|
||||
if (isController && FXPlusApplication.IS_SCENE_BUILDER == true) {
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(getClass().getClassLoader().getResource(fxController.path()));
|
||||
fxmlLoader.setRoot(this);
|
||||
fxmlLoader.setController(this);
|
||||
fxmlLoader.setShow(true);
|
||||
// System.out.println("?");
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void initialize() {
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if("".equals(name)){
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName());
|
||||
}else{
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName()) +"#"+name;
|
||||
/**
|
||||
* 唤起舞台
|
||||
*/
|
||||
public void showStage() {
|
||||
if (isWindow) {
|
||||
this.stage.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void closeStage() {
|
||||
if (isWindow) {
|
||||
this.stage.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if ("".equals(name) || name == null) { // 原本无“name == null”判断条件,会出错
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName());
|
||||
} else {
|
||||
return StringUtils.getBaseClassName(getClass().getSimpleName()) + "#" + name;
|
||||
}
|
||||
}
|
||||
public void doInit(){}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
@@ -87,11 +103,20 @@ public class FXBaseController extends Pane {
|
||||
isController = controller;
|
||||
}
|
||||
|
||||
public boolean isWindows() {
|
||||
return isWindows;
|
||||
public boolean isWindow() {
|
||||
return isWindow;
|
||||
}
|
||||
|
||||
public void setWindows(boolean windows) {
|
||||
isWindows = windows;
|
||||
public void setWindow(boolean window) {
|
||||
isWindow = window;
|
||||
}
|
||||
|
||||
public Stage getStage() {
|
||||
return stage;
|
||||
}
|
||||
|
||||
public void setStage(Stage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.entity;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 10:03
|
||||
*/
|
||||
public class FXFieldViewFieldMapping {
|
||||
|
||||
private boolean readOnly;
|
||||
private Class type;
|
||||
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public Class getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Class type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.edu.scau.biubiusuisui.entity;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
/**
|
||||
* 将Controller中的JavaFX的field包装成FXFieldWrapper
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 10:03
|
||||
*/
|
||||
public class FXFieldWrapper {
|
||||
|
||||
private FXField fxField;
|
||||
|
||||
private Property property;
|
||||
|
||||
private Class type;
|
||||
|
||||
public Class getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Class type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public FXField getFxField() {
|
||||
return fxField;
|
||||
}
|
||||
|
||||
public void setFxField(FXField fxField) {
|
||||
this.fxField = fxField;
|
||||
}
|
||||
|
||||
public Property getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(Property property){
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.edu.scau.biubiusuisui.entity;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.proxy.classProxy.FXEntityProxy;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@@ -9,7 +9,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* Context is use for storing Controller
|
||||
* In addition,you can store an instance into Session to use it everywhere
|
||||
*
|
||||
@@ -18,62 +17,35 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class FXPlusContext {
|
||||
|
||||
private FXPlusContext(){}
|
||||
private FXPlusContext() {
|
||||
}
|
||||
|
||||
private static Map<String, List<FXBaseController>> controllerContext = new ConcurrentHashMap<>(); //FXController控制器注册表
|
||||
|
||||
private static Map<Object, FXEntityProxy> beanProxyMap = new ConcurrentHashMap<>(); // Object注册为FXEntityObject
|
||||
private static Map<Object, FXEntityProxy> beanMap = new ConcurrentHashMap<>(); // Object注册为FXEntityObject
|
||||
|
||||
public static Property getEntityPropertyByName(Object object, String fieldName){
|
||||
FXEntityProxy fxEntityProxy = FXPlusContext.getProryByBeanObject(object);
|
||||
if(fxEntityProxy == null){
|
||||
return null;
|
||||
}
|
||||
return fxEntityProxy.getStringPropertyMap().get(fieldName);
|
||||
}
|
||||
|
||||
private static Map<String, Object> session = new ConcurrentHashMap<>();
|
||||
|
||||
public static void addController(FXBaseController fxBaseController){
|
||||
public static void addController(FXBaseController fxBaseController) {
|
||||
List<FXBaseController> controllers = controllerContext.get(fxBaseController.getName());
|
||||
if(controllers == null){
|
||||
if (controllers == null) {
|
||||
controllers = new LinkedList<>();
|
||||
}
|
||||
controllers.add(fxBaseController);
|
||||
}
|
||||
|
||||
public static List<FXBaseController> getControllers(String key){
|
||||
public static List<FXBaseController> getControllers(String key) {
|
||||
return controllerContext.get(key);
|
||||
}
|
||||
|
||||
public static FXEntityProxy getProryByBeanObject(Object object){
|
||||
return beanProxyMap.get(object);
|
||||
public static FXEntityProxy getProxyByBeanObject(Object object) {
|
||||
return beanMap.get(object);
|
||||
}
|
||||
|
||||
public static void setProxyByBeanObject(Object object,FXEntityProxy fxEntityProxy){
|
||||
beanProxyMap.put(object,fxEntityProxy);
|
||||
}
|
||||
public static Map<Object, FXEntityProxy> getBeanProxyMap() {
|
||||
return beanProxyMap;
|
||||
public static void setProxyByBeanObject(Object object, FXEntityProxy fxEntityProxy) {
|
||||
beanMap.put(object, fxEntityProxy);
|
||||
}
|
||||
|
||||
public static void setBeanProxyMap(Map<Object, FXEntityProxy> beanProxyMap) {
|
||||
FXPlusContext.beanProxyMap = beanProxyMap;
|
||||
}
|
||||
|
||||
public static Map<String, List<FXBaseController>> getControllerContext() {
|
||||
return controllerContext;
|
||||
}
|
||||
|
||||
public static void setControllerContext(Map<String, List<FXBaseController>> controllerContext) {
|
||||
FXPlusContext.controllerContext = controllerContext;
|
||||
}
|
||||
|
||||
public static Map<String, Object> getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public static void setSession(Map<String, Object> session) {
|
||||
FXPlusContext.session = session;
|
||||
public static Property getEntityPropertyByName(Object object, String fieldName) {
|
||||
return getProxyByBeanObject(object).getPropertyByFieldName(fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.example;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 1:47
|
||||
*/
|
||||
@FXController(path = "Main.fxml")
|
||||
@FXWindow(title = "demo1")
|
||||
public class MainController extends FXBaseController{
|
||||
|
||||
@FXML
|
||||
private ResourceBundle resources;
|
||||
|
||||
@FXML
|
||||
private URL location;
|
||||
|
||||
@FXML
|
||||
private Button addBtn;
|
||||
|
||||
@FXML
|
||||
private Button delBtn;
|
||||
|
||||
@FXML
|
||||
private ListView<String> list;
|
||||
|
||||
Student student;
|
||||
|
||||
@FXML
|
||||
void addWord(ActionEvent event) {
|
||||
student.addList("hello" );
|
||||
}
|
||||
|
||||
@FXML
|
||||
void delWord(ActionEvent event) {
|
||||
student.delList("hello");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
student = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
|
||||
Property property = FXPlusContext.getEntityPropertyByName(student, "list");
|
||||
list.itemsProperty().bind(property);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.example;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/27 20:02
|
||||
*/
|
||||
|
||||
@FXEntity
|
||||
public class Student {
|
||||
|
||||
@FXField
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private String gender;
|
||||
|
||||
private String code;
|
||||
|
||||
@FXField
|
||||
private List<String> list = new ArrayList<>();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void addList(String word){
|
||||
list.add(word);
|
||||
}
|
||||
public void delList(String word){
|
||||
list.remove(word);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.edu.scau.biubiusuisui.example.actionDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.actionDemo")
|
||||
public class Demo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(Demo.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package cn.edu.scau.biubiusuisui.example.actionDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXBind;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
*/
|
||||
@FXController(path = "actionDemo/actionDemo.fxml")
|
||||
@FXWindow(title = "actionDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
@FXML
|
||||
@FXBind("text=${@toUs(time.text)}")
|
||||
private Label us;
|
||||
|
||||
@FXML
|
||||
@FXBind("text=${@toJp(time.text)}")
|
||||
private Label jp;
|
||||
|
||||
@FXML
|
||||
@FXBind("text=${@toUk(time.text)}")
|
||||
private Label uk;
|
||||
|
||||
@FXML
|
||||
private TextField time;
|
||||
|
||||
public String toUs(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 0.1454;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
|
||||
public String toJp(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 15.797;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
|
||||
public String toUk(String value) {
|
||||
double money = Double.valueOf(value);
|
||||
double percent = 0.1174;
|
||||
return String.valueOf(money * percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
time.setText("0");
|
||||
time.textProperty().addListener(new ChangeListener<String>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
|
||||
if (null == newValue || "".equals(newValue)) {
|
||||
time.setText("0");
|
||||
} else if (!newValue.matches("^[0-9]*$")) {
|
||||
time.setText(oldValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.edu.scau.biubiusuisui.example.actionDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 12:19
|
||||
*/
|
||||
@FXEntity
|
||||
public class User {
|
||||
@FXField
|
||||
private String name;
|
||||
@FXField
|
||||
private String password;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.edu.scau.biubiusuisui.example.firstDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 第一个示例
|
||||
* @date 2020/1/1 23:06
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.firstDemo"}) //会扫描带FXController和FXEntity的类进行初始化
|
||||
public class Demo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(Demo.class); //其他配置和JavaFX相同,这里要调用FXPlusAppcalition的start方法,开始FX-plus加强
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.edu.scau.biubiusuisui.example.firstDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2020/1/1 23:06
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "firstDemo/firstDemo.fxml")
|
||||
@FXWindow(title = "firstDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController implements Initializable {
|
||||
|
||||
@FXML
|
||||
private Button addHelloButton;
|
||||
@FXML
|
||||
private Button deleteHelloButton;
|
||||
|
||||
@FXML
|
||||
private ListView<String> list;
|
||||
|
||||
private Student student;
|
||||
|
||||
@FXML
|
||||
void addWord(ActionEvent event) {
|
||||
student.addList("hello");
|
||||
}
|
||||
|
||||
@FXML
|
||||
void delWord(ActionEvent event) {
|
||||
student.delList("hello");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
student = (Student) FXEntityFactory.wrapFxBean(Student.class); // 从工厂中拿到将JavaBean转换得到的JavaFXBean
|
||||
Property listProperty = FXPlusContext.getEntityPropertyByName(student, "list");
|
||||
list.itemsProperty().bind(listProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.edu.scau.biubiusuisui.example.firstDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2020/1/1 23:07
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
|
||||
@FXEntity
|
||||
public class Student {
|
||||
|
||||
@FXField //标记该属性是否被生成对应的Property
|
||||
private int age = 0;
|
||||
|
||||
@FXField
|
||||
private List<String> list = new ArrayList<>();
|
||||
|
||||
public void addList(String word) {
|
||||
list.add(word);
|
||||
}
|
||||
|
||||
public void delList(String word) {
|
||||
list.remove(word);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.edu.scau.biubiusuisui.example;
|
||||
package cn.edu.scau.biubiusuisui.example.listDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
@@ -7,9 +7,9 @@ import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 7:05
|
||||
* @Date:2019/7/27 1:43
|
||||
*/
|
||||
@FXScan(base = {"cn.edu.scau.biubiusuisui.example"})
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.listDemo")
|
||||
public class Demo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.edu.scau.biubiusuisui.example.listDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXBind;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXData;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:43
|
||||
*/
|
||||
@FXController(path = "listDemo/listDemo.fxml")
|
||||
@FXWindow(title = "listDemo", mainStage = true)
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
@FXData
|
||||
User user = new User();
|
||||
|
||||
@FXML
|
||||
@FXBind("items=${@toList(user.names)}")
|
||||
private ListView<String> userNameListView;
|
||||
|
||||
|
||||
@FXML
|
||||
public void addUserName() {
|
||||
user.addNames("Jack\t" + (count++));
|
||||
}
|
||||
|
||||
public ObservableList toList(ArrayList list) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
return FXCollections.observableList(list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.edu.scau.biubiusuisui.example.listDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 12:19
|
||||
*/
|
||||
@FXEntity
|
||||
public class User {
|
||||
@FXField
|
||||
private String name;
|
||||
|
||||
@FXField
|
||||
private String password;
|
||||
|
||||
@FXField
|
||||
private ArrayList<String> names = new ArrayList<>();
|
||||
|
||||
|
||||
public User() {
|
||||
// names.add("hello ");
|
||||
// names.add("test");
|
||||
}
|
||||
|
||||
|
||||
public void addNames(String name) {
|
||||
names.add(name);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public ArrayList<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public void setNames(ArrayList<String> names) {
|
||||
this.names = names;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.edu.scau.biubiusuisui.example.mqDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.mqDemo")
|
||||
public class MQDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(MQDemo.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.edu.scau.biubiusuisui.example.mqDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXReceiver;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.TextArea;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 主界面
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "mqDemo/main.fxml")
|
||||
@FXWindow(mainStage = true, title = "MQDemo")
|
||||
public class MainController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
private TextArea outTA;
|
||||
|
||||
/**
|
||||
* 接收者必须指定要订阅的[发送者类名:方法名]
|
||||
* 发送函数的返回值会注入到接收函数的参数中
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
@FXReceiver(name = "TopBarController:sendToMain")
|
||||
public void handleTopBar(String msg) {
|
||||
// TODO: 2019/12/8
|
||||
// 处理导航栏的点击事件
|
||||
outTA.appendText(msg + "\n");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.edu.scau.biubiusuisui.example.mqDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXSender;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 导航栏示例
|
||||
* @date 2019/12/8 13:17
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "mqDemo/topBar.fxml")
|
||||
public class TopBarController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
public void indexClick() {
|
||||
sendToMain("点击[首页]");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void scoreClick() {
|
||||
sendToMain("点击[积分中心]");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void questionClick() {
|
||||
sendToMain("点击[问答中心]");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void selfClick() {
|
||||
sendToMain("点击[个人中心]");
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统会通过发射信号,调用所有订阅这个发射信号函数的方法,从而响应信号
|
||||
*
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
@FXSender //标注为信号发射函数
|
||||
public String sendToMain(String msg) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2019/12/4 21:00
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "redirectDemo/dialog.fxml")
|
||||
@FXWindow(title = "弹窗")
|
||||
public class DialogController extends FXBaseController {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2019/12/3 11:53
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "redirectDemo/login.fxml")
|
||||
@FXWindow(title = "redirectDemo", mainStage = true)
|
||||
public class LoginController extends FXBaseController {
|
||||
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
|
||||
@FXML
|
||||
private PasswordField passwordPF;
|
||||
|
||||
@FXML
|
||||
public void registerClick() {
|
||||
System.out.println("点击注册.....");
|
||||
redirectToRegister();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirectToRegister() {
|
||||
return "RegisterController";
|
||||
}
|
||||
|
||||
@FXML
|
||||
@FXRedirect(close = false) //弹窗
|
||||
public String redirectToDialog() {
|
||||
return "DialogController";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXScan;
|
||||
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 测试重定向功能的Application
|
||||
* @date 2019/12/3 11:52
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXScan(base = "cn.edu.scau.biubiusuisui.example.redirectDemo")
|
||||
public class RedirectDemo extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXPlusApplication.start(RedirectDemo.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description
|
||||
* @date 2019/12/4 00:07
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "redirectDemo/register.fxml")
|
||||
@FXWindow(title = "register")
|
||||
public class RegisterController extends FXBaseController {
|
||||
@FXML
|
||||
private TextField usernameTF;
|
||||
|
||||
@FXML
|
||||
private TextField emailTF;
|
||||
@FXML
|
||||
private PasswordField passwordPF;
|
||||
|
||||
@FXML
|
||||
private PasswordField confirmPasswordPF;
|
||||
|
||||
@FXML
|
||||
public void registerClick() {
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void loginClick() {
|
||||
redirectToLogin();
|
||||
}
|
||||
|
||||
@FXRedirect
|
||||
public String redirectToLogin() {
|
||||
return "LoginController";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.edu.scau.biubiusuisui.example.redirectDemo;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 登录成功的Controller
|
||||
* @date 2019/12/3 12:43
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
@FXController(path = "redirectDemo/success.fxml")
|
||||
@FXWindow(title = "success")
|
||||
public class SuccessController extends FXBaseController implements Initializable {
|
||||
|
||||
@FXML
|
||||
private Label usernameLabel;
|
||||
|
||||
@FXML
|
||||
private Label passwordLabel;
|
||||
|
||||
|
||||
@FXML
|
||||
@FXRedirect
|
||||
public String redirectToLogin() {
|
||||
return "LoginController";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.edu.scau.biubiusuisui.exception;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 3:00
|
||||
*/
|
||||
public class NoSuchChangeMethod extends Exception {
|
||||
|
||||
public NoSuchChangeMethod() {
|
||||
super("No such change method");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.edu.scau.biubiusuisui.expression;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 2:02
|
||||
*/
|
||||
public interface BindParser {
|
||||
public void parse(Object target,String expression);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.action;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.expression.BindParser;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 2:03
|
||||
*/
|
||||
public class ChangeParser implements BindParser {
|
||||
|
||||
@Override
|
||||
public void parse(Object target, String expression) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 20:03
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExpFunction<T,U,R>{
|
||||
R apply(T t, U u);
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXValue;
|
||||
import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.javafx.fxml.expression.Expression;
|
||||
import com.sun.javafx.fxml.expression.VariableExpression;
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 将FXBind中表达式建立绑定
|
||||
* 格式如下
|
||||
* 语法如下:
|
||||
* FXBind("S")
|
||||
* S -> left=right
|
||||
* left -> property
|
||||
* right -> ${expression}
|
||||
* expression -> bean.field
|
||||
* <p>
|
||||
* FXBind("text=${bean.field})
|
||||
* textProperty 通过 adapter.getModelProeprty --> textProperty实例
|
||||
* bean 通过namespace 获取,因为bean有FXEntity标签,所以返回包装过后的bean的property
|
||||
* 最后
|
||||
* left.bind(right)
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/7/23 15:05
|
||||
*/
|
||||
public class ExpressionParser {
|
||||
|
||||
private Object namespace;
|
||||
private Object targetController;
|
||||
private static final String BIND_PREFIX = "${";
|
||||
private static final String BIND_SUFIX = "}";
|
||||
private static final String PROEPRTY = "Property";
|
||||
|
||||
public enum ExpressionType {
|
||||
DataExpression,
|
||||
ActionExpression
|
||||
}
|
||||
|
||||
public ExpressionParser(Object namespace, Object targetController) {
|
||||
this.namespace = namespace;
|
||||
this.targetController = targetController;
|
||||
}
|
||||
|
||||
public ExpressionParser(Object namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
private Property getLeftProperty(MyBeanAdapter myBeanAdapter, String key) {
|
||||
return (Property) myBeanAdapter.getPropertyModel(key);
|
||||
}
|
||||
|
||||
private static final String FUNCTION_PREFIX = "@";
|
||||
|
||||
private MyExpressionValue getRightExpreesion(MyBeanAdapter myBeanAdapter, String key, String rightExpression) {
|
||||
Expression expression = null;
|
||||
if (rightExpression.startsWith(FUNCTION_PREFIX)) {
|
||||
expression = getFunctionExpression(rightExpression);
|
||||
} else {
|
||||
expression = Expression.valueOf(rightExpression);
|
||||
}
|
||||
Class clazz = myBeanAdapter.getType(key);
|
||||
MyExpressionValue myExpressionValue = new MyExpressionValue(namespace, expression, clazz);
|
||||
return myExpressionValue;
|
||||
}
|
||||
|
||||
private Expression getFunctionExpression(String rightExpression) {
|
||||
Expression expression = null;
|
||||
int indexLeft = rightExpression.indexOf("(");
|
||||
String methodName = rightExpression.substring(1,indexLeft);
|
||||
int indexRight = rightExpression.indexOf(")");
|
||||
String argString = rightExpression.substring(indexLeft + 1, indexRight);
|
||||
String[] args = null;
|
||||
if(!"".equals(argString.trim())) {
|
||||
args = argString.split(",");
|
||||
}
|
||||
Class clazz = targetController.getClass();
|
||||
Method[] methods = clazz.getMethods();
|
||||
Expression[] expressions = null;
|
||||
if(args!=null) {
|
||||
expressions = new Expression[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (!"".equals(args[i].trim())) {
|
||||
expressions[i] = Expression.valueOf(args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals(methodName)) {
|
||||
expression = new FunctionExpression(method, targetController, expressions);
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
public void parse(Object object, @NotNull String expression) throws NoSuchChangeMethod {
|
||||
//check expression
|
||||
int index = expression.indexOf("=");
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
String[] items = expression.split("=");
|
||||
if (items.length != 2) {
|
||||
return;
|
||||
}
|
||||
String left = items[0];
|
||||
String right = items[1];
|
||||
if (left == null || right == null) {
|
||||
return;
|
||||
}
|
||||
right = right.trim();
|
||||
ExpressionType expressionType;
|
||||
if (right.startsWith(BIND_PREFIX) && right.endsWith(BIND_SUFIX)) {
|
||||
int length = right.length();
|
||||
right = right.substring(2, length - 1);
|
||||
expressionType = ExpressionType.DataExpression;
|
||||
} else {
|
||||
right = right.substring(1); //#changeMethod -> changeMethod
|
||||
expressionType = ExpressionType.ActionExpression;
|
||||
}
|
||||
MyBeanAdapter myBeanAdapter = new MyBeanAdapter(object);
|
||||
Property leftProperty = getLeftProperty(myBeanAdapter, left);
|
||||
switch (expressionType) {
|
||||
case DataExpression:
|
||||
bindDataExpression(left, right, myBeanAdapter, leftProperty);
|
||||
break;
|
||||
case ActionExpression:
|
||||
//
|
||||
bindActionExpression(right, leftProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void bindActionExpression(String right, Property leftProperty) throws NoSuchChangeMethod {
|
||||
Class clazz = targetController.getClass();
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals(right)) {
|
||||
leftProperty.addListener((observable, oldValue, newValue) -> {
|
||||
try {
|
||||
Object[] objects = getArgs(method, observable, newValue, oldValue);
|
||||
method.invoke(targetController, objects);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindDataExpression(String left, String right, MyBeanAdapter myBeanAdapter, Property leftProperty) {
|
||||
MyExpressionValue rightProperty = getRightExpreesion(myBeanAdapter, left, right);
|
||||
leftProperty.bind(rightProperty);
|
||||
}
|
||||
|
||||
public Object[] getArgs(Method method, Object... args) {
|
||||
Parameter[] parameters = method.getParameters();
|
||||
Object[] objects = new Object[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
FXValue annotation = parameters[i].getAnnotation(FXValue.class);
|
||||
switch (annotation.value()) {
|
||||
case "target":
|
||||
objects[i] = args[0];
|
||||
break;
|
||||
case "newValue":
|
||||
objects[i] = args[1];
|
||||
break;
|
||||
case "oldValue":
|
||||
objects[i] = args[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
import com.sun.javafx.fxml.expression.Expression;
|
||||
import com.sun.javafx.fxml.expression.KeyPath;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 20:00
|
||||
*/
|
||||
public class FunctionExpression extends Expression {
|
||||
|
||||
private Method method;
|
||||
private Object target;
|
||||
private Expression []args;
|
||||
|
||||
public FunctionExpression(Method method, Object target, Expression[]expressions) {
|
||||
this.method = method;
|
||||
this.target = target;
|
||||
this.args = expressions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KeyPath> getArguments() {
|
||||
List<KeyPath> list = new ArrayList<>();
|
||||
if(args !=null) {
|
||||
for (Expression expression : args) {
|
||||
list.addAll(expression.getArguments());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(Object namespace) {
|
||||
Object result = null;
|
||||
if(args!=null){
|
||||
Object[] values = new Object[args.length];
|
||||
for(int i = 0 ;i<args.length;i++){
|
||||
values[i] = args[i].evaluate(namespace);
|
||||
}
|
||||
try {
|
||||
result = method.invoke(target, values);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}else{
|
||||
try {
|
||||
result = method.invoke(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object namespace, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefined(Object namespace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getArguments(List arguments) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.utils.BeanUtil;
|
||||
import com.sun.javafx.fxml.BeanAdapter;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/23 15:16
|
||||
*/
|
||||
public class MyBeanAdapter extends BeanAdapter {
|
||||
|
||||
private Object object;
|
||||
|
||||
/**
|
||||
* Creates a new Bean adapter.
|
||||
*
|
||||
* @param bean The Bean object to wrap.
|
||||
*/
|
||||
public MyBeanAdapter(Object bean) {
|
||||
super(bean);
|
||||
this.object = bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObservableValue<T> getPropertyModel(String key) {
|
||||
if (object.getClass().getAnnotation(FXEntity.class) == null) {
|
||||
return super.getPropertyModel(key);
|
||||
} else {
|
||||
return BeanUtil.getPropertyByName(object, key);
|
||||
}
|
||||
}
|
||||
|
||||
public String valueOf(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
import com.sun.javafx.fxml.BeanAdapter;
|
||||
import com.sun.javafx.fxml.expression.Expression;
|
||||
import com.sun.javafx.fxml.expression.KeyPath;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.beans.value.ObservableValueBase;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.MapChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class MyExpressionValue extends ObservableValueBase<Object> {
|
||||
|
||||
// Monitors a namespace for changes along a key path
|
||||
private class KeyPathMonitor {
|
||||
private String key;
|
||||
private KeyPathMonitor next;
|
||||
|
||||
private Object namespace = null;
|
||||
|
||||
private ListChangeListener<Object> listChangeListener = new ListChangeListener<Object>() {
|
||||
@Override
|
||||
public void onChanged(Change<? extends Object> change) {
|
||||
while (change.next()) {
|
||||
int index = Integer.parseInt(key);
|
||||
|
||||
if (index >= change.getFrom() && index < change.getTo()) {
|
||||
fireValueChangedEvent();
|
||||
remonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private MapChangeListener<String, Object> mapChangeListener = new MapChangeListener<String, Object>() {
|
||||
@Override
|
||||
public void onChanged(Change<? extends String, ? extends Object> change) {
|
||||
if (key.equals(change.getKey())) {
|
||||
fireValueChangedEvent();
|
||||
remonitor();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private ChangeListener<Object> propertyChangeListener = new ChangeListener<Object>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
|
||||
fireValueChangedEvent();
|
||||
remonitor();
|
||||
}
|
||||
};
|
||||
|
||||
public KeyPathMonitor(Iterator<String> keyPathIterator) {
|
||||
this.key = keyPathIterator.next();
|
||||
|
||||
if (keyPathIterator.hasNext()) {
|
||||
next = new KeyPathMonitor(keyPathIterator);
|
||||
} else {
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void monitor(Object namespace) {
|
||||
if (namespace instanceof ObservableList<?>) {
|
||||
((ObservableList<Object>)namespace).addListener(listChangeListener);
|
||||
} else if (namespace instanceof ObservableMap<?, ?>) {
|
||||
((ObservableMap<String, Object>)namespace).addListener(mapChangeListener);
|
||||
} else {
|
||||
|
||||
MyBeanAdapter namespaceAdapter = new MyBeanAdapter(namespace);
|
||||
ObservableValue<Object> propertyModel = namespaceAdapter.getPropertyModel(key);
|
||||
|
||||
if (propertyModel != null) {
|
||||
propertyModel.addListener(propertyChangeListener);
|
||||
}
|
||||
|
||||
namespace = namespaceAdapter;
|
||||
}
|
||||
|
||||
this.namespace = namespace;
|
||||
|
||||
if (next != null) {
|
||||
Object value = Expression.get(namespace, key);
|
||||
if (value != null) {
|
||||
next.monitor(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void unmonitor() {
|
||||
if (namespace instanceof ObservableList<?>) {
|
||||
((ObservableList<Object>)namespace).removeListener(listChangeListener);
|
||||
} else if (namespace instanceof ObservableMap<?, ?>) {
|
||||
((ObservableMap<String, Object>)namespace).removeListener(mapChangeListener);
|
||||
} else if (namespace != null) {
|
||||
MyBeanAdapter namespaceAdapter = (MyBeanAdapter)namespace;
|
||||
ObservableValue<Object> propertyModel = namespaceAdapter.getPropertyModel(key);
|
||||
|
||||
if (propertyModel != null) {
|
||||
propertyModel.removeListener(propertyChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
namespace = null;
|
||||
|
||||
if (next != null) {
|
||||
next.unmonitor();
|
||||
}
|
||||
}
|
||||
|
||||
public void remonitor() {
|
||||
if (next != null) {
|
||||
next.unmonitor();
|
||||
Object value = Expression.get(namespace, key);
|
||||
if (value != null) {
|
||||
next.monitor(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object namespace;
|
||||
private Expression expression;
|
||||
private Class<?> type;
|
||||
|
||||
private ArrayList<KeyPathMonitor> argumentMonitors;
|
||||
|
||||
private int listenerCount = 0;
|
||||
|
||||
public MyExpressionValue(Object namespace, Expression expression, Class<?> type) {
|
||||
if (namespace == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (expression == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
this.namespace = namespace;
|
||||
this.expression = expression;
|
||||
this.type = type;
|
||||
|
||||
List<KeyPath> arguments = expression.getArguments();
|
||||
argumentMonitors = new ArrayList<KeyPathMonitor>(arguments.size());
|
||||
|
||||
for (KeyPath argument : arguments) {
|
||||
argumentMonitors.add(new KeyPathMonitor(argument.iterator()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return BeanAdapter.coerce(expression.evaluate(namespace), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(InvalidationListener listener) {
|
||||
if (listenerCount == 0) {
|
||||
monitorArguments();
|
||||
}
|
||||
|
||||
super.addListener(listener);
|
||||
listenerCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(InvalidationListener listener) {
|
||||
super.removeListener(listener);
|
||||
listenerCount--;
|
||||
|
||||
if (listenerCount == 0) {
|
||||
unmonitorArguments();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ChangeListener<? super Object> listener) {
|
||||
if (listenerCount == 0) {
|
||||
monitorArguments();
|
||||
}
|
||||
|
||||
super.addListener(listener);
|
||||
listenerCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ChangeListener<? super Object> listener) {
|
||||
super.removeListener(listener);
|
||||
listenerCount--;
|
||||
|
||||
if (listenerCount == 0) {
|
||||
unmonitorArguments();
|
||||
}
|
||||
}
|
||||
|
||||
private void monitorArguments() {
|
||||
for (KeyPathMonitor argumentMonitor : argumentMonitors) {
|
||||
argumentMonitor.monitor(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
private void unmonitorArguments() {
|
||||
for (KeyPathMonitor argumentMonitor : argumentMonitors) {
|
||||
argumentMonitor.unmonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/4 11:16
|
||||
*/
|
||||
public interface BeanBuilder {
|
||||
/**
|
||||
* 万能工厂方法
|
||||
* @param type 类型
|
||||
* @return 实例对象
|
||||
*/
|
||||
Object getBean(Class type);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/4 11:13
|
||||
*/
|
||||
public class FXBuilder implements BeanBuilder{
|
||||
@Override
|
||||
public Object getBean(Class type) {
|
||||
Object object = null;
|
||||
try {
|
||||
object = type.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXBind;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXData;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
|
||||
import cn.edu.scau.biubiusuisui.expression.data.ExpressionParser;
|
||||
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
|
||||
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXControllerProxy;
|
||||
import cn.edu.scau.biubiusuisui.stage.StageManager;
|
||||
import javafx.collections.ObservableMap;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 8:12
|
||||
*/
|
||||
public class FXControllerFactory {
|
||||
|
||||
|
||||
private static final BeanBuilder BEAN_BUILDER = new FXBuilder();
|
||||
private static FXWindowParser windowAnnotationParser = new FXWindowParser();
|
||||
|
||||
|
||||
/**
|
||||
* 控制类的注入流程
|
||||
* 这是一个即将被创建的控制类
|
||||
* <pre>
|
||||
* <code>
|
||||
* class MainController{
|
||||
* @Autowired
|
||||
* Student stu; //普通属性
|
||||
* @FXML
|
||||
* Button btn; //FX属性
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* 1. 实现对普通属性的注入
|
||||
* 如果使用了Spring那么这类会自动注入那些@Autowired的属性,请不要将这个方法用在控制器属性中
|
||||
* <pre>
|
||||
* <code>
|
||||
* class MainController{
|
||||
* @Autowired
|
||||
* Student stu ; //初始化完成
|
||||
* @FXML
|
||||
* Button btn; // null
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* 2. 通过loadFXML实现对FX属性的注入
|
||||
* <pre>
|
||||
* <code>
|
||||
* class MainController{
|
||||
* @Autowired
|
||||
* Student stu ; //初始化完成
|
||||
* @FXML
|
||||
* Button btn; // 初始化完成
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* <p>
|
||||
* 3. 完成对FXBind的注解的解析
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* 4. 完成注册
|
||||
*
|
||||
* @param clazz instance that extends by FXBaseController
|
||||
* @param controllerName
|
||||
* @return
|
||||
*/
|
||||
private static FXBaseController getFxBaseController(Class clazz, String controllerName, BeanBuilder beanBuilder) {
|
||||
return getFxBaseController0(clazz, controllerName, beanBuilder);
|
||||
}
|
||||
|
||||
private static FXBaseController getFxBaseController0(Class clazz, String controllerName, BeanBuilder beanBuilder) {
|
||||
URL fxmlPath;
|
||||
FXController fxController = null; //reflect and get FXController cn.edu.scau.biubiusuisui.annotation
|
||||
fxController = (FXController) clazz.getDeclaredAnnotation(FXController.class);
|
||||
Pane parent = null;
|
||||
FXBaseController fxBaseController = null;
|
||||
FXBaseController fxControllerProxy = null;
|
||||
if (fxController != null) {
|
||||
String fxmlPathName = fxController.path();
|
||||
fxmlPath = clazz.getClassLoader().getResource(fxmlPathName);
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(fxmlPath);
|
||||
// create a cn.edu.scau.biubiusuisui.proxy for monitoring methods
|
||||
|
||||
fxBaseController = (FXBaseController) beanBuilder.getBean(clazz); //获取controller实例
|
||||
parseData(fxBaseController);
|
||||
|
||||
if (fxBaseController != null) {
|
||||
FXControllerProxy controllerProxy = new FXControllerProxy();
|
||||
fxControllerProxy = (FXBaseController) controllerProxy.getInstance(fxBaseController); //产生代理从而实现赋能
|
||||
fxmlLoader.setRoot(fxControllerProxy);
|
||||
fxmlLoader.setController(fxControllerProxy);
|
||||
fxmlLoader.setBaseController(fxBaseController);
|
||||
try {
|
||||
parent = fxmlLoader.load();
|
||||
if (controllerName != null) {
|
||||
fxControllerProxy.setName(controllerName);
|
||||
fxBaseController.setName(controllerName);
|
||||
} else {
|
||||
fxBaseController.setName(parent.getId());
|
||||
}
|
||||
ObservableMap namespace = fxmlLoader.getNamespace();
|
||||
addDataInNameSpace(namespace, fxBaseController); //处理fxBaseController里面的@FXData
|
||||
scanBind(namespace, fxBaseController); //处理@FXBind
|
||||
register(fxBaseController, fxControllerProxy);
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return fxControllerProxy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将代理对象和目标对象注册
|
||||
*
|
||||
* @param fxBaseController 目标对象
|
||||
* @param fxBaseControllerProxy 代理对象
|
||||
*/
|
||||
private static void register(FXBaseController fxBaseController, FXBaseController fxBaseControllerProxy) {
|
||||
FXPlusContext.addController(fxBaseController); //保存
|
||||
MessageQueue.getInstance().registerConsumer(fxBaseController, fxBaseControllerProxy); // 添加进入消息队列 信号功能
|
||||
}
|
||||
|
||||
/**
|
||||
* 为有FXWindow注解的类创建Stage
|
||||
*
|
||||
* @param fxWindow
|
||||
* @param fxBaseControllerProxy
|
||||
* @return
|
||||
*/
|
||||
private static Stage createWindow(FXWindow fxWindow, FXBaseController fxBaseControllerProxy) {
|
||||
Stage stage = new Stage();
|
||||
fxBaseControllerProxy.setStage(stage);
|
||||
double preWidth = fxWindow.preWidth() == 0 ? fxBaseControllerProxy.getPrefWidth() : fxWindow.preWidth();
|
||||
double preHeight = fxWindow.preHeight() == 0 ? fxBaseControllerProxy.getPrefHeight() : fxWindow.preHeight();
|
||||
Scene scene = new Scene(fxBaseControllerProxy, preWidth, preHeight);
|
||||
stage.setScene(scene);
|
||||
windowAnnotationParser.parse(stage, fxBaseControllerProxy, fxWindow);
|
||||
|
||||
StageManager.getInstance().registerWindow(fxBaseControllerProxy); //注册舞台
|
||||
if (fxWindow.mainStage() == true) { //当是主舞台时,先show为敬
|
||||
// System.out.println("FXControllerFactory: "+(fxControllerProxy.getStage() == null));
|
||||
fxBaseControllerProxy.showStage();
|
||||
}
|
||||
return stage;
|
||||
}
|
||||
|
||||
private FXControllerFactory() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载舞台
|
||||
* 原函数名为loadMainStage(Class clazz, BeanBuilder beanBuilder)
|
||||
*
|
||||
* @param clazz
|
||||
* @param beanBuilder
|
||||
*/
|
||||
public static void loadStage(Class clazz, BeanBuilder beanBuilder) {
|
||||
FXWindow declaredAnnotation = (FXWindow) clazz.getDeclaredAnnotation(FXWindow.class);
|
||||
//只有当用了FXWindow注解,才会注册Stage
|
||||
if (declaredAnnotation != null) {
|
||||
getFXWindow(clazz, null, beanBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz) {
|
||||
return getFXController(clazz, BEAN_BUILDER);
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz, BeanBuilder beanBuilder) {
|
||||
FXBaseController fxBaseController = getFXController(clazz, null, beanBuilder);
|
||||
return fxBaseController;
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz, String controllerName) {
|
||||
return getFXController(clazz, controllerName, BEAN_BUILDER);
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz, String controllerName, BeanBuilder beanBuilder) {
|
||||
FXBaseController fxBaseController = getFxBaseController(clazz, controllerName, beanBuilder);
|
||||
return fxBaseController;
|
||||
}
|
||||
|
||||
|
||||
public static Stage getFXWindow(Class clazz) {
|
||||
FXWindow fxWindow = (FXWindow) clazz.getDeclaredAnnotation(FXWindow.class);
|
||||
if (fxWindow != null) {
|
||||
FXBaseController fxController = getFXController(clazz, null, BEAN_BUILDER);
|
||||
return createWindow(fxWindow, fxController);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Stage getFXWindow(Class clazz, BeanBuilder beanBuilder) {
|
||||
FXWindow fxWindow = (FXWindow) clazz.getDeclaredAnnotation(FXWindow.class);
|
||||
if (fxWindow != null) {
|
||||
FXBaseController fxController = getFXController(clazz, null, beanBuilder);
|
||||
return createWindow(fxWindow, fxController);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Stage getFXWindow(Class clazz, String controllerName) {
|
||||
FXWindow fxWindow = (FXWindow) clazz.getDeclaredAnnotation(FXWindow.class);
|
||||
if (fxWindow != null) {
|
||||
FXBaseController fxController = getFXController(clazz, controllerName, BEAN_BUILDER);
|
||||
return createWindow(fxWindow, fxController);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Stage getFXWindow(Class clazz, String controllerName, BeanBuilder beanBuilder) {
|
||||
FXWindow fxWindow = (FXWindow) clazz.getDeclaredAnnotation(FXWindow.class);
|
||||
if (fxWindow != null) {
|
||||
FXBaseController fxController = getFXController(clazz, controllerName, beanBuilder);
|
||||
return createWindow(fxWindow, fxController);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseData(Object fxControllerObject) {
|
||||
Class clazz = fxControllerObject.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
FXData annotation = field.getAnnotation(FXData.class);
|
||||
if (annotation != null) {
|
||||
field.setAccessible(true);
|
||||
//建立代理
|
||||
try {
|
||||
Object fieldValue = field.get(fxControllerObject);
|
||||
Object fieldValueProxy = FXEntityFactory.wrapFxBean(fieldValue);
|
||||
field.set(fxControllerObject, fieldValueProxy);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addDataInNameSpace(ObservableMap namespace, Object object) {
|
||||
Class clazz = object.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
FXData annotation = field.getAnnotation(FXData.class);
|
||||
if (annotation != null) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
String fx_id;
|
||||
field.setAccessible(true);
|
||||
if ("".equals(annotation.fx_id())) {
|
||||
fx_id = field.getName();
|
||||
} else {
|
||||
fx_id = annotation.fx_id();
|
||||
}
|
||||
Object fieldValue = field.get(object);
|
||||
namespace.put(fx_id, fieldValue);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void scanBind(ObservableMap namespace, Object object) {
|
||||
Class clazz = object.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
parseBind(namespace, object, field);
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseBind(ObservableMap namespace, Object object, Field field) {
|
||||
FXBind fxBind = field.getAnnotation(FXBind.class);
|
||||
field.setAccessible(true);
|
||||
ExpressionParser expressionParser = new ExpressionParser(namespace, object);
|
||||
if (fxBind != null) {
|
||||
String[] expressions = fxBind.value();
|
||||
try {
|
||||
Object objectValue = field.get(object);
|
||||
for (String e : expressions) {
|
||||
expressionParser.parse(objectValue, e);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchChangeMethod noSuchChangeMethod) {
|
||||
noSuchChangeMethod.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFXWindow(Class clazz) {
|
||||
if (clazz.getDeclaredAnnotation(FXWindow.class) != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXField;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXFieldViewFieldMapping;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXFieldWrapper;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.proxy.classProxy.FXEntityProxy;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
|
||||
import cn.edu.scau.biubiusuisui.utils.ClassUtils;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
@@ -11,8 +11,8 @@ import javafx.collections.FXCollections;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
@@ -20,26 +20,29 @@ import java.util.List;
|
||||
*/
|
||||
public class FXEntityFactory {
|
||||
|
||||
private FXEntityFactory(){}
|
||||
|
||||
public static Object createJavaBeanProxy(Class clazz) {
|
||||
Object object = null;
|
||||
try {
|
||||
object = clazz.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return createJavaBeanProxy(object);
|
||||
private FXEntityFactory() {
|
||||
}
|
||||
|
||||
public static Object createJavaBeanProxy(Object object){
|
||||
public static Object wrapFxBean(Class clazz) {
|
||||
return wrapFxBean(clazz, new FXBuilder());
|
||||
}
|
||||
|
||||
public static Object wrapFxBean(Class clazz, BeanBuilder beanBuilder) {
|
||||
Object object = null;
|
||||
object = beanBuilder.getBean(clazz);
|
||||
if (object != null) {
|
||||
return wrapFxBean(object);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object wrapFxBean(Object object) {
|
||||
FXEntityProxy fxEntityProxy = new FXEntityProxy();
|
||||
Object objectProxy = null;
|
||||
try {
|
||||
objectProxy = fxEntityProxy.getInstance(object);
|
||||
processFXEntityProxy(object,objectProxy,fxEntityProxy);
|
||||
objectProxy = fxEntityProxy.getInstance(object); // 初始化代理类
|
||||
processFXEntityProxy(object, objectProxy, fxEntityProxy);
|
||||
FXPlusContext.setProxyByBeanObject(objectProxy, fxEntityProxy);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
@@ -47,34 +50,27 @@ public class FXEntityFactory {
|
||||
return objectProxy;
|
||||
}
|
||||
|
||||
|
||||
public static void processFXEntityProxy(Object entity, Object proxy,FXEntityProxy fxEntityProxy) throws IllegalAccessException {
|
||||
Map<String, Property> stringPropertyMap = new HashMap<>();
|
||||
Map<String, FXFieldViewFieldMapping> stringFXFieldMethodMappingMap = new HashMap<>();
|
||||
Field []fields = entity.getClass().getDeclaredFields();
|
||||
for(Field field:fields){
|
||||
Annotation annotation = ClassUtils.getAnnotationInList( FXField.class,field.getDeclaredAnnotations());
|
||||
if(annotation != null){
|
||||
private static void processFXEntityProxy(Object entity, Object proxy, FXEntityProxy fxEntityProxy) throws IllegalAccessException {
|
||||
Map<String, FXFieldWrapper> fxFieldWrapperMap = new HashMap<>();
|
||||
Field[] fields = entity.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
Annotation annotation = ClassUtils.getAnnotationInList(FXField.class, field.getDeclaredAnnotations());
|
||||
if (annotation != null) {
|
||||
Property property = null;
|
||||
field.setAccessible(true);
|
||||
FXField fxField = (FXField)annotation;
|
||||
|
||||
FXFieldViewFieldMapping fieldMethodMapping = new FXFieldViewFieldMapping();
|
||||
fieldMethodMapping.setReadOnly(fxField.readOnly());
|
||||
fieldMethodMapping.setType(field.getType());
|
||||
stringFXFieldMethodMappingMap.put(field.getName(), fieldMethodMapping);
|
||||
|
||||
if(field.get(entity) == null){
|
||||
property = getFieldDefalutProperty(field);
|
||||
|
||||
}else{
|
||||
property = getFieldProperty(entity, field);
|
||||
FXField fxField = (FXField) annotation;
|
||||
FXFieldWrapper fieldWrapper = new FXFieldWrapper();
|
||||
fieldWrapper.setFxField(fxField);
|
||||
fieldWrapper.setType(field.getType());
|
||||
if (field.get(entity) == null) {
|
||||
property = getFieldDefaultProperty(field);
|
||||
} else {
|
||||
property = getFieldProperty(entity, field);
|
||||
}
|
||||
if(property !=null) {
|
||||
//添加时间;
|
||||
property.addListener((object,oldVal,newVal)->{
|
||||
if(!fxField.readOnly()) {
|
||||
if(!field.getType().equals(List.class)) {
|
||||
if (property != null) {
|
||||
property.addListener((object, oldVal, newVal) -> {
|
||||
if (!fxField.readOnly()) {
|
||||
if (!List.class.isAssignableFrom(field.getType())) {
|
||||
try {
|
||||
field.set(proxy, newVal);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -83,60 +79,63 @@ public class FXEntityFactory {
|
||||
}
|
||||
}
|
||||
});
|
||||
stringPropertyMap.put(field.getName(), property);
|
||||
}
|
||||
fieldWrapper.setProperty(property);
|
||||
fxFieldWrapperMap.put(field.getName(), fieldWrapper);
|
||||
}
|
||||
}
|
||||
fxEntityProxy.setStringPropertyMap(stringPropertyMap);
|
||||
fxEntityProxy.setStringFXFieldMethodMappingMap(stringFXFieldMethodMappingMap);
|
||||
fxEntityProxy.setFxFieldWrapperMap(fxFieldWrapperMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Property getFieldProperty(Object object,Field field) throws IllegalAccessException {
|
||||
private static Property getFieldProperty(Object object, Field field) throws IllegalAccessException {
|
||||
Class type = field.getType();
|
||||
Object value = field.get(object);
|
||||
|
||||
Property property = null;
|
||||
if(Boolean.class.equals(type)){
|
||||
|
||||
if (Boolean.class.equals(type) || boolean.class.equals(type)) {
|
||||
property = new SimpleBooleanProperty((Boolean) value);
|
||||
}else if(Double.class.equals(type)){
|
||||
} else if (Double.class.equals(type) || double.class.equals(type)) {
|
||||
property = new SimpleDoubleProperty((Double) value);
|
||||
}else if (Float.class.equals(type)){
|
||||
} else if (Float.class.equals(type) || float.class.equals(type)) {
|
||||
property = new SimpleFloatProperty((Float) value);
|
||||
}else if(Integer.class.equals(type)){
|
||||
} else if (Integer.class.equals(type) || int.class.equals(type)) {
|
||||
property = new SimpleIntegerProperty((Integer) value);
|
||||
}else if(Long.class.equals(type)){
|
||||
} else if (Long.class.equals(type) || long.class.equals(property)) {
|
||||
property = new SimpleLongProperty((Long) value);
|
||||
}else if(String.class.equals(type)){
|
||||
} else if (String.class.equals(type)) {
|
||||
property = new SimpleStringProperty((String) value);
|
||||
}else if(List.class.equals(type)){
|
||||
property = new SimpleListProperty(FXCollections.observableList((List)value));
|
||||
}else if(Object.class.equals(type)){
|
||||
} else if (List.class.isAssignableFrom(type)) {
|
||||
property = new SimpleListProperty(FXCollections.observableList((List) value));
|
||||
} else if (Object.class.isAssignableFrom(type)) {
|
||||
property = new SimpleObjectProperty(value);
|
||||
}
|
||||
return property;
|
||||
}
|
||||
private static Property getFieldDefalutProperty(Field field) throws IllegalAccessException{
|
||||
|
||||
private static Property getFieldDefaultProperty(Field field) throws IllegalAccessException {
|
||||
Class type = field.getType();
|
||||
Property property = null;
|
||||
if(Boolean.class.equals(type)){
|
||||
if (Boolean.class.equals(type) || boolean.class.equals(type)) {
|
||||
property = new SimpleBooleanProperty();
|
||||
}else if(Double.class.equals(type)){
|
||||
} else if (Double.class.equals(type) || double.class.equals(type)) {
|
||||
property = new SimpleDoubleProperty();
|
||||
}else if (Float.class.equals(type)){
|
||||
} else if (Float.class.equals(type) || float.class.equals(type)) {
|
||||
property = new SimpleFloatProperty();
|
||||
}else if(Integer.class.equals(type)){
|
||||
} else if (Integer.class.equals(type) || int.class.equals(type)) {
|
||||
property = new SimpleIntegerProperty();
|
||||
}else if(Long.class.equals(type)){
|
||||
} else if (Long.class.equals(type) || long.class.equals(property)) {
|
||||
property = new SimpleLongProperty();
|
||||
}else if(String.class.equals(type)){
|
||||
} else if (String.class.equals(type)) {
|
||||
property = new SimpleStringProperty();
|
||||
}else if(List.class.equals(type)){
|
||||
} else if (List.class.isAssignableFrom(type)) {
|
||||
property = new SimpleListProperty();
|
||||
}else if(Object.class.equals(type)){
|
||||
} else if (Object.class.isAssignableFrom(type)) {
|
||||
property = new SimpleObjectProperty();
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXController;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
|
||||
import cn.edu.scau.biubiusuisui.proxy.classProxy.FXControllerProxy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 8:12
|
||||
*/
|
||||
public class FXFactory {
|
||||
|
||||
|
||||
private FXFactory() {
|
||||
}
|
||||
|
||||
|
||||
public static void loadFXController(Class clazz) {
|
||||
getFXController(clazz, "");
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz) {
|
||||
FXBaseController fxBaseController = getFXController(clazz, "");
|
||||
return fxBaseController;
|
||||
}
|
||||
|
||||
public static FXBaseController getFXController(Class clazz, String controllerName) {
|
||||
FXBaseController fxBaseController = getFxBaseController(clazz, controllerName);
|
||||
return fxBaseController;
|
||||
}
|
||||
|
||||
private static void register(FXBaseController fxBaseController, FXBaseController fxBaseControllerProxy) {
|
||||
FXPlusContext.addController(fxBaseController);
|
||||
MessageQueue.getInstance().registerCosumer(fxBaseController, fxBaseControllerProxy);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clazz instance that extends by FXBaseController
|
||||
* @param controllerName
|
||||
* @return
|
||||
*/
|
||||
private static FXBaseController getFxBaseController(Class clazz, String controllerName) {
|
||||
Annotation[] annotations = clazz.getAnnotations();
|
||||
Boolean isController = false;
|
||||
URL fxmlPath;
|
||||
Boolean isWindow = false;
|
||||
FXWindow fxWindow = null;
|
||||
FXController fxController = null;
|
||||
//reflect and get FXController cn.edu.scau.biubiusuisui.annotation
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation.annotationType().equals(FXController.class)) {
|
||||
fxController = (FXController) annotation;
|
||||
isController = true;
|
||||
} else if (annotation.annotationType().equals(FXWindow.class)) {
|
||||
fxWindow = (FXWindow) annotation;
|
||||
isWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
Pane parent = null;
|
||||
|
||||
FXBaseController fxControllerProxy = null;
|
||||
FXBaseController fxBaseController = null;
|
||||
|
||||
if (isController) {
|
||||
String name = fxController.path();
|
||||
fxmlPath = clazz.getClassLoader().getResource(name);
|
||||
FXMLLoaderPlus fxmlLoader = new FXMLLoaderPlus(fxmlPath);
|
||||
try {
|
||||
// create a cn.edu.scau.biubiusuisui.proxy for monitoring methods
|
||||
fxBaseController = (FXBaseController) clazz.newInstance();
|
||||
FXControllerProxy controllerProxy = new FXControllerProxy();
|
||||
fxControllerProxy = (FXBaseController) controllerProxy.getInstance(fxBaseController);
|
||||
fxControllerProxy.setName(controllerName);
|
||||
fxBaseController.setName(controllerName);
|
||||
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fxmlLoader.setRoot(fxControllerProxy);
|
||||
fxmlLoader.setController(fxControllerProxy);
|
||||
try {
|
||||
parent = fxmlLoader.load();
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
//register
|
||||
register(fxBaseController, fxControllerProxy);
|
||||
if (isWindow) {
|
||||
Stage stage = new Stage();
|
||||
double preWidth = fxWindow.preWidth() == 0 ? parent.getPrefWidth() : fxWindow.preWidth();
|
||||
double preHeight = fxWindow.preHeight() == 0 ? parent.getPrefWidth() : fxWindow.preHeight();
|
||||
Scene scene = new Scene(fxControllerProxy, preWidth, preHeight);
|
||||
stage.setScene(scene);
|
||||
stage.setTitle(fxWindow.title());
|
||||
stage.show();
|
||||
}
|
||||
return fxControllerProxy;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 15:57
|
||||
*/
|
||||
|
||||
public class DefaultEventFunction implements ChangeListener {
|
||||
|
||||
public DefaultEventFunction() {}
|
||||
|
||||
@Override
|
||||
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/30 10:11
|
||||
*/
|
||||
public class DragWindowHandlerImpl implements EventHandler<MouseEvent> {
|
||||
//参考<a href="https://www.cnblogs.com/moonlightL/p/5982679.html"></a>
|
||||
private Stage stage; //primaryStage为start方法头中的Stage
|
||||
private double oldStageX;
|
||||
private double oldStageY;
|
||||
private double oldScreenX;
|
||||
private double oldScreenY;
|
||||
final int RESIZE_WIDTH = 5;// 判定是否为调整窗口状态的范围与边界距离
|
||||
private double MIN_WIDTH = 300;// 窗口最小宽度
|
||||
private double MIN_HEIGHT = 250;// 窗口最小高度
|
||||
boolean isRight;// 是否处于右边界调整窗口状态
|
||||
boolean isBottomRight;// 是否处于右下角调整窗口状态
|
||||
boolean isBottom;// 是否处于下边界调整窗口状态
|
||||
private Pane pane;
|
||||
private boolean fix = false;
|
||||
|
||||
public DragWindowHandlerImpl(Stage primaryStage, Pane pane,boolean fix) { //构造器
|
||||
this.stage = primaryStage;
|
||||
this.pane = pane;
|
||||
this.fix = fix;
|
||||
}
|
||||
|
||||
public DragWindowHandlerImpl(Stage stage, double MIN_WIDTH, double MIN_HEIGHT, Pane pane, boolean fix) {
|
||||
this.stage = stage;
|
||||
this.MIN_WIDTH = MIN_WIDTH;
|
||||
this.MIN_HEIGHT = MIN_HEIGHT;
|
||||
this.pane = pane;
|
||||
this.fix = fix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent e) {
|
||||
|
||||
if (e.getEventType() == MouseEvent.MOUSE_PRESSED) { //鼠标按下的事件
|
||||
this.oldStageX = this.stage.getX();
|
||||
this.oldStageY = this.stage.getY();
|
||||
this.oldScreenX = e.getScreenX();
|
||||
this.oldScreenY = e.getScreenY();
|
||||
|
||||
} else if (e.getEventType() == MouseEvent.MOUSE_DRAGGED) { //鼠标拖动的事件
|
||||
//
|
||||
double nextX = stage.getX();
|
||||
double nextY = stage.getY();
|
||||
double nextWidth = stage.getWidth();
|
||||
double nextHeight = stage.getHeight();
|
||||
if(!fix) {
|
||||
double x = e.getSceneX();
|
||||
double y = e.getSceneY();
|
||||
// 保存窗口改变后的x、y坐标和宽度、高度,用于预判是否会小于最小宽度、最小高度
|
||||
|
||||
|
||||
if (isRight || isBottomRight) {// 所有右边调整窗口状态
|
||||
nextWidth = x;
|
||||
}
|
||||
if (isBottomRight || isBottom) {// 所有下边调整窗口状态
|
||||
nextHeight = y;
|
||||
}
|
||||
if (nextWidth <= MIN_WIDTH) {// 如果窗口改变后的宽度小于最小宽度,则宽度调整到最小宽度
|
||||
nextWidth = MIN_WIDTH;
|
||||
}
|
||||
if (nextHeight <= MIN_HEIGHT) {// 如果窗口改变后的高度小于最小高度,则高度调整到最小高度
|
||||
nextHeight = MIN_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
// 最后统一改变窗口的x、y坐标和宽度、高度,可以防止刷新频繁出现的屏闪情况
|
||||
if(isBottom ||isBottomRight ||isRight) {
|
||||
stage.setX(nextX);
|
||||
stage.setY(nextY);
|
||||
stage.setWidth(nextWidth);
|
||||
stage.setHeight(nextHeight);
|
||||
}else {
|
||||
this.stage.setX(e.getScreenX() - this.oldScreenX + this.oldStageX);
|
||||
this.stage.setY(e.getScreenY() - this.oldScreenY + this.oldStageY);
|
||||
}
|
||||
} else if (e.getEventType() == MouseEvent.MOUSE_MOVED) {
|
||||
if(!fix) {
|
||||
e.consume();
|
||||
double x = e.getSceneX();
|
||||
double y = e.getSceneY();
|
||||
double width = stage.getWidth();
|
||||
double height = stage.getHeight();
|
||||
Cursor cursorType = Cursor.DEFAULT;// 鼠标光标初始为默认类型,若未进入调整窗口状态,保持默认类型
|
||||
// 先将所有调整窗口状态重置
|
||||
isRight = isBottomRight = isBottom = false;
|
||||
if (y >= height - RESIZE_WIDTH) {
|
||||
if (x <= RESIZE_WIDTH) {// 左下角调整窗口状态
|
||||
|
||||
} else if (x >= width - RESIZE_WIDTH) {// 右下角调整窗口状态
|
||||
isBottomRight = true;
|
||||
cursorType = Cursor.SE_RESIZE;
|
||||
} else {// 下边界调整窗口状态
|
||||
isBottom = true;
|
||||
cursorType = Cursor.S_RESIZE;
|
||||
}
|
||||
} else if (x >= width - RESIZE_WIDTH) {// 右边界调整窗口状态
|
||||
isRight = true;
|
||||
cursorType = Cursor.E_RESIZE;
|
||||
}
|
||||
// 最后改变鼠标光标
|
||||
|
||||
pane.setCursor(cursorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 1:54
|
||||
*/
|
||||
public interface Draggale {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.edu.scau.biubiusuisui.function;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/30 10:40
|
||||
*/
|
||||
public class FXWindowParser {
|
||||
|
||||
public void parse(Stage stage, Pane fxControllerProxy, FXWindow fxWindow) {
|
||||
|
||||
stage.setTitle(fxWindow.title());
|
||||
|
||||
if (fxWindow.resizable()) {
|
||||
stage.setResizable(false);
|
||||
}
|
||||
|
||||
if (fxWindow.draggable()) {
|
||||
final int RESIZE_WIDTH = 5;// 判定是否为调整窗口状态的范围与边界距离
|
||||
EventHandler dragWindowHandler = new DragWindowHandlerImpl(stage, fxWindow.minWidth(), fxWindow.minHeight(), fxControllerProxy, fxWindow.resizable());
|
||||
fxControllerProxy.setOnMousePressed(dragWindowHandler);
|
||||
fxControllerProxy.setOnMouseDragged(dragWindowHandler);
|
||||
fxControllerProxy.setOnMouseMoved(dragWindowHandler);
|
||||
}
|
||||
stage.initStyle(fxWindow.style());
|
||||
}
|
||||
}
|
||||
@@ -19,31 +19,32 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MessageQueue {
|
||||
|
||||
|
||||
private static Map<String, List<FXMethodEntity>> receivers = new ConcurrentHashMap<>();
|
||||
private static Map<String, List<FXMethodEntity>> receivers = new ConcurrentHashMap<>(); //Map<主题,订阅了主题的所有方法>
|
||||
|
||||
private static MessageQueue messageQueue = null;
|
||||
|
||||
private MessageQueue(){ }
|
||||
private MessageQueue() {
|
||||
}
|
||||
|
||||
public static synchronized MessageQueue getInstance(){
|
||||
if(messageQueue == null){
|
||||
public static synchronized MessageQueue getInstance() {
|
||||
if (messageQueue == null) {
|
||||
messageQueue = new MessageQueue();
|
||||
}
|
||||
return messageQueue;
|
||||
}
|
||||
|
||||
public void registerCosumer(FXBaseController fxBaseController,FXBaseController fxBaseControllerProxy){
|
||||
public void registerConsumer(FXBaseController fxBaseController, FXBaseController fxBaseControllerProxy) {
|
||||
Class clazz = fxBaseController.getClass();
|
||||
Method [] methods = clazz.getDeclaredMethods();
|
||||
for(Method method : methods){
|
||||
Annotation[]annotations = method.getDeclaredAnnotations();
|
||||
for(Annotation annotation : annotations){
|
||||
if(FXReceiver.class.equals(annotation.annotationType())){
|
||||
FXReceiver receiver = (FXReceiver)annotation;
|
||||
FXMethodEntity fxMethodEntity = new FXMethodEntity(fxBaseControllerProxy,method);
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
Annotation[] annotations = method.getDeclaredAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
if (FXReceiver.class.equals(annotation.annotationType())) {
|
||||
// System.out.println("FXReceiver");
|
||||
FXReceiver receiver = (FXReceiver) annotation;
|
||||
FXMethodEntity fxMethodEntity = new FXMethodEntity(fxBaseControllerProxy, method);
|
||||
List<FXMethodEntity> fxMethodEntities = receivers.get(receiver.name());
|
||||
if(fxMethodEntities == null){
|
||||
if (fxMethodEntities == null) {
|
||||
fxMethodEntities = new ArrayList<>();
|
||||
}
|
||||
fxMethodEntities.add(fxMethodEntity);
|
||||
@@ -53,11 +54,12 @@ public class MessageQueue {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMsg(String id,Object msg) {
|
||||
public void sendMsg(String id, Object msg) {
|
||||
List<FXMethodEntity> lists = receivers.get(id);
|
||||
if (lists != null) {
|
||||
for (FXMethodEntity fxMethodEntity : lists) {
|
||||
Method method = fxMethodEntity.getMethod();
|
||||
method.setAccessible(true);
|
||||
FXBaseController fxBaseController = fxMethodEntity.getFxBaseController();
|
||||
if (method.getParameterCount() == 0) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package cn.edu.scau.biubiusuisui.proxy;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXSender;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
|
||||
import cn.edu.scau.biubiusuisui.stage.StageManager;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* This proxy class intercept Methods that has special annotation such as
|
||||
* FXSender which is a mark for message queue
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:03
|
||||
*/
|
||||
public class FXControllerProxy implements MethodInterceptor {
|
||||
|
||||
|
||||
FXBaseController target;
|
||||
|
||||
|
||||
public Object getInstance(FXBaseController target) {
|
||||
this.target = target;
|
||||
// System.out.println(target.toString());
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(this.target.getClass());
|
||||
enhancer.setCallback(this);
|
||||
Object proxy = enhancer.create();
|
||||
// target.* -> proxy.*
|
||||
inject(target, proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
|
||||
Object o1 = methodProxy.invokeSuper(o, objects); //获取该方法运行后的结果
|
||||
Annotation[] annotations = method.getDeclaredAnnotations();
|
||||
|
||||
for (Annotation annotation : annotations) {
|
||||
if (FXSender.class.equals(annotation.annotationType())) { // 拦截是否发送消息函数
|
||||
FXSender fxSender = (FXSender) annotation;
|
||||
// System.out.println("FXSender");
|
||||
String name = target.getName() + ":";
|
||||
// System.out.println("FXControllerProxy:" + name);
|
||||
if ("".equals(fxSender.name())) {
|
||||
name += method.getName();
|
||||
} else {
|
||||
name += fxSender.name();
|
||||
}
|
||||
MessageQueue.getInstance().sendMsg(name, o1);
|
||||
}
|
||||
if (FXRedirect.class.equals((annotation.annotationType()))) { //拦截是否重定向函数
|
||||
FXRedirect fxRedirect = (FXRedirect) annotation;
|
||||
if (fxRedirect.close()) { //关闭原窗口
|
||||
StageManager.getInstance().closeStage(target.getName());
|
||||
}
|
||||
StageManager.getInstance().redirectTo(o1);
|
||||
}
|
||||
}
|
||||
return o1;
|
||||
}
|
||||
|
||||
private void inject(Object target, Object proxy) {
|
||||
Class clazz = target.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object value = field.get(target);
|
||||
field.set(proxy, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.edu.scau.biubiusuisui.proxy.classProxy;
|
||||
package cn.edu.scau.biubiusuisui.proxy;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXFieldViewFieldMapping;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXFieldWrapper;
|
||||
import cn.edu.scau.biubiusuisui.utils.StringUtils;
|
||||
import javafx.beans.property.*;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
@@ -17,9 +17,7 @@ import java.util.Map;
|
||||
public class FXEntityProxy implements MethodInterceptor {
|
||||
|
||||
Object target;
|
||||
|
||||
private Map<String, Property> stringPropertyMap;
|
||||
private Map<String, FXFieldViewFieldMapping> stringFXFieldMethodMappingMap;
|
||||
private Map<String, FXFieldWrapper> fxFieldWrapperMap;
|
||||
|
||||
public Object getInstance(Object target) {
|
||||
this.target = target;
|
||||
@@ -41,32 +39,30 @@ public class FXEntityProxy implements MethodInterceptor {
|
||||
*/
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
|
||||
Object o1 = methodProxy.invokeSuper(o, objects);
|
||||
|
||||
Object o1 = methodProxy.invokeSuper(o, objects); //获取该方法运行后的结果
|
||||
String methodName = method.getName();
|
||||
String fieldName = null;
|
||||
if (methodName.length() >= 3) {
|
||||
fieldName = StringUtils.toInstanceName(methodName.substring(3));
|
||||
fieldName = StringUtils.toInstanceName(methodName.substring(3)); // 该method有可能是getter和setter方法,进行处理
|
||||
} else {
|
||||
return o1;
|
||||
}
|
||||
FXFieldViewFieldMapping fieldMethodMapping = stringFXFieldMethodMappingMap.get(fieldName);
|
||||
Property property = stringPropertyMap.get(fieldName);
|
||||
if(fieldMethodMapping == null || property == null){
|
||||
FXFieldWrapper fxFieldWrapper = fxFieldWrapperMap.get(fieldName);
|
||||
Property property = getPropertyByFieldName(fieldName);
|
||||
if (fxFieldWrapper == null || property == null) {
|
||||
return o1;
|
||||
}
|
||||
|
||||
Class type = fieldMethodMapping.getType();
|
||||
Class type = fxFieldWrapper.getType();
|
||||
if (methodName.startsWith("set")) {
|
||||
if(Boolean.class.equals(type)){
|
||||
if(Boolean.class.equals(type) || boolean.class.equals(type)){
|
||||
((SimpleBooleanProperty)property).set((Boolean)objects[0]);
|
||||
}else if(Double.class.equals(type)){
|
||||
}else if(Double.class.equals(type)||double.class.equals(type)){
|
||||
((SimpleDoubleProperty)property).set((Double)objects[0]);
|
||||
}else if (Float.class.equals(type)){
|
||||
}else if (Float.class.equals(type) || float.class.equals(type)){
|
||||
((SimpleFloatProperty)property).set((Float) objects[0]);
|
||||
}else if(Integer.class.equals(type)){
|
||||
}else if(Integer.class.equals(type) || int.class.equals(type)){
|
||||
((SimpleIntegerProperty)property).set((Integer) objects[0]);
|
||||
}else if(Long.class.equals(type)){
|
||||
}else if(Long.class.equals(type) ||long.class.equals(type)){
|
||||
((SimpleLongProperty)property).set((Long)objects[0]);
|
||||
}else if(String.class.equals(type)){
|
||||
((SimpleStringProperty)property).set((String)objects[0]);
|
||||
@@ -75,9 +71,9 @@ public class FXEntityProxy implements MethodInterceptor {
|
||||
((SimpleListProperty)(property)).add(objects[0]);
|
||||
}else if(methodName.startsWith("del")){
|
||||
((SimpleListProperty)(property)).remove(objects[0]);
|
||||
}else if(methodName.startsWith("cls")){
|
||||
((SimpleListProperty)(property)).clear();
|
||||
}
|
||||
|
||||
//修改
|
||||
return o1;
|
||||
}
|
||||
|
||||
@@ -90,22 +86,17 @@ public class FXEntityProxy implements MethodInterceptor {
|
||||
}
|
||||
|
||||
public Property getPropertyByFieldName(String name) {
|
||||
return stringPropertyMap.get(name);
|
||||
if (fxFieldWrapperMap.get(name) == null) {
|
||||
return null;
|
||||
}
|
||||
return fxFieldWrapperMap.get(name).getProperty();
|
||||
}
|
||||
|
||||
public Map<String, Property> getStringPropertyMap() {
|
||||
return stringPropertyMap;
|
||||
public Map<String, FXFieldWrapper> getFxFieldWrapperMap() {
|
||||
return fxFieldWrapperMap;
|
||||
}
|
||||
|
||||
public void setStringPropertyMap(Map<String, Property> stringPropertyMap) {
|
||||
this.stringPropertyMap = stringPropertyMap;
|
||||
}
|
||||
|
||||
public Map<String, FXFieldViewFieldMapping> getStringFXFieldMethodMappingMap() {
|
||||
return stringFXFieldMethodMappingMap;
|
||||
}
|
||||
|
||||
public void setStringFXFieldMethodMappingMap(Map<String, FXFieldViewFieldMapping> stringFXFieldMethodMappingMap) {
|
||||
this.stringFXFieldMethodMappingMap = stringFXFieldMethodMappingMap;
|
||||
public void setFxFieldWrapperMap(Map<String, FXFieldWrapper> fxFieldWrapperMap) {
|
||||
this.fxFieldWrapperMap = fxFieldWrapperMap;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package cn.edu.scau.biubiusuisui.proxy.classProxy;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXSender;
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
*
|
||||
* This proxy class intercept Methods that has special annotation such as
|
||||
* FXSender which is a mark for message queue
|
||||
*
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:03
|
||||
*/
|
||||
public class FXControllerProxy implements MethodInterceptor {
|
||||
|
||||
|
||||
FXBaseController target;
|
||||
|
||||
public Object getInstance(FXBaseController target) {
|
||||
this.target = target;
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(this.target.getClass());
|
||||
enhancer.setCallback(this);
|
||||
return enhancer.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
|
||||
Object o1 = methodProxy.invokeSuper(o, objects);
|
||||
Annotation []annotations = method.getDeclaredAnnotations();
|
||||
for(Annotation annotation : annotations){
|
||||
if(FXSender.class.equals(annotation.annotationType())){
|
||||
FXSender fxSender = (FXSender)annotation;
|
||||
String name = target.getName() +":";
|
||||
if("".equals(fxSender.name())){
|
||||
name += method.getName();
|
||||
}else{
|
||||
name += fxSender.name();
|
||||
}
|
||||
MessageQueue.getInstance().sendMsg(name,o1);
|
||||
}
|
||||
}
|
||||
return o1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.edu.scau.biubiusuisui.stage;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author suiyu_yang
|
||||
* @description 舞台管理器
|
||||
* @date 2019/12/3 15:43
|
||||
* @email suiyu_yang@163.com
|
||||
*/
|
||||
public class StageManager {
|
||||
private static StageManager stageManager = null;
|
||||
private static Map<String, FXBaseController> windows = new ConcurrentHashMap<>(); //
|
||||
|
||||
private StageManager() {
|
||||
|
||||
}
|
||||
|
||||
public static synchronized StageManager getInstance() {
|
||||
if (stageManager == null) {
|
||||
stageManager = new StageManager();
|
||||
}
|
||||
return stageManager;
|
||||
}
|
||||
|
||||
public void registerWindow(FXBaseController fxBaseControllerProxy) {
|
||||
if (fxBaseControllerProxy.isWindow()) {
|
||||
// System.out.println("StageController: "+(fxBaseControllerProxy.getStage() == null));
|
||||
windows.put(fxBaseControllerProxy.getName(), fxBaseControllerProxy);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeStage(String controllerName) {
|
||||
windows.get(controllerName).closeStage();
|
||||
}
|
||||
|
||||
public void redirectTo(Object controller) {
|
||||
// System.out.println("跳转->" + controller);
|
||||
windows.get(controller).showStage();
|
||||
}
|
||||
}
|
||||
19
src/main/java/cn/edu/scau/biubiusuisui/utils/BeanUtil.java
Normal file
19
src/main/java/cn/edu/scau/biubiusuisui/utils/BeanUtil.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package cn.edu.scau.biubiusuisui.utils;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.proxy.FXEntityProxy;
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/28 1:52
|
||||
*/
|
||||
public class BeanUtil {
|
||||
public static Property getPropertyByName(Object entity, String fieldName){
|
||||
FXEntityProxy fxEntityProxy = FXPlusContext.getProxyByBeanObject(entity);
|
||||
if(fxEntityProxy == null){
|
||||
return null;
|
||||
}
|
||||
return fxEntityProxy.getFxFieldWrapperMap().get(fieldName).getProperty();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package cn.edu.scau.biubiusuisui.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
@@ -12,22 +13,22 @@ import java.util.List;
|
||||
* @Date:2019/6/25 5:20
|
||||
*/
|
||||
public class ClassUtils {
|
||||
private ClassLoader cl;
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public ClassUtils() {
|
||||
cl = getClass().getClassLoader();
|
||||
classLoader = getClass().getClassLoader();
|
||||
}
|
||||
|
||||
private List<String> getAllFXControllerClassName(String base, List<String> nameList) {
|
||||
String splashPath = StringUtils.dotToSplash(base);
|
||||
URL url = cl.getResource(splashPath);
|
||||
URL url = classLoader.getResource(splashPath);
|
||||
String filePath = StringUtils.getRootPath(url);
|
||||
List<String> names = null;
|
||||
names = readFromDirectory(filePath);
|
||||
for (String name : names) {
|
||||
if (isClassFile(name)) {
|
||||
nameList.add(toFullyQualifiedName(name, base));
|
||||
} else if (isDirectory(name)){
|
||||
} else if (isDirectory(name)) {
|
||||
nameList = getAllFXControllerClassName(base + "." + name, nameList);
|
||||
}
|
||||
}
|
||||
@@ -48,9 +49,11 @@ public class ClassUtils {
|
||||
private static boolean isClassFile(String name) {
|
||||
return name.endsWith(".class");
|
||||
}
|
||||
private static boolean isDirectory(String name){
|
||||
|
||||
private static boolean isDirectory(String name) {
|
||||
return !name.contains(".");
|
||||
}
|
||||
|
||||
private static List<String> readFromDirectory(String path) {
|
||||
File file = new File(path);
|
||||
String[] names = file.list();
|
||||
@@ -62,8 +65,8 @@ public class ClassUtils {
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasDeclaredAnnotation(Class clazz, Class annotation){
|
||||
if(annotation == null){
|
||||
public static boolean hasDeclaredAnnotation(Class clazz, Class annotation) {
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
if (hasAnnotationInList(annotation, clazz.getDeclaredAnnotations())) return true;
|
||||
@@ -71,7 +74,7 @@ public class ClassUtils {
|
||||
}
|
||||
|
||||
public static boolean hasAnnotation(Class clazz, Class annotation) {
|
||||
if(annotation == null){
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
if (hasAnnotationInList(annotation, clazz.getAnnotations())) return true;
|
||||
@@ -79,16 +82,16 @@ public class ClassUtils {
|
||||
}
|
||||
|
||||
public static boolean hasAnnotationInList(Class annotation, Annotation[] annotations2) {
|
||||
if(getAnnotationInList(annotation,annotations2) == null){
|
||||
if (getAnnotationInList(annotation, annotations2) == null) {
|
||||
return false;
|
||||
}else{
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Annotation getAnnotationInList(Class annotation,Annotation[]annotations){
|
||||
if(annotations == null || annotation == null){
|
||||
return null;
|
||||
public static Annotation getAnnotationInList(Class annotation, Annotation[] annotations) {
|
||||
if (annotations == null || annotation == null) {
|
||||
return null;
|
||||
}
|
||||
for (Annotation annotation1 : annotations) {
|
||||
if (annotation1.annotationType().equals(annotation)) {
|
||||
@@ -97,4 +100,15 @@ public class ClassUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void copyField(Object target, Object base) {
|
||||
Class clazz = base.getClass();
|
||||
Class targetClass = target.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
|
||||
// Field field1 = targetClass.getField(field.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package cn.edu.scau.biubiusuisui.utils;
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 3:46
|
||||
*/
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public class StringUtils {
|
||||
@@ -61,21 +62,34 @@ public class StringUtils {
|
||||
return trimmed.substring(splashIndex);
|
||||
}
|
||||
|
||||
public static String getBaseClassName(String name){
|
||||
public static String getBaseClassName(String name) {
|
||||
int index = name.indexOf("$");
|
||||
if(index == -1){
|
||||
if (index == -1) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(0,index);
|
||||
// System.out.println(name.substring(0,index));
|
||||
return name.substring(0, index);
|
||||
}
|
||||
|
||||
|
||||
public static String toInstanceName(String name){
|
||||
/**
|
||||
* Object -> object ; Student -> student
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static String toInstanceName(String name) {
|
||||
String result = name.substring(0, 1).toLowerCase().concat(name.substring(1));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String toClassName(String name){
|
||||
/**
|
||||
* object -> Object ; student -> Student
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static String toClassName(String name) {
|
||||
String result = name.substring(0, 1).toUpperCase().concat(name.substring(1));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.PasswordField?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<fx:root prefHeight="400.0" prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.MainController">
|
||||
<children>
|
||||
<Button fx:id="addBtn" layoutX="432.0" layoutY="83.0" mnemonicParsing="false" onAction="#addWord" text="add" />
|
||||
<Button fx:id="delBtn" layoutX="432.0" layoutY="151.0" mnemonicParsing="false" onAction="#delWord" text="del" />
|
||||
<ListView fx:id="list" layoutX="42.0" layoutY="51.0" prefHeight="275.0" prefWidth="334.0" />
|
||||
</children>
|
||||
<fx:root id="haha" prefHeight="253.0" prefWidth="625.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.expressionDemo.Main2">
|
||||
<children>
|
||||
<Label fx:id="label" layoutX="33.0" layoutY="53.0" prefHeight="37.0" prefWidth="100.0" text="账号:">
|
||||
<font>
|
||||
<Font size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="usr" layoutX="162.0" layoutY="57.0" prefHeight="30.0" prefWidth="277.0" />
|
||||
<Button fx:id="resetBtn" layoutX="33.0" layoutY="187.0" mnemonicParsing="false" onAction="#reset" text="重置" />
|
||||
<Label layoutX="33.0" layoutY="116.0" prefHeight="27.0" prefWidth="69.0" text="密码">
|
||||
<font>
|
||||
<Font size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button fx:id="loginBtn" layoutX="370.0" layoutY="187.0" mnemonicParsing="false" onAction="#login" text="登录" />
|
||||
<Label fx:id="usrMsg" layoutX="450.0" layoutY="62.0" prefHeight="19.0" prefWidth="157.0" />
|
||||
<PasswordField fx:id="psw" layoutX="162.0" layoutY="128.0" prefHeight="30.0" prefWidth="277.0" />
|
||||
<Label fx:id="pswMsg" layoutX="450.0" layoutY="133.0" prefHeight="20.0" prefWidth="157.0" />
|
||||
</children>
|
||||
</fx:root>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import cn.edu.scau.biubiusuisui.example.actionDemo.MainController?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
|
||||
<fx:root prefHeight="400.0" prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.MainController">
|
||||
<fx:root prefHeight="709.0" prefWidth="995.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.expressionDemo.Main2">
|
||||
<children>
|
||||
<Button fx:id="btn" layoutX="266.0" layoutY="179.0" mnemonicParsing="false" text="Button" />
|
||||
<Button fx:id="btn" layoutX="793.0" layoutY="146.0" mnemonicParsing="false" text="Button" />
|
||||
<MainController layoutX="85.0" layoutY="123.0" />
|
||||
</children>
|
||||
</fx:root>
|
||||
|
||||
29
src/main/resources/SpringExpressionDemo.fxml
Normal file
29
src/main/resources/SpringExpressionDemo.fxml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.PasswordField?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<fx:root id="haha" prefHeight="253.0" prefWidth="625.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.springExpressionDemo.SpringExpressionDemoController">
|
||||
<children>
|
||||
<Label fx:id="label" layoutX="33.0" layoutY="53.0" prefHeight="37.0" prefWidth="100.0" text="账号:">
|
||||
<font>
|
||||
<Font size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="usr" layoutX="162.0" layoutY="57.0" prefHeight="30.0" prefWidth="277.0" />
|
||||
<Button fx:id="resetBtn" layoutX="33.0" layoutY="187.0" mnemonicParsing="false" onAction="#reset" text="重置" />
|
||||
<Label layoutX="33.0" layoutY="116.0" prefHeight="27.0" prefWidth="69.0" text="密码">
|
||||
<font>
|
||||
<Font size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button fx:id="loginBtn" layoutX="370.0" layoutY="187.0" mnemonicParsing="false" onAction="#login" text="登录" />
|
||||
<Label fx:id="usrMsg" layoutX="450.0" layoutY="62.0" prefHeight="19.0" prefWidth="157.0" />
|
||||
<PasswordField fx:id="psw" layoutX="162.0" layoutY="128.0" prefHeight="30.0" prefWidth="277.0" />
|
||||
<Label fx:id="pswMsg" layoutX="450.0" layoutY="133.0" prefHeight="20.0" prefWidth="157.0" />
|
||||
</children>
|
||||
</fx:root>
|
||||
16
src/main/resources/actionDemo/actionDemo.fxml
Normal file
16
src/main/resources/actionDemo/actionDemo.fxml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<fx:root prefHeight="191.0" prefWidth="607.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171"
|
||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.actionDemo.MainController">
|
||||
<children>
|
||||
<TextField fx:id="time" layoutX="108.0" layoutY="28.0" prefHeight="28.0" prefWidth="330.0"/>
|
||||
<Label fx:id="us" layoutX="108.0" layoutY="75.0" prefHeight="24.0" prefWidth="330.0" text="US:"/>
|
||||
<Label fx:id="jp" layoutX="108.0" layoutY="107.0" prefHeight="24.0" prefWidth="330.0" text="JP:"/>
|
||||
<Label fx:id="uk" layoutX="108.0" layoutY="142.0" prefHeight="24.0" prefWidth="330.0" text="UK:"/>
|
||||
<Label layoutX="67.0" layoutY="77.0" text="US"/>
|
||||
<Label layoutX="69.0" layoutY="109.0" text="JP"/>
|
||||
<Label layoutX="66.0" layoutY="144.0" text="UK"/>
|
||||
</children>
|
||||
</fx:root>
|
||||
20
src/main/resources/applicationContext.xml
Normal file
20
src/main/resources/applicationContext.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<!-- <bean id="..." class="...">
|
||||
collaborators and configuration for this bean go here
|
||||
</bean>
|
||||
<bean id="..." class="...">
|
||||
collaborators and configuration for this bean go here
|
||||
</bean> -->
|
||||
|
||||
<!-- more bean definitions go here
|
||||
UserDao ud = new UserDao();
|
||||
-->
|
||||
<context:component-scan base-package="cn.edu.scau.biubiusuisui"/>
|
||||
|
||||
</beans>
|
||||
15
src/main/resources/firstDemo/firstDemo.fxml
Normal file
15
src/main/resources/firstDemo/firstDemo.fxml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<fx:root prefHeight="400.0" prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171"
|
||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.firstDemo.MainController">
|
||||
<children>
|
||||
<Button fx:id="addHelloButton" layoutX="432.0" layoutY="83.0" mnemonicParsing="false" onAction="#addWord"
|
||||
text="add"/>
|
||||
<Button fx:id="deleteHelloButton" layoutX="432.0" layoutY="151.0" mnemonicParsing="false" onAction="#delWord"
|
||||
text="del"/>
|
||||
<ListView fx:id="list" layoutX="42.0" layoutY="51.0" prefHeight="275.0" prefWidth="334.0"/>
|
||||
</children>
|
||||
</fx:root>
|
||||
11
src/main/resources/listDemo/listDemo.fxml
Normal file
11
src/main/resources/listDemo/listDemo.fxml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<fx:root prefHeight="600.0" prefWidth="800.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.listDemo.MainController">
|
||||
<children>
|
||||
<ListView fx:id="userNameListView" layoutX="144.0" layoutY="46.0" prefHeight="457.0" prefWidth="423.0"/>
|
||||
<Button layoutX="602.0" layoutY="489.0" mnemonicParsing="false" onAction="#addUserName" text="addUserName"/>
|
||||
</children>
|
||||
</fx:root>
|
||||
21
src/main/resources/moveDemo.fxml
Normal file
21
src/main/resources/moveDemo.fxml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
|
||||
<fx:root prefHeight="600.0" prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.moveDemo.Main2">
|
||||
<children>
|
||||
<Circle fx:id="circle" fill="DODGERBLUE" layoutX="99.0" layoutY="191.0" radius="39.0" stroke="BLACK" strokeType="INSIDE" />
|
||||
<TextField layoutX="199.0" layoutY="310.0" text="123" fx:id="xinput" />
|
||||
<TextField fx:id="yinput" layoutX="199.0" layoutY="367.0" text="123" />
|
||||
<Label layoutX="14.0" layoutY="315.0" text="X" />
|
||||
<Label layoutX="14.0" layoutY="372.0" text="Y" />
|
||||
<Button layoutX="148.0" layoutY="310.0" mnemonicParsing="false" text="-" fx:id="xSub" onAction="#subX"/>
|
||||
<Button layoutX="415.0" layoutY="310.0" mnemonicParsing="false" text="+" fx:id="xAdd" onAction="#addX"/>
|
||||
<Button fx:id="ySub" layoutX="148.0" layoutY="367.0" mnemonicParsing="false" text="-" onAction="#subY"/>
|
||||
<Button fx:id="yAdd" layoutX="415.0" layoutY="367.0" mnemonicParsing="false" text="+" onAction="#addY"/>
|
||||
</children>
|
||||
</fx:root>
|
||||
18
src/main/resources/mqDemo/main.fxml
Normal file
18
src/main/resources/mqDemo/main.fxml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import cn.edu.scau.biubiusuisui.example.mqDemo.TopBarController?>
|
||||
<?import javafx.scene.control.TextArea?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/10.0.2-internal"
|
||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.mqDemo.MainController">
|
||||
<children>
|
||||
<VBox prefHeight="400.0" prefWidth="600.0">
|
||||
<children>
|
||||
<TopBarController/>
|
||||
<TextArea fx:id="outTA" editable="false" prefHeight="350.0" prefWidth="600.0" wrapText="true"/>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</fx:root>
|
||||
20
src/main/resources/mqDemo/topBar.fxml
Normal file
20
src/main/resources/mqDemo/topBar.fxml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0"
|
||||
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="cn.edu.scau.biubiusuisui.example.mqDemo.TopBarController">
|
||||
<children>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="600.0" spacing="20.0">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#indexClick" prefHeight="50.0" prefWidth="100.0" text="首页"/>
|
||||
<Button mnemonicParsing="false" onAction="#scoreClick" prefHeight="50.0" prefWidth="100.0" text="积分中心"/>
|
||||
<Button mnemonicParsing="false" onAction="#questionClick" prefHeight="50.0" prefWidth="100.0"
|
||||
text="问答中心"/>
|
||||
<Button mnemonicParsing="false" onAction="#selfClick" prefHeight="50.0" prefWidth="100.0" text="个人中心"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</fx:root>
|
||||
16
src/main/resources/redirectDemo/dialog.fxml
Normal file
16
src/main/resources/redirectDemo/dialog.fxml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="400.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Label layoutX="103.0" layoutY="100.0" text="这是一个弹窗......">
|
||||
<font>
|
||||
<Font size="24.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</fx:root>
|
||||
51
src/main/resources/redirectDemo/login.fxml
Normal file
51
src/main/resources/redirectDemo/login.fxml
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0"
|
||||
prefWidth="800.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="cn.edu.scau.biubiusuisui.example.redirectDemo.LoginController">
|
||||
<children>
|
||||
<VBox alignment="CENTER" layoutX="265.0" layoutY="100.0" prefHeight="300.0" prefWidth="250.0" spacing="10.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="250.0" text="登录">
|
||||
<font>
|
||||
<Font size="27.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="50.0" text="用户名:"/>
|
||||
<TextField fx:id="usernameTF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="50.0" text="密码:"/>
|
||||
<PasswordField fx:id="passwordPF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_RIGHT" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label onMouseClicked="#registerClick" prefHeight="50.0" text="还没有账户,去注册" underline="true">
|
||||
<HBox.margin>
|
||||
<Insets right="10.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_RIGHT" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#redirectToDialog" text="测试弹窗的按钮">
|
||||
<HBox.margin>
|
||||
<Insets right="20.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</fx:root>
|
||||
8
src/main/resources/redirectDemo/register.css
Normal file
8
src/main/resources/redirectDemo/register.css
Normal file
@@ -0,0 +1,8 @@
|
||||
#content {
|
||||
alignment: center;
|
||||
}
|
||||
|
||||
#content .label {
|
||||
-fx-pref-height: 50;
|
||||
-fx-pref-width: 100;
|
||||
}
|
||||
69
src/main/resources/redirectDemo/register.fxml
Normal file
69
src/main/resources/redirectDemo/register.fxml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0"
|
||||
prefWidth="600.0" stylesheets="@register.css" type="Pane" xmlns="http://javafx.com/javafx/8.0.171"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="cn.edu.scau.biubiusuisui.example.redirectDemo.RegisterController">
|
||||
<children>
|
||||
<VBox alignment="CENTER" layoutX="100.0" layoutY="55.0" prefHeight="350.0" prefWidth="400.0">
|
||||
<children>
|
||||
<HBox prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="404.0" text="注册">
|
||||
<font>
|
||||
<Font size="24.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
<VBox id="content" alignment="CENTER" prefHeight="350.0" prefWidth="400.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label text="用户名:"/>
|
||||
<TextField fx:id="usernameTF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label text="电子邮箱:"/>
|
||||
<TextField fx:id="emailTF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label text="密码:"/>
|
||||
<PasswordField fx:id="passwordPF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label text="确认密码:"/>
|
||||
<PasswordField fx:id="confirmPasswordPF"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_RIGHT" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label minWidth="150.0" onMouseClicked="#loginClick" prefWidth="151.0" text="已有账号,前往登录"
|
||||
underline="true"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_RIGHT" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#registerClick" text="注册">
|
||||
<HBox.margin>
|
||||
<Insets right="50.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</fx:root>
|
||||
33
src/main/resources/redirectDemo/success.fxml
Normal file
33
src/main/resources/redirectDemo/success.fxml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0"
|
||||
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="cn.edu.scau.biubiusuisui.example.redirectDemo.SuccessController">
|
||||
<children>
|
||||
<VBox alignment="CENTER" layoutX="158.0" layoutY="80.0" prefHeight="300.0" prefWidth="250.0" spacing="10.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="250.0" text="登录成功">
|
||||
<font>
|
||||
<Font size="27.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="50.0" text="用户名:"/>
|
||||
<Label fx:id="usernameLabel" alignment="CENTER" prefHeight="50.0" prefWidth="150.0"/>
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="50.0" prefWidth="50.0" text="密码:"/>
|
||||
<Label fx:id="passwordLabel" alignment="CENTER" prefHeight="50.0" prefWidth="150.0"/>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button layoutX="421.0" layoutY="367.0" mnemonicParsing="false" onAction="#redirectToLogin" text="返回主界面"/>
|
||||
</children>
|
||||
</fx:root>
|
||||
12
src/main/resources/springDemo.fxml
Normal file
12
src/main/resources/springDemo.fxml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
|
||||
<fx:root id="haha" prefHeight="403.0" prefWidth="625.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.springDemo.SpringController">
|
||||
<children>
|
||||
<Label fx:id="label" layoutX="18.0" layoutY="166.0" prefHeight="68.0" prefWidth="304.0" text="我是控制器属性" />
|
||||
<Button layoutX="52.0" layoutY="98.0" onAction="#add" prefHeight="30.0" prefWidth="129.0" text="控制器1的按钮" />
|
||||
</children>
|
||||
</fx:root>
|
||||
16
src/main/resources/springDemo2.fxml
Normal file
16
src/main/resources/springDemo2.fxml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import cn.edu.scau.biubiusuisui.example.springDemo.SpringController?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
|
||||
<fx:root id="haha" prefHeight="629.0" prefWidth="934.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.springDemo2.SpringController2">
|
||||
<children>
|
||||
<SpringController layoutX="20.0" layoutY="129.0" fx:id="springController"/>
|
||||
<Button layoutX="135.0" layoutY="552.0" mnemonicParsing="false" text="Button" onAction="#test"/>
|
||||
<Label layoutX="14.0" layoutY="81.0" text="Controller属性" />
|
||||
<Label layoutX="20.0" layoutY="557.0" text="本控制器属性" />
|
||||
<Label layoutX="385.0" layoutY="25.0" text="两个控制器之间信号传递" />
|
||||
</children>
|
||||
</fx:root>
|
||||
@@ -1,14 +1,19 @@
|
||||
import cn.edu.scau.biubiusuisui.example.Student;
|
||||
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/25 2:11
|
||||
*/
|
||||
public class MainTest {
|
||||
|
||||
public void testMethod(String a,int b){
|
||||
|
||||
}
|
||||
@Test
|
||||
public void test(){
|
||||
public void test() throws NoSuchMethodException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.edu.scau.biubiusuisui.expression;
|
||||
|
||||
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/24 11:55
|
||||
*/
|
||||
public class ExpressionParserTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.edu.scau.biubiusuisui.expression.data;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.annotation.FXValue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/7/27 3:13
|
||||
*/
|
||||
public class ExpressionParserTest {
|
||||
|
||||
private ExpressionParser expressionParser;
|
||||
@Before
|
||||
public void init(){
|
||||
expressionParser = new ExpressionParser(null);
|
||||
}
|
||||
@Test
|
||||
public void parse() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getArgs() throws NoSuchMethodException {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
package cn.edu.scau.biubiusuisui.factory;
|
||||
|
||||
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
|
||||
import cn.edu.scau.biubiusuisui.example.Student;
|
||||
import javafx.beans.property.Property;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author jack
|
||||
* @Date:2019/6/28 1:32
|
||||
@@ -34,18 +29,17 @@ public class FXEntityFactoryTest {
|
||||
|
||||
@Test
|
||||
public void createJavaBeanProxy() {
|
||||
Student student = new Student();
|
||||
student.setName("NAME");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createJavaBeanProxy2() throws InstantiationException, IllegalAccessException {
|
||||
Student student1 = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
|
||||
System.out.println(student1);
|
||||
FXPlusContext.getProryByBeanObject(student1).getStringPropertyMap().forEach((k,v)->{
|
||||
System.out.println("k " +k +"v" + v);
|
||||
});
|
||||
student1.setName("Jack");
|
||||
// Student student1 = (Student) FXEntityFactory.warpFxBean(Student.class);
|
||||
// System.out.println(student1);
|
||||
// FXPlusContext.getProxyByBeanObject(student1).getStringPropertyMap().forEach((k, v)->{
|
||||
// System.out.println("k " +k +"v" + v);
|
||||
// });
|
||||
// student1.setName("Jack");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user