# gui-shell-core **Repository Path**: qq1134380223/gui-shell-core ## Basic Information - **Project Name**: gui-shell-core - **Description**: 写一些普通的java 函数,再给他们加上一些注解,这个框架会为带有注解的函数创建一个可视化的调用界面。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2023-01-21 - **Last Updated**: 2025-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: GUI, shell ## README # GUI SHELL ## 简介 一个类似于spring-shell的框架,不同之处在于这个框架生成gui界面。 ## quick start 导入依赖 ```xml io.gitee.qq1134380223 gui-shell-core 1.1.1.RELEASE ``` oracle jdk8 包含有javax的相关模块,而jdk11以后javafx已经不是jdk的内置模块,因此需要额外引入。 如果你使用jdk11或更高的jdk版本,那么还需要以下依赖。 ```xml org.openjfx javafx-fxml 17 ``` 编写TestMethodGroup ```java @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "嗨", desc = "点击执行功能按钮,然后这个方法的输出将会输出到结果输出区") public String hi() { return "hi!"; } } ``` 编写主方法 ```java public class Main { public static void main(String[] args) { GuiShellApplication.runApplication("测试窗口标题", new TestMethodGroup()); } } ``` 运行主方法,你会看到这个界面 ![img.png](img.png) 展开右侧的列表中的“测试功能组”,选择“嗨”,然后点击“执行功能”按钮,这时```hi()```方法的的返回值就会显示在结果输出区。 ![img_1.png](img_1.png) ① 来自与main方法中```GuiShellApplication.runApplication```的第一个参数。 ② ```TestMethodGroup```的```@GuiShellGroup```注解值,注意需要在main方法中```GuiShellApplication.runApplication``` 的第二个参数传入```TestMethodGroup```实例。 ③ ```hi()```的注解```@GuiShellGroupMethod```的value值,这个值是“功能名称”。 ④ 选择了“嗨”这个功能后,点击“执行功能”按钮时会执行 ```hi()```方法,返回值会显示在结果输出区。 ⑤ 功能说明,来自于```hi()```的注解```@GuiShellGroupMethod```的desc值,这个值是“功能说明”。 你可以在```TestMethodGroup```中添加多个注解有```@GuiShellGroupMethod```的```public``` 方法。注意,框架并不要求多个方法的```@GuiShellGroupMethod```的value值必须各不相同,只是如果你写相同的value值,会在使用的过程中无法区分两个value相同的方法。 ```GuiShellApplication.runApplication```的第二个参数是变长参数,因此你也可以传入多个带有```@GuiShellGroup``` 注解的类型的实例。同样```@GuiShellGroup```注解的value值并不要求必须不同,但相同的value会让使用过程中难以区分两个同名的功能组。 ## 参数 方法可以有参数,框架会为参数生成对应的输入组件。现在修改```TestMethodGroup```的```hi()```方法 ```java import io.gitee.qq1134380223.guishellcore.annotation.Param; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "嗨", desc = "点击执行功能按钮,然后这个函数的输出将会输出到结果输出区") public String hi(@Param("姓名") String name) { return "hi! " + name; } } ``` 重新运行程序并选择“嗨”功能,可以看到参数输入区出现一个输入姓名的输入框,输入姓名并点击执行功能。 ![img_2.png](img_2.png) ① 输入框前的参数名称来自于```@Param```的value值 ② 执行功能时,框架会将输入框中的值传入```hi```方法 框架能为大部分类型生成人性化的输入组件,但并非所有,框架支持的参数类型包括在以下列表中: | 类型 | 对应的输入组件 | |:---------------------------------------------:|:--------------:| | int,Integer | 整数输入框 | | double,Double | 小数输入框 | | boolean,Boolean | 勾选框 | | String | 输入框 | | @Choices String[] | 多选框 | | @Single @Choices String | 下拉框 | | File | 文件选择器 | | @Directory File | 目录选择器 | | LocaleDate | 日期选择框 | | 上述类型的数组(注意是数组[]不是集合List) | 可增加减少的上述输入框 | | 至少有一个setter的bean类型,bean的属性字段是上述类 | 将上述输入框组合而成的输入框 | | 上述类型的子类 | 父类对应的输入框 | | 上述类型的数组(注意:本行没有重复) | 可增加减少的上述输入框 | | 至少有一个setter的bean类型,bean的属性字段是上述类((注意:本行没有重复)) | 将上述输入框组合而成的输入框 | | 上述类型的子类 (注意:本行没有重复) | 父类对应的输入框 | ### @Choices String[] 多选框 修改一下功能 ```java @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "多选", desc = "点击选择选项") public String multiChoice(@Param("选项") @Choices({"item1", "item2", "item3"}) String[] choices) { return String.join(",", choices); } } ``` 效果如图: ![img_4.png](img_4.png) ### @Single @Choices String 单选框 修改一下功能 ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.Param; import io.gitee.qq1134380223.guishellcore.annotation.Single; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "嗨", desc = "点击执行功能按钮,然后这个函数的输出将会输出到结果输出区") public String hi(@Param("问候语") @Single @Choices({"hi", "hello"}) String greeting, @Param("姓名") String name) { return greeting + " " + name; } } ``` 效果如图: ![img_3.png](img_3.png) 当@Single注解的参数类型为String时,@Single可以省略。但当其注解的类型是String[]时,则不能省略,因为省略后就不能区分是多个单选还是一个多选。 注解或String[][]或String数组的数组的数组等等时@Single同理不能省略。 ### File 文件输入框 ```java @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod("输入一个文件") public File getAFile(@Param("文件") File file) { return file; } } ``` 运行测试: ![img_7.png](img_7.png) 点击选择文件后弹出: ![img_8.png](img_8.png) 选择文件然后点击执行功能: ![img_9.png](img_9.png) ### @Directory File 目录输入框 ```java import io.gitee.qq1134380223.guishellcore.annotation.Directory; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod("输入一个目录") public File getAFile(@Param("目录") @Directory File file) { return file; } } ``` 效果同File,只是弹出的选择框时目录选择框: ![img_10.png](img_10.png) ### bean 组合输入框 定义一个Bean类型参数 ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.Param; @Data //lombok public class Student { @Param("姓名") String name; @Param("年龄") int year; @Param("性别") @Choices({"男", "女", "其他"}) String gender; } ``` 写一个方法 ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.Param; import io.gitee.qq1134380223.guishellcore.annotation.Single; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "输入一个学生信息") public Student hi(@Param("学生信息") Student student) { return student; } } ``` 运行测试: ![img_5.png](img_5.png) ### 数组类型参数 以学生信息为例 ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.Param; import io.gitee.qq1134380223.guishellcore.annotation.Single; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupMethod(value = "输入一群学生信息") public Student[] hi(@Param("学生信息") Student[] students) { return students; } } ``` 运行测试: ![img_6.png](img_6.png) ## 返回值 单击结果输出区的文字,可以进入复制模式。 ![img_11.png](img_11.png) ### File类型的返回值 在windows操作系统中,结果输出区会为File类型的返回值生成一个“在资源管理查看”的按钮,点击可打开文件所在目录。 ![img_9.png](img_9.png) ### void 类型返回值 会输出“功能已执行完毕,没有任何返回值” ### 其他类型的返回值 这个框架会尽量的使用json格式数据表达返回的对象,如果返回的对象无法用json表达则会显示它toString()后的值。 ## 属性 ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.GuiShellGroupProperty; import io.gitee.qq1134380223.guishellcore.annotation.Param; import io.gitee.qq1134380223.guishellcore.annotation.Single; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupProperty("字段属性") int i = 0; public int getI() {//字段属性必须有getter return i; } @GuiShellGroupProperty("方法属性") public int getIp1() {//方法属性必须public且无参 return i + 1; } @GuiShellGroupMethod(value = "改变属性") public void hi() { i++; } } ``` 每次点击“执行功能”属性区都会刷新并更新属性的值。 ![img_12.png](img_12.png) 点击属性的字符,可以进入复制模式。 ![img_13.png](img_13.png) ### File类型的属性 例子: ```java import io.gitee.qq1134380223.guishellcore.annotation.Directory; import io.gitee.qq1134380223.guishellcore.annotation.GuiShellGroupProperty; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupProperty("目录") File dir; public File getDir() { return dir; } @GuiShellGroupMethod("输入一个目录") public void getAFile(@Param("目录") @Directory File file) { dir = file; } } ``` 对于File类型的属性,在windows操作系统下,会为其生成一个“在资源管理器中查看”的按钮。 ![img_14.png](img_14.png) ### 其他类型的属性 对于其他类型的属性,框架会尽量以json的格式展示其内容,如果不能则以其toString的值展示。 以Student类为例子: ```java import io.gitee.qq1134380223.guishellcore.annotation.Choices; import io.gitee.qq1134380223.guishellcore.annotation.GuiShellGroupProperty; import io.gitee.qq1134380223.guishellcore.annotation.Param; import io.gitee.qq1134380223.guishellcore.annotation.Single; @GuiShellGroup("测试功能组") public class TestMethodGroup { @GuiShellGroupProperty("学生信息") Student student; public Student getStudent() { return student; } @GuiShellGroupMethod(value = "输入一个学生信息") public void hi(@Param("学生信息") Student student) { this.student = student; } } ``` 效果如图: ![img_15.png](img_15.png) ## 耗时任务 如果一个```@GuiShellGroupMethod```注解的函数是耗时任务,可以为其加上```@Async```注解,这样在执行耗时任务的时候就会输出“功能正在执行,请稍后”。 示例: ```java @GuiShellGroup("耗时任务") public class Test { @GuiShellGroupMethod("耗时任务") @Async public void test() { //耗时任务的代码 } } ``` ## 整合Spring Boot 整合springboot的步骤如下 1. 创建springboot 项目 2. 引入gui-shell-core依赖 3. 编写功能组类,并加上```@Component```注解 注意gui-shell-core依赖中包含springboot的启动配置,无需手动调用```GuiShellApplication.runApplication``` 使用spring boot 的ioc功能,你能向功能组中注入你需要的bean,比如dao,service等 ### 配置窗口标题 在application.properties中配置 ```properties guishell.title=你的标题 ``` ## kotlin 使用kotlin可以简化开发,至少不用写那么多public、getter和setter。使用spring boot initializer可以很方便的创建基于kotlin的springboot项目,这样在项目中就可以很方便的使用kotlin开发功能。