J2SE+swing客户端开发进阶总结

Hello , 我是恒。分享一个练手项目一本糊涂账,顺便帮站长宣传一下站点https://how2j.cn
本项目是基于Swing和JDBC开发的图形界面桌面应用,通过这个项目能运用锻炼J2SE知识和技能

结构

├───src/
│   ├───HutuMainFrame.java
│   ├───dao/
│   │   ├───CategoryDAO.java
│   │   ├───ConfigDAO.java
│   │   ├───RecordDAO.java
│   ├───entity/
│   │   ├───Category.java
│   │   ├───Config.java
│   │   ├───Record.java
│   ├───gui/
│   │   ├───frame/
│   │   │   ├───MainFrame.java
│   │   ├───listener/
│   │   │   ├───BackupListener.java
│   │   │   ├───CategoryListener.java
│   │   │   ├───ConfigListener.java
│   │   │   ├───RecordListener.java
│   │   │   ├───RecoverListener.java
│   │   │   ├───ToolBarListener.java
│   │   ├───model/
│   │   │   ├───CategoryComboBoxModel.java
│   │   │   ├───CategoryTableModel.java
│   │   ├───page/
│   │   │   ├───SpendPage.java
│   │   ├───panel/
│   │   │   ├───BackupPanel.java
│   │   │   ├───CategoryPanel.java
│   │   │   ├───ConfigPanel.java
│   │   │   ├───MainPanel.java
│   │   │   ├───RecordPanel.java
│   │   │   ├───RecoverPanel.java
│   │   │   ├───ReportPanel.java
│   │   │   ├───SpendPanel.java
│   │   │   ├───WorkingPanel.java
│   ├───service/
│   │   ├───CategoryService.java
│   │   ├───ConfigService.java
│   │   ├───RecordService.java
│   │   ├───ReportService.java
│   │   ├───SpendService.java
│   ├───startup/
│   │   ├───Bootstrap.java
│   ├───test/
│   │   ├───Test.java
│   ├───util/
│   │   ├───CenterPanel.java
│   │   ├───ChartUtil.java
│   │   ├───CircleProgressBar.java
│   │   ├───ColorUtil.java
│   │   ├───DateUtil.java
│   │   ├───DBUtil.java
│   │   ├───GUIUtil.java
│   │   ├───MysqlUtil.java

学习点

单例模式

SpendPanel类的实例通过instance变量来访问,使得监听器通过单例模式的面板访问组件

package gui.panel;

import javax.swing.JLabel;

public class SpendPanel {
	public static SpendPanel instance = new SpendPanel();

	JLabel lMonthSpend = new JLabel("本月消费");
	JLabel lTodaySpend = new JLabel("今日消费");
	/* .....*/
	private SpendPanel(){
		
	}
}

面板类与监听器类松耦合

GUI进阶

界面包规范
MainFrame 主窗体类,规划在gui.frame包下
消费一览面板类,规划在gui.panel包下
RecordPanel 记一笔面板类,规划在gui.panel包下
ToolBarListener 工具条监听器类,规划在gui.listener包下
BackupListener 备份监听器类,规划在gui.listener包下
界面工具类
GUIUtil.java开发图形界面的过程中,减少代码复用,作为工具类
设置按钮图标

public static void setImageIcon(JButton b, String fileName, String tip) {
    ImageIcon i = new ImageIcon(new File(imageFolder, fileName).getAbsolutePath());
    b.setIcon(i);
    b.setPreferredSize(new Dimension(61, 81));
    b.setToolTipText(tip);
    b.setVerticalTextPosition(JButton.BOTTOM);
    b.setHorizontalTextPosition(JButton.CENTER);
    b.setText(tip);
}

checkNumber、checkZero和checkEmpty方法用于验证用户输入的有效性

public static boolean checkNumber(JTextField tf, String input) {
    // ...
}

public static boolean checkZero(JTextField tf, String input) {
    // ...
}

表单生成

设计

实体类Entity

配置信息Config类与配置信息表 config相对应,还有消费分类Category和消费信息类Record

package entity;

public class Config {

	public int id;
	public String key;
	public String value;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	
}

业务类

ConfigService 设置业务类,这个类是监听器直接调用的类,然后再通过ConfigService去调用ConfigDAO

package service;
 
import dao.ConfigDAO;
import entity.Config;
 
public class ConfigService {
    public static final String budget = "budget";
    public static final String mysqlPath = "mysqlPath";
    public static final String default_budget = "500";
 
    static ConfigDAO dao= new ConfigDAO();
    static{
        init();
    }

    public static void init(){
        init(budget, default_budget);
        init(mysqlPath, "");
    }
数据库CURD以及备份还原

CURD
不多说
工具类 MysqlUtil的创建
备份方法backup()通过Runtime调用mysqldump.exe进行备份
恢复方法recover通过Runtime调用mysql.exe进行数据的还原

    public static void backup(String mysqlPath, String backupfile) throws IOException {
        String commandFormat = "\"%s/bin/mysqldump.exe\" -u%s -p%s   -hlocalhost   -P%d %s -r \"%s\"";
 
        String command = String.format(commandFormat, mysqlPath, DBUtil.loginName, DBUtil.password, DBUtil.port,
                DBUtil.database, backupfile);
        Runtime.getRuntime().exec(command);
    }
 
    public static void recover(String mysqlPath, String recoverfile) {
        try {
            String commandFormat = "\"%s/bin/mysql.exe\" -u%s -p%s   %s ";
            String command = String.format(commandFormat, mysqlPath, DBUtil.loginName, DBUtil.password,
                    DBUtil.database);
 
            Process p = Runtime.getRuntime().exec(command);
            OutputStream out = p.getOutputStream();
            String inStr;
            StringBuffer sb = new StringBuffer("");
            String outStr;
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(recoverfile), "utf8"));
            while ((inStr = br.readLine()) != null) {
                sb.append(inStr + "\r\n");
            }
            outStr = sb.toString();
 
            OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
            writer.write(outStr);
            writer.flush();
            out.close();
            br.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }

最后

最后我没有列出所有精髓所在,特别是架构上。
对于我来说,还是有很多值得学习的地方

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值