9 Commits

Author SHA1 Message Date
suisui
8a7efd76c6 fix:修复打包后读取jar包资源文件异常 2021-09-16 23:43:55 +08:00
suisui
96a58bcda5 update:更新sonatype配置 2021-09-15 23:58:58 +08:00
suisui
34ddd6f26e update:补充部分注释 2021-09-06 09:02:24 +08:00
suisui
38dc53b484 fix #I1HKWY 2021-09-05 23:21:15 +08:00
suisui
547c036cdb 1.2.1-SNAPSHOT 2021-09-05 23:07:24 +08:00
suisui
a69651447c fix:修复读取中文路径文件异常 2021-09-05 22:58:16 +08:00
yangsuiyu
f6189b1bf9 支持动态修改窗口标题setWindowTitle、窗口图标setIcon、窗口可拖拽拖放setDragAndResize的接口 2020-08-29 17:50:33 +08:00
yangsuiyu
d139cbe3c5 1.修复IDEA中无法加载resources文件夹的Bug;2.修改多语言Demo 2020-08-28 23:20:34 +08:00
yangsuiyu
5b7131febf 更新READNE文档 2020-05-08 00:16:38 +08:00
40 changed files with 472 additions and 166 deletions

3
.gitignore vendored
View File

@@ -1 +1,2 @@
.idea
.idea
*.iml

View File

@@ -8,7 +8,7 @@ Language: [中文](README.md)
- [The Process of Developing](#the-process-of-developing)
[Maven Repository](#maven-repository)
~~[Maven Repository](#maven-repository)~~
[Git](#git)
@@ -70,8 +70,6 @@ The framework is not the framework for beautifying UI, but to simplify the step
### The Process of Developing
Our project has suspended update from Nov. 25, 2019, and the next release will be updated to 2.0. We try to provides more data binding operations and optimize performance.
- [x] Modularization
- [x] Integration with Spring
- [x] Signal Mechanism
@@ -93,7 +91,7 @@ Our project has suspended update from Nov. 25, 2019, and the next release will b
<dependency>
<groupId>com.gitee.Biubiuyuyu</groupId>
<artifactId>javafx-plus</artifactId>
<version>1.0.0-RELEASE</version>
<version>1.2.1-SNAPSHOT</version>
</dependency>
```
@@ -936,7 +934,7 @@ When an FXController needs to be internationalized and localized, you need to ad
```java
@FXWindow(mainStage = true, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
public class ChineseController extends FXBaseController {
@FXML
public void clickToOtherLanguage() {
@@ -952,7 +950,7 @@ public class ChineseController extends FXBaseController {
```java
@FXWindow(mainStage = false, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.ENGLISH)
public class EnglishController extends FXBaseController {
@FXML
public void clickToOtherLanguage() {
@@ -1024,7 +1022,7 @@ register.email=\u90ae\u7bb1
#### Example
The sample code is in `cn.edu.scau.biubiusuisui.example.languageDemo`, the running result as follows:
The sample code is in `cn.edu.scau.biubiusuisui.example.langDemo`, the running result as follows:
![language_demo](README.en/language_demo.gif)

View File

@@ -8,7 +8,7 @@
- [开发进程](#开发进程)
[Maven仓库地址](#Maven仓库地址)
~~[Maven仓库地址](#Maven仓库地址)~~
[Git地址](#git地址)
@@ -70,8 +70,6 @@
![JavaFx-Plus](README/JavaFX-Plus.png)
### 开发进程
2019年11月25日起项目暂停更新将会下次发布将会升级为2.0版本,到时候将会提供更多数据绑定操作,以及优化性能。
- [x] 模块化
- [x] 与Spring的融合
- [x] 信号机制
@@ -88,11 +86,14 @@
- [ ] 优化性能
## Maven仓库地址
maven仓库中的JavaFX-Plus版本是较旧版本建议使用最新发行版。
```xml
<dependency>
<groupId>com.gitee.Biubiuyuyu</groupId>
<artifactId>javafx-plus</artifactId>
<version>1.0.0-RELEASE</version>
<version>1.2.1-SNAPSHOT</version>
</dependency>
```
## Git地址
@@ -959,7 +960,7 @@ public enum FXPlusLocale {
```java
@FXWindow(mainStage = true, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
public class ChineseController extends FXBaseController {
@FXML
public void clickToOtherLanguage() {
@@ -975,7 +976,7 @@ public class ChineseController extends FXBaseController {
```java
@FXWindow(mainStage = false, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.ENGLISH)
public class EnglishController extends FXBaseController {
@FXML
public void clickToOtherLanguage() {
@@ -1047,7 +1048,7 @@ register.email=\u90ae\u7bb1
#### 示例演示
示例代码在`cn.edu.scau.biubiusuisui.example.languageDemo`中,运行可得:
示例代码在`cn.edu.scau.biubiusuisui.example.langDemo`中,运行可得:
![language_demo](README/language_demo.gif)
@@ -1328,6 +1329,10 @@ public class Student {
4. 完善JavaFX-Plus生命周期
5. 新增日志log模块
6. 新增语言国际化操作
7. 新增测试生命周期LifeDemo示例和测试国际化的LanguageDemo示例代码
7. 新增测试生命周期LifeDemo示例和测试国际化的LangDemo示例代码
8. 规范化代码和更新README
## v1.3.0 TODO
1. 开放动态修改窗口标题setWindowTitles、窗口图标setIcon、窗口可拖拽缩放setDragAndResize的接口

106
pom.xml
View File

@@ -4,11 +4,12 @@
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.1.1-RELEASE</version>
<packaging>jar</packaging>
<version>1.2.1-SNAPSHOT</version>
<!-- packaging为pom时不会加载resources 故注释-->
<!-- <packaging>pom</packaging>-->
<parent>
<groupId>org.sonatype.oss</groupId>
@@ -18,47 +19,83 @@
<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>
<properties>
<cglib.version>3.1</cglib.version>
<junit.version>4.13.1</junit.version>
<slf4j-log4j12.version>1.7.21</slf4j-log4j12.version>
<tomcat.version>9.0.48</tomcat.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-io.version>2.11.0</commons-io.version>
</properties>
<dependencies>
<!-- 第三方动态代理库-->
<!-- 第三方动态代理库 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
<version>${cglib.version}</version>
</dependency>
<!-- Junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- log4j 日志-->
<!-- log4j 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
<version>${slf4j-log4j12.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.29</version>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>javafx-plus</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>javafx-plus</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<build>
<!--配置Maven 对resource文件 过滤 -->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.fxml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -66,6 +103,7 @@
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<!-- 过期的方法的警告-->
<arg>-Xlint:deprecation</arg>
@@ -87,6 +125,20 @@
</descriptorRefs>
</configuration>
</plugin>
<!-- Source 开源 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -95,20 +147,6 @@
<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>

View File

@@ -12,6 +12,7 @@ import cn.edu.scau.biubiusuisui.utils.ClassUtil;
import cn.edu.scau.biubiusuisui.utils.FileUtil;
import cn.edu.scau.biubiusuisui.utils.LogUtil;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
@@ -25,7 +26,6 @@ import java.util.Set;
*/
public class FXPlusApplication {
private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXPlusApplication.class);
// Application
private static FXWindowParser windowAnnotationParser = new FXWindowParser();
@@ -37,7 +37,11 @@ public class FXPlusApplication {
public static void start(Class clazz, BeanBuilder beanBuilder) {
logger.info("starting JavaFX-Plus Application");
logger.info("\n" + FileUtil.readFileFromResources("banner.txt"));
try {
logger.info("\n" + FileUtil.readFileFromResources("banner.txt"));
} catch (UnsupportedEncodingException e) {
logger.error("\n read classpath:banner.txt error, you can ignore it");
}
// 初始化日志路径
LogUtil.initLog4jBase();
@@ -56,15 +60,15 @@ public class FXPlusApplication {
for (String dir : sets) {
logger.info("scanning directory: " + dir);
ClassUtil classUtil = new ClassUtil();
List<String> temps = classUtil.scanAllClassName(dir);
for (String className : temps) {
try {
List<String> temps = null;
try {
temps = classUtil.scanAllClassName(dir);
for (String className : temps) {
logger.info("loading class: " + className);
loadFXPlusClass(className, beanBuilder);
} catch (ClassNotFoundException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
} catch (UnsupportedEncodingException | ClassNotFoundException exception) {
logger.error("{}", exception);
}
}
}

View File

@@ -4,14 +4,22 @@ import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
import cn.edu.scau.biubiusuisui.function.DragWindowHandlerImpl;
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
import cn.edu.scau.biubiusuisui.utils.FileUtil;
import cn.edu.scau.biubiusuisui.utils.IFxPlusConstants;
import cn.edu.scau.biubiusuisui.utils.ResourceBundleUtil;
import cn.edu.scau.biubiusuisui.utils.StringUtil;
import javafx.event.EventHandler;
import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.HashMap;
@@ -19,7 +27,7 @@ import java.util.Map;
import java.util.ResourceBundle;
/**
/*
* In JavaFX-Plus Framework Controller
* We use MVC model
* V means view which stand for fxml
@@ -36,7 +44,7 @@ import java.util.ResourceBundle;
* @since JavaFX2.0 JDK1.8
*/
public class FXBaseController extends Pane {
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBaseController.class);
private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXBaseController.class);
protected String name = "";
private Stage stage;
@@ -45,7 +53,8 @@ public class FXBaseController extends Pane {
/**
* @description 用于携带信息数据
* <p>description 用于携带信息数据</p>
*
* @version 1.2
*/
private Map<String, Object> query = new HashMap<>();
@@ -69,7 +78,7 @@ public class FXBaseController extends Pane {
// 添加赋予是否为窗口的逻辑
if (annotation.annotationType().equals(FXWindow.class)) {
fxWindow = (FXWindow) annotation;
isWindow = true;
this.isWindow = true;
}
}
//load fxml file to show panel in scene builder
@@ -173,13 +182,16 @@ public class FXBaseController extends Pane {
* 唤起舞台
*/
public void showStage() {
if (isWindow) {
if (this.isWindow) {
this.stage.show();
}
}
/**
* 显示并等待
*/
public void showAndWait() {
if (isWindow) {
if (this.isWindow) {
this.stage.showAndWait();
}
}
@@ -188,7 +200,7 @@ public class FXBaseController extends Pane {
* 关闭舞台
*/
public void closeStage() {
if (isWindow) {
if (this.isWindow) {
this.stage.close();
}
}
@@ -198,16 +210,80 @@ public class FXBaseController extends Pane {
* @version 1.2
*/
public void hideStage() {
if (isWindow) {
if (this.isWindow) {
this.stage.setIconified(true);
}
}
/**
* <p>description: 开放设置窗口标题 </p>
*
* @param title 标题
* @return true--修改标题成功 false--修改失败
* @version 1.3
*/
public final void setWindowTitle(String title) {
if (this.isWindow) {
this.stage.setTitle(title);
logger.info("setting title of window");
} else {
logger.warn("the controller is not window");
}
}
/**
* <p>description: 开放设置窗口图标</p>
*
* @param icon String 图标URL地址需要放在resources文件下或项目根目录下
*/
public final void setIcon(String icon) {
if (this.isWindow) {
if (!"".equals(icon)) {
try {
URL iconUrl = new FileUtil().getFilePathFromResources(icon);
if (iconUrl != null) {
if (new File(StringUtil.getRootPath(iconUrl)).exists()) {
this.stage.getIcons().clear();
this.stage.getIcons().add(new Image(icon));
} else {
logger.warn("the icon file has not existed");
}
} else {
logger.warn("the icon file has not existed");
}
} catch (ProtocolNotSupport | UnsupportedEncodingException exception) {
logger.error(exception.getMessage(), exception);
}
}
}
}
/**
* <p>Description 开放是否允许窗口可拖拽和缩放的接口</p>
*
* @param draggable 可拖拽
* @param resizable 可缩放
*/
public final void setDragAndResize(boolean draggable, boolean resizable) {
this.stage.setResizable(resizable);
if (draggable || resizable) {
EventHandler dragWindowHandler = new DragWindowHandlerImpl(stage, this, draggable, resizable);
this.setOnMousePressed(dragWindowHandler);
this.setOnMouseDragged(dragWindowHandler);
this.setOnMouseMoved(dragWindowHandler);
}
}
/**
* 获取Controller名字
*
* @return name
*/
public String getName() {
if ("".equals(name) || name == null) { // 原本无“name == null”判断条件会出错
return StringUtil.getBaseClassName(getClass().getSimpleName());
} else {
return StringUtil.getBaseClassName(getClass().getSimpleName()) + "#" + name;
return StringUtil.getBaseClassName(getClass().getSimpleName()) + IFxPlusConstants.CONTROLLER_NAME_SEPARATOR + name;
}
}
@@ -224,11 +300,11 @@ public class FXBaseController extends Pane {
}
public boolean isWindow() {
return isWindow;
return this.isWindow;
}
public void setWindow(boolean window) {
isWindow = window;
this.isWindow = window;
}
public Stage getStage() {

View File

@@ -12,9 +12,13 @@ import java.lang.reflect.Method;
* @since JavaFX2.0 JDK1.8
*/
public class FXMethodEntity {
/**
* 所属Controller
*/
private FXBaseController fxBaseController;
/**
* 实际方法
*/
private Method method;
public FXMethodEntity(FXBaseController fxBaseController, Method method) {

View File

@@ -33,6 +33,8 @@ public class FXPlusContext {
controllers = new LinkedList<>();
}
controllers.add(fxBaseController);
// @since 1.2.1 fix: 没有将controller真正注册到context的异常
controllerContext.put(fxBaseController.getName(), controllers);
}

View File

@@ -11,8 +11,19 @@ import java.util.Map;
* @since JavaFX2.0 JDK1.8
*/
public class FXRedirectParam {
/**
* 跳转的目标Controller
*/
private String toController;
/**
* query方式的参数, like: helloController?name=JavaFx-Plus&msg=helloWorld
* the map will store: { name -> JavaFx-Plus, msg -> helloWorld}
*/
private Map<String, Object> query = new HashMap<>();
/**
* param方式的参数会以map方式传递给目标Controller
*/
private Map<String, Object> params = new HashMap<>();
public FXRedirectParam(String toController) {

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.example.languageDemo;
package cn.edu.scau.biubiusuisui.example.langDemo;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
@@ -15,8 +15,11 @@ import javafx.fxml.FXML;
* @since JDK1.8
*/
@FXWindow(mainStage = true, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.SIMPLIFIED_CHINESE)
public class ChineseController extends FXBaseController {
private String title = "languageDemo";
private int count = 0;
@FXML
public void clickToChinese() {
redirect("ChineseController");
@@ -32,8 +35,18 @@ public class ChineseController extends FXBaseController {
redirect("KoreanController");
}
/**
* 测试是否setWindowTitle接口
*/
@FXML
public void changeTitleClick() {
this.setWindowTitle(this.title + count);
count++;
}
@FXRedirect
public String redirect(String name) {
return name;
}
}

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.example.languageDemo;
package cn.edu.scau.biubiusuisui.example.langDemo;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
@@ -14,8 +14,11 @@ import javafx.fxml.FXML;
* @since JDK1.8
*/
@FXWindow(mainStage = false, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.ENGLISH)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.ENGLISH)
public class EnglishController extends FXBaseController {
private String title = "languageDemo";
private int count = 0;
@FXML
public void clickToChinese() {
redirect("ChineseController");
@@ -31,6 +34,15 @@ public class EnglishController extends FXBaseController {
redirect("KoreanController");
}
/**
* 测试是否setWindowTitle接口
*/
@FXML
public void changeTitleClick() {
this.setWindowTitle(this.title + count);
count++;
}
@FXRedirect
public String redirect(String name) {
return name;

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.example.languageDemo;
package cn.edu.scau.biubiusuisui.example.langDemo;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXRedirect;
@@ -14,8 +14,11 @@ import javafx.fxml.FXML;
* @since JDK1.8
*/
@FXWindow(mainStage = false, title = "languageDemo")
@FXController(path = "fxml/languageDemo/languageDemo.fxml", locale = FXPlusLocale.KOREAN)
@FXController(path = "fxml/langDemo/langDemo.fxml", locale = FXPlusLocale.KOREAN)
public class KoreanController extends FXBaseController {
private String title = "languageDemo";
private int count = 0;
@FXML
public void clickToChinese() {
redirect("ChineseController");
@@ -31,6 +34,16 @@ public class KoreanController extends FXBaseController {
redirect("KoreanController");
}
/**
* 测试是否setWindowTitle接口
*/
@FXML
public void changeTitleClick() {
this.setWindowTitle(this.title + count);
count++;
}
@FXRedirect
public String redirect(String name) {
return name;

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.example.languageDemo;
package cn.edu.scau.biubiusuisui.example.langDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
@@ -11,10 +11,11 @@ import javafx.stage.Stage;
* @date 2020/5/3 09:57
* @since JDK1.8
*/
@FXScan(base = "cn.edu.scau.biubiusuisui.example.languageDemo")
@FXScan(base = "cn.edu.scau.biubiusuisui.example.langDemo")
public class LanguageDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXPlusApplication.start(getClass());
}
}

View File

@@ -8,7 +8,6 @@ import cn.edu.scau.biubiusuisui.entity.FXPlusLocale;
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
import javafx.fxml.FXML;
import javafx.scene.input.Clipboard;
/**
* @author suisui

View File

@@ -0,0 +1,53 @@
package cn.edu.scau.biubiusuisui.example.windowDemo;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import javafx.fxml.FXML;
import javafx.scene.control.ToggleButton;
import javafx.stage.StageStyle;
/**
* @author suisui
* @description 测试Controller
* @date 2020/8/29 09:41
* @since JDK1.8
*/
@FXWindow(mainStage = true, title = "windowDemo", icon = "image/icon.png", style = StageStyle.UNDECORATED)
@FXController(path = "fxml/windowDemo/windowDemo.fxml")
public class DemoController extends FXBaseController {
private String title = "windowDemo -- ";
private int count = 0;
private String iconStr = "image/icon2.png";
private String iconStr2 = "image/icon3.png";
@FXML
private ToggleButton canResizableTB;
@Override
public void initialize() throws Exception {
canResizableTB.selectedProperty().addListener(e -> {
this.setDragAndResize(true, canResizableTB.isSelected());
});
}
/**
* 修改标题点击事件
*/
@FXML
public void changeTitleClick() {
this.setWindowTitle(title + count);
count++;
}
/**
* 字符串修改图标
*/
@FXML
public void changeIconClick() {
this.setIcon(count % 2 == 0 ? iconStr : iconStr2);
count++;
}
}

View File

@@ -0,0 +1,20 @@
package cn.edu.scau.biubiusuisui.example.windowDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* @author suisui
* @description 测试开放设置部分FXWindow属性的接口
* @date 2020/8/29 09:40
* @since JDK1.8
*/
@FXScan(base = "cn.edu.scau.biubiusuisui.example.windowDemo")
public class FXWindowDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXPlusApplication.start(FXWindowDemo.class);
}
}

View File

@@ -13,7 +13,7 @@ import cn.edu.scau.biubiusuisui.expression.data.ExpressionParser;
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
import cn.edu.scau.biubiusuisui.mq.MessageQueue;
import cn.edu.scau.biubiusuisui.proxy.FXControllerProxy;
import cn.edu.scau.biubiusuisui.stage.StageManager;
import cn.edu.scau.biubiusuisui.utils.ResourceBundleUtil;
@@ -168,7 +168,7 @@ public class FXControllerFactory {
* @Description 为有FXWindow注解的类创建Stage
*/
private static Stage createWindow(FXWindow fxWindow, Class clazz, FXBaseController fxBaseControllerProxy) {
logger.info("creating window");
logger.info("creating window.....");
Stage stage = new Stage();
fxBaseControllerProxy.setStage(stage);
double preWidth = fxWindow.preWidth() == 0 ? fxBaseControllerProxy.getPrefWidth() : fxWindow.preWidth();

View File

@@ -6,6 +6,6 @@ package cn.edu.scau.biubiusuisui.function;
* @date 2019/7/27 1:54
* @since JavaFX2.0 JDK1.8
*/
public interface Draggale {
public interface Draggable {
}

View File

@@ -22,44 +22,28 @@ import java.net.URL;
* @since JavaFX2.0 JDK1.8
*/
public class FXWindowParser {
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXWindowParser.class);
private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(FXWindowParser.class);
public void parse(Stage stage, FXBaseController fxControllerProxy, FXWindow fxWindow) {
logger.info("parsing @FXWindow of class: " + fxControllerProxy.getName());
// 处理 title
stage.setTitle(fxWindow.title());
fxControllerProxy.setWindowTitle(fxWindow.title());
// 处理 icon
if (!"".equals(fxWindow.icon())) {
try {
URL iconUrl = new FileUtil().getFilePathFromResources(fxWindow.icon());
if (iconUrl != null) {
if (new File(StringUtil.getRootPath(iconUrl)).exists()) {
stage.getIcons().add(new Image(fxWindow.icon()));
} else {
logger.warn("the icon file has not existed");
}
} else {
logger.warn("the icon file has not existed");
}
} catch (ProtocolNotSupport protocolNotSupport) {
logger.error(protocolNotSupport.getMessage(), protocolNotSupport);
protocolNotSupport.printStackTrace();
}
fxControllerProxy.setIcon(fxWindow.icon());
// 处理draggable和resizable
if (fxWindow.draggable() || fxWindow.resizable()) {
fxControllerProxy.setDragAndResize(fxWindow.draggable(), fxWindow.resizable());
}
// fxWindow的resizable默认为false
if (fxWindow.resizable()) {
stage.setResizable(true);
fxControllerProxy.setDragAndResize(fxWindow.draggable(), true);
}
// 处理draggable和resizable
if (fxWindow.draggable() || fxWindow.resizable()) {
EventHandler dragWindowHandler = new DragWindowHandlerImpl(stage, fxWindow.minWidth(), fxWindow.minHeight(), fxControllerProxy, fxWindow.draggable(), fxWindow.resizable());
fxControllerProxy.setOnMousePressed(dragWindowHandler);
fxControllerProxy.setOnMouseDragged(dragWindowHandler);
fxControllerProxy.setOnMouseMoved(dragWindowHandler);
}
// 处理style
stage.initStyle(fxWindow.style());
}

View File

@@ -1,8 +1,6 @@
package cn.edu.scau.biubiusuisui.log;
import org.slf4j.Logger;
/**
* @author suisui
* @version 1.2

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.messageQueue;
package cn.edu.scau.biubiusuisui.mq;
import cn.edu.scau.biubiusuisui.annotation.FXReceiver;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
@@ -20,9 +20,8 @@ import java.util.concurrent.ConcurrentHashMap;
* @date 2019/6/25 12:24
* @since JavaFX2.0 JDK1.8
*/
public class MessageQueue {
private IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(MessageQueue.class);
private static final IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(MessageQueue.class);
private static Map<String, List<FXMethodEntity>> receivers = new ConcurrentHashMap<>(); //Map<主题订阅了主题的所有方法>
@@ -31,6 +30,11 @@ public class MessageQueue {
private MessageQueue() {
}
/**
* 获取mq单例
*
* @return MessageQueue
*/
public static synchronized MessageQueue getInstance() {
if (messageQueue == null) {
messageQueue = new MessageQueue();
@@ -39,9 +43,9 @@ public class MessageQueue {
}
/**
* @param fxBaseController
* @param fxBaseControllerProxy
* @Description 注册消费者即FXReceiver注解的method
* @param fxBaseController 基础controller
* @param fxBaseControllerProxy 基础controller代理
* @description 注册消费者即FXReceiver注解的method
*/
public void registerConsumer(FXBaseController fxBaseController, FXBaseController fxBaseControllerProxy) {
Class clazz = fxBaseController.getClass();
@@ -51,7 +55,6 @@ public class MessageQueue {
for (Annotation annotation : annotations) {
if (FXReceiver.class.equals(annotation.annotationType())) {
logger.info("registering consumer: " + fxBaseControllerProxy.getName());
// System.out.println("FXReceiver");
FXReceiver receiver = (FXReceiver) annotation;
FXMethodEntity fxMethodEntity = new FXMethodEntity(fxBaseControllerProxy, method);
List<FXMethodEntity> fxMethodEntities = receivers.get(receiver.name());
@@ -66,9 +69,9 @@ public class MessageQueue {
}
/**
* @param id
* @param msg
* @Description 处理消息发送id为topic,msg为消息
* @param id 消息topic
* @param msg 消息内容
* @description 处理消息发送
*/
public void sendMsg(String id, Object msg) {
List<FXMethodEntity> lists = receivers.get(id);
@@ -80,23 +83,15 @@ public class MessageQueue {
if (method.getParameterCount() == 0) {
try {
method.invoke(fxBaseController);
} catch (IllegalAccessException e) {
} catch (IllegalAccessException | InvocationTargetException e) {
logger.error(e.getMessage());
e.printStackTrace();
} catch (InvocationTargetException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
} else {
try {
// obj the object the underlying method is invoked from
// 调起FXReceiver注解的方法
method.invoke(fxBaseController, msg);
} catch (IllegalAccessException e) {
} catch (IllegalAccessException | InvocationTargetException e) {
logger.error(e.getMessage());
e.printStackTrace();
} catch (InvocationTargetException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -3,7 +3,7 @@ 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.mq.MessageQueue;
import cn.edu.scau.biubiusuisui.stage.StageManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

View File

@@ -2,6 +2,7 @@ package cn.edu.scau.biubiusuisui.utils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
@@ -22,7 +23,14 @@ public class ClassUtil {
classLoader = getClass().getClassLoader();
}
private List<String> getAllFXControllerClassName(String base, List<String> nameList) {
/**
* 获取所有FxController的类名
*
* @param base 基础目录路径
* @param nameList 类名列表
* @return 所有FXController的类名列表
*/
private List<String> getAllFXControllerClassName(String base, List<String> nameList) throws UnsupportedEncodingException {
String splashPath = StringUtil.dotToSplash(base);
URL url = classLoader.getResource(splashPath);
String filePath = StringUtil.getRootPath(url);
@@ -42,7 +50,7 @@ public class ClassUtil {
return nameList;
}
public List<String> scanAllClassName(String base) {
public List<String> scanAllClassName(String base) throws UnsupportedEncodingException {
return getAllFXControllerClassName(base, new LinkedList<>());
}
@@ -62,7 +70,9 @@ public class ClassUtil {
}
private static List<String> readFromDirectory(String path) {
if (path == null) return null;
if (path == null) {
return null;
}
return readFromFileDirectory(path);
}

View File

@@ -3,9 +3,11 @@ package cn.edu.scau.biubiusuisui.utils;
import cn.edu.scau.biubiusuisui.exception.ProtocolNotSupport;
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
/**
* @author jack
@@ -18,7 +20,7 @@ public class FileUtil {
/**
* @param filePath
* @return
* @return 返回URL
* @throws ProtocolNotSupport
* @decription 从resources文件夹中读取File
* 输出如: file:/Users/suisui/workspace/Idea/JavaFX-Plus/target/classes/image/icon.png
@@ -28,19 +30,40 @@ public class FileUtil {
return FileUtil.class.getClassLoader().getResource(filePath);
}
/**
* @param filePath
* @return
* @description 读取resources文件夹下的file相对于resources的文件路径如 resources/config.conf 则只需 config.conf
* @since 1.2.0 update: 使用getResourcesAsStream读取屏蔽jar包读取障碍
*/
public static String readFileFromResources(String filePath) {
String path = StringUtil.getRootPath(FileUtil.class.getClassLoader().getResource(filePath));
return readFile(path);
public static String readFileFromResources(String filePath) throws UnsupportedEncodingException {
InputStream is = FileUtil.class.getClassLoader().getResourceAsStream(filePath);
if (is == null) {
return "";
}
StringBuffer content = new StringBuffer();
try (
InputStreamReader inputStreamReader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(inputStreamReader);
) {
String temp;
while ((temp = br.readLine()) != null) {
// 一次读入一行数据
content.append(temp + "\r\n");
}
return content.toString();
} catch (IOException e) {
logger.error("reading file error", e);
} finally {
IOUtils.closeQuietly(is);
}
return "";
}
/**
* @param filePath 绝对路径或相对路径
* @return
* @return 返回文件内容
* @description 读取文件
*/
public static String readFile(String filePath) {
@@ -54,15 +77,14 @@ public class FileUtil {
content.append(temp + "\r\n");
}
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
logger.error("reading file error", e);
}
return content.toString();
}
/**
* @param filePath
* @param content
* @param filePath 写出文件的地址
* @param content 文件内容
* @description 写文件
*/
public static void writeFile(String filePath, String content) {

View File

@@ -0,0 +1,10 @@
package cn.edu.scau.biubiusuisui.utils;
/**
* @author suisui
* @description 函数工具类
* @date 2020/8/28 23:32
* @since JDK1.8
*/
public class FunctionUtil {
}

View File

@@ -0,0 +1,18 @@
package cn.edu.scau.biubiusuisui.utils;
/**
* @author suisui
* @version 1.2.0
* <p> Description: JavaFx-Plus常量 </p>
* @time 2021/9/5 10:36 下午
*/
public interface IFxPlusConstants {
/**
* 项目默认编码 UTF-8
*/
String DEFAULT_CHARSET = "UTF-8";
/**
* FXController名称分隔符
*/
String CONTROLLER_NAME_SEPARATOR = "#";
}

View File

@@ -2,8 +2,11 @@ package cn.edu.scau.biubiusuisui.utils;
import cn.edu.scau.biubiusuisui.log.FXPlusLoggerFactory;
import cn.edu.scau.biubiusuisui.log.IFXPlusLogger;
import org.apache.commons.lang3.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
/**
* @author jack
@@ -11,20 +14,20 @@ import java.net.URL;
* @version 1.0
* @date 2019/6/25 3:46
* @since JavaFX2.0 JDK1.8
* @since 1.3.0 add继承StringUtils
*/
public class StringUtil {
public class StringUtil extends StringUtils {
private static IFXPlusLogger logger = FXPlusLoggerFactory.getLogger(StringUtil.class);
private StringUtil() {
}
/**
* "file:/home/whf/cn/fh" -> "/home/whf/cn/fh"
* "jar:file:/home/whf/foo.jar!cn/fh" -> "/home/whf/foo.jar"
*/
public static String getRootPath(URL url) {
String fileUrl = url.getFile();
public static String getRootPath(URL url) throws UnsupportedEncodingException {
String fileUrl = URLDecoder.decode(url.getFile(),IFxPlusConstants.DEFAULT_CHARSET);
int pos = fileUrl.indexOf('!');
if (-1 == pos) {
@@ -51,7 +54,6 @@ public class StringUtil {
* @return
*/
public static String splashToDot(String name) {
return name.replaceAll("/", "\\.");
}
@@ -63,7 +65,6 @@ public class StringUtil {
if (-1 != pos) {
return name.substring(0, pos);
}
return name;
}
@@ -76,7 +77,6 @@ public class StringUtil {
public static String trimURI(String uri) {
String trimmed = uri.substring(1);
int splashIndex = trimmed.indexOf('/');
return trimmed.substring(splashIndex);
}
@@ -103,8 +103,7 @@ public class StringUtil {
* @return
*/
public static String toInstanceName(String name) {
String result = name.substring(0, 1).toLowerCase().concat(name.substring(1));
return result;
return name.substring(0, 1).toLowerCase().concat(name.substring(1));
}
/**
@@ -114,12 +113,11 @@ public class StringUtil {
* @return
*/
public static String toClassName(String name) {
String result = name.substring(0, 1).toUpperCase().concat(name.substring(1));
return result;
return name.substring(0, 1).toUpperCase().concat(name.substring(1));
}
/**
* cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/languageDemo.fxml -> fxml/languageDemo/languageDemo.fxml
* cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/langDemo.fxml -> fxml/languageDemo/langDemo.fxml
*
* @param name
* @return
@@ -135,7 +133,7 @@ public class StringUtil {
}
/**
* cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/languageDemo.fxml -> languageDemo
* cn/edu/scau/biubiusuisui/resources/fxml/languageDemo/langDemo.fxml -> languageDemo
*
* @param name 文件名
* @return
@@ -144,7 +142,7 @@ public class StringUtil {
public static String getFileBaseName(String name) {
String result = "";
String[] tempStrs = name.split("/");
if (1 == tempStrs.length) { //只有文件名即name: languageDemo.fxml
if (1 == tempStrs.length) { //只有文件名即name: langDemo.fxml
result = StringUtil.trimExtension(name);
} else {
result = StringUtil.trimExtension(tempStrs[tempStrs.length - 1]);

View File

@@ -58,6 +58,7 @@
<Button mnemonicParsing="false" onAction="#clickToChinese" text="%chinese"/>
<Button mnemonicParsing="false" onAction="#clickToEnglish" text="%english"/>
<Button mnemonicParsing="false" onAction="#clickToKorean" text="%korean"/>
<Button mnemonicParsing="false" onAction="#changeTitleClick" text="修改"/>
</children>
</HBox>
</children>

View File

@@ -1 +1 @@
dialog=弹窗
dialog=\u5f39\u7a97

View File

@@ -1,3 +1,3 @@
button.goAndClose=跳转并关闭此窗口
button.go=弹窗
parentController=父组件
button.goAndClose=\u8df3\u8f6c\u5e76\u5173\u95ed\u6b64\u7a97\u53e3
button.go=\u5f39\u7a97
parentController=\u7236\u7ec4\u4ef6

View File

@@ -1 +1 @@
childrenController=子组件
childrenController=\u5b50\u7ec4\u4ef6

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.Pane?>
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
prefWidth="600.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ToolBar layoutY="276.0" prefHeight="124.0" prefWidth="600.0">
<items>
<Button mnemonicParsing="false" onAction="#changeTitleClick" text="修改标题"/>
<Button mnemonicParsing="false" onAction="#changeIconClick" text="修改图标"/>
<ToggleButton fx:id="canResizableTB" mnemonicParsing="false" text="是否允许窗口拖拽缩放"/>
</items>
</ToolBar>
</children>
</fx:root>

View File

View File

@@ -0,0 +1 @@
changeTitle

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -12,7 +12,7 @@ log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
# MacOS
log4j.appender.D.File=${log.base}/logs/debug/javafxplus.log
log4j.appender.D.Append=true
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
@@ -22,6 +22,6 @@ log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
# MacOS
log4j.appender.E.File=${log.base}/logs/error/javafxplus.log
log4j.appender.E.Append=true
log4j.appender.E.Threshold=ERROR
log4j.appender.E.Threshold=ERROR
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH:mm:ss} [%t] [%l] - %m%n