# SwingX **Repository Path**: Dlow71/glod_-swing ## Basic Information - **Project Name**: SwingX - **Description**: 轮子项目,从0到1实现了IOC和AOP,并适配Swing,让开发者可以使用Spring的开发方式去开发Swing,加速Swing开发并能对代码进行一定程度解耦,工具包在MagicSwing分支下的util文件夹下的SwingX文件夹,直接拷贝到项目里面就能用了 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: MagicSwing - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 14 - **Forks**: 1 - **Created**: 2023-05-23 - **Last Updated**: 2025-06-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: Swing, Spring, java-util ## README > **SwingX Beat 1.0版本** > **Author:山沐与山** ## 1 SwingX 简介 - 一个方便Swing开发的小工具 - 实现了类似于IOC、依赖注入和AOP,而且针对了swing做了特殊适配 - 用spring的方式去开发swing - 对象单例化,避免了切换页面反复new对象,提升了页面切换的流畅度,并且针对代码进行了解耦,避免了组件传值,传来传去的麻烦事 ## 2 SwingX 使用教程 ### 2.1 源码 - SwingX源码放在了src/main/java/com/carbon/util/SwingX目录,把SwingX文件夹或者整个Util文件夹拷到你自己的项目里面就能使用了 - 然后如果想看演示效果的话,请先将项目中的carbon-a.sql文件导入数据库,然后配置一下jdbc.properties,直接进入SplashWindow类启动项目就可以看到效果了 - SwingX的最佳实践可以看com/carbon/main/ProjectMain.java类 ### 2.2 注解 - @ViewMain、@Service、@Component、@Handler 都是语义化注解,加了注解后就会被注入到IOC容器中 - @Autowired 这个注解你可以在任何bean下,注入你想要注入的对象 - @Aspect和@AspectPlus分别是AOP第一代和第二代注解,第二代支持使用表达式去匹配,不过目前只能支持within,@Order注解是配合这两个注解使用的,用来指定切面类的优先级 ### 2.3 工具类介绍 - **SizeUtil** 可以快速设置Swing窗口的大小和一些样式,可重载方法去拓展及自定义 - **SqlUtil** 可以快速生成sql,但是目前功能性不是特别强,还存在一点小问题,后续想拓展成mybatis这样的框架 - **ClassUtil** 封装了基本反射需要用到的功能 - **CamelCaseUtil** 驼峰下划线转换工具类 - **ObjectUtils** 快速对一个对象及里面的属性进行判空的小工具 ### 2.4 使用正解 - 用法跟SpringBoot类似,首先要有一个启动类,在启动类里面加上下图实例代码,这个传递的参数就是启动类的class对象,然后方法会根据启动类所在路径及其以下路径开始扫描并注册对象到IOC容器当中 ```java public static void main(String[] args) { SwingX.initialize(SplashWindow.class); } ``` - 当然也可以自己自定义扫描路径 ```java public static void main(String[] args) { SwingX.initialize("com.carbon"); } ``` - 窗口类之前统一的都是继承的JFrame,但如果你的某个页面需要对数据进行一些操作,那么一定要继承DefaultFrame这个抽象类, 同时@ViewMain里面提供了一个属性isCurtain,如果设置为true的话,那就相当于首页,默认第一个展示的页面,比如登录页就是第一个需要展示出来的页面 - 目前窗口类也只适配了JFrame,其他窗口如Dialog就没适配,因此画页面指定了只能使用JFrame,不过也算是能应对大多数场景了 ```java @ViewMain(isCurtain=true) public class ProjectMain extends DefaultFrame { ... } ``` - 在页面的构造器中,不要主动去刷新数据与绑定事件,只需要选择性重写loadData和bindAction方法就行了,框架会帮你自动调用,同时切记不要主动去setVisible=true,避免闪屏 ```java @ViewMain public class ProjectMain extends DefaultFrame { @Override public void loadData() { TableDTO tableDTO = getTableDto(); ProjectTableModel projectTableModel = ProjectTableModel.assembleTable(tableDTO.getData()); this.table1.setModel(projectTableModel); } @Override public void bindAction() { addBtn.addActionListener(projectHandler); updateBtn.addActionListener(projectHandler); delBtn.addActionListener(projectHandler); searchBtn.addActionListener(projectHandler); resetBtn.addActionListener(projectHandler); } } ``` - AOP使用如下,项目里面同时兼容@Aspect和@AspectPlus,前者是根据注解去织入类,后者是根据表达式匹配织入类,切面类必须实现DefaultAspect,然后自己去指定实现一些方法,切记被织入的类一定得是被容器管理的对象才行,比如加@Component ```java @Aspect(value = Service.class) //@AspectPlus(pointcut = "within(com.carbon.common.service.project.impl.*)") @Order(0) @Slf4j public class ServiceTimeCalcAspect extends DefaultAspect { private long timestampCache; @Override public void before(Class targetClass, Method method, Object[] args) throws Throwable { log.info("开始计时,执行的类是[{}],执行的方法是[{}],参数是[{}]",targetClass.getName() ,method.getName(),args); timestampCache = System.currentTimeMillis(); } @Override public Object afterReturning(Class targetClass, Method method, Object[] args, Object returnValue) throws Throwable { long end = System.currentTimeMillis(); long costTime = end - timestampCache; log.info("结束计时,执行的类是[{}],执行的方法是[{}],参数是[{}],时间为[{}]",targetClass.getName() ,method.getName(),args,costTime); return returnValue; } } ``` ###总结 >虽然目前并不完善,还有许多地方没有适配,比如目前窗口只适配了JFrame,但毕竟也是一个自己从0开始写的小工具包,能依据现有掌握的知识去改造并解决Swing开发中的各种问题,还是有点小成就感,如果使用过程中发现有任何问题,可以来联系我哟 > ,这段时间应该是不会再更新了,一是比赛要来了,二是可能会去学习新的东西,swing也算到头了吧, > 但是这不意味着结束,可能哪天课设/比赛又需要用到swing了,那到时候我也一定会回来