java管家婆项目

文章目录

    • 项目要求
    • 建立数据库
    • 图形化界面调用说明
    • 在eclipse中建包
      • 1. com.itheima.gip.app中创建类MainApp
      • 2. com.itheima.gip.controller中创建类AddLedgerControlle
      • 3.com.itheima.gip.controller创建AddSortController
      • 4.com.itheima.gip.controller创建EditLedgerController
      • 5.com.itheima.gip.controller创建EditSortController
      • 6.com.itheima.gip.controller创建 LedgerMngController
      • 7.com.itheima.gip.controller创建MainFrameController
      • 8.com.itheima.gip.controller创建SortMngController
      • 9.com.itheima.gip.dao创建 LedgerDao
      • 10.在com.itheima.gip.dao中创建SortDao
      • 11.在com.itheima.gip.domain中创建 Ledger
      • 12.在com.itheima.gip.domain中创建 QueryForm
      • 13.在com.itheima.gip.domain中创建 Sort
      • 14.在com.itheima.gip.services中创建LedgerServices
      • 15.在com.itheima.gip.services中创建SortService
      • 16.在com.itheima.gip.tools包中创建DateChooser
      • 17.在com.itheima.gip.tools中创建DateUtils
      • 18.在com.itheima.gip.tools中创建DateUtils
      • 19.在com.itheima.gip.tools中创建 JDBCUtils
      • 20.在com.itheima.gip.tools中创建 JFreeChartUtils
      • 21.在com.itheima.gip.tools中创建 ListTableModel< T >
      • 22.在com.itheima.gip.view;中创建 AbstractLedgerMngDialog
      • 23.在com.itheima.gip.view;中创建 AbstractMainFrame
      • 24.在com.itheima.gip.view;中创建 AbstractOperationLedgerDialog
      • 25.在com.itheima.gip.view;中创建 AbstractOperationSortDialog
      • 26.在com.itheima.gip.view;中创建 AbstractShapeDialog
      • 27.在com.itheima.gip.view;中创建 AbstractSortMngDialog

项目要求

编写一个管家婆家庭记账软件,该软件的主要功能有:
分类管理:查询分类、添加分类、编辑分类、删除分类
财务管理:多条件查询、添加账务、编辑账务、删除帐务、收支分类比例图。
要求:采用三层架构+MVC分层模型开发。

建立数据库

CREATE TABLE gjp_sort(
    --主键
    sid INT PRIMARY KEY AUTO_INCREMENT,
    sname VARCHAR(200),
    parent VARCHAR(100),
    -- 账务描述
    desc VARCHAR(1000)
 );
CREATE TABLE gjp_ledger(
   -- 主键
    lid INT PRIMARY KEY AUTO_INCREMENT,
    -- 分类名称   
    parent VARCHAR(200),
    -- 金额
    money DOUBLE,
	-- 分类
	sid INT,
    -- 账户
    account VARCHAR(100),
    -- 创建日期
    createtime DATE,
    -- 账务描述
    ldesc VARCHAR(1000)
 );
### 建立查询 
INSERT  INTO gjp_sort(sid,sname,parent,sdesc) 
VALUES 
(1,'服装支出','支出','买衣服'),
(2,'吃饭支出','支出',''),
(3,'交通支出','支出',''),
(4,'住房支出','支出',''),
(5,'工资收入','收入','fda'),
(6,'股票收入','收入',''),
(7,'礼金支出','支出',''),
(8,'其它支出','支出','');
INSERT  INTO gjp_ledger(lid,parent,money,sid,account,createtime,ldesc) 
values 
(1,'支出',247,2,'交通银行','2016-03-22','家庭聚餐'),
(2,'收入',12345,5,'现金','2016-03-15','开工资了'),
(3,'支出',1998,1,'现金','2016-04-02','买衣服'),
(4,'支出',325,2,'现金','2016-06-18','朋友聚餐'),
(10,'收入',8000,6,'工商银行','2016-10-28','股票大涨'),
(11,'收入',5089,6,'工商银行','2016-10-28','股票又大张'),
(12,'收入',5088,5,'交通银行','2016-10-28','又开工资了'),
(13,'支出',5008,7,'现金','2016-10-28','朋友结婚'),
(14,'支出',1568,8,'现金','2016-10-29','丢钱了'),    
(15,'支出',2300,3,'交通银行','2016-10-29','油价还在张啊'),
(16,'支出',1090,2,'工商银行','2016-10-29','又吃饭'),
(17,'收入',1008,5,'现金','2016-10-30','开资'),
(18,'支出',2000,3,'现金','2016-10-30','机票好贵'),
(19,'收入',5000,5,'现金','2016-10-30','又开资');

图形化界面调用说明

窗体和他的控制器子类的一个说明
主窗体类:AbstractMainFrame.java
子类(控制器)继承AbstractMainFrame.java
MainFrameControoler 子类
显示主窗体 new AbstractMainFrame的子类,控制器
MainFrameControiier主窗体控制器

分类对话框 :AbstractSortMngDialog.java继承JDialog
子类(控制器),继承AbstractSortMngDialog
SortMngControoler 子类
MainFrameCotroller子类方法中sortMng()显示出分类对话框
是由主窗体点击后显示

sortMngController子类重写的三个方法
添加,编辑,删除分类

操作分类对话框 ,AbstractOperationSortDialog 继承JDialog
在分类管理中点击了添加分类或编辑分类就要弹出分类对话框,AbstractOperationSortDialog
子类(控制器) AddSortController继承AbstractOperationSortDialog
子类(控制器) EditSortController继承AbstractOperationSortDialog

账务管理对话框:AbstractLedgerMngDialog 继承JDialog
子类()LedgerMngController,显示账务管理对话框,new LedgerMngController
主窗体类:AbstractMainFrame–>子类(MainFrameCotroller子类,财务管理按钮)

操作账务对话框 AbstractOperationLedgerDialog继承JDialog
在账务对话框中,点击添加账务,编辑账务,弹出操作账务对话框AbstractOperationLedgerDialog
子类(控制器) AddLedgeController继承AbstractOperationLedgeDialog
子类(控制器) EditLedgeController继承AbstractOperationLedgeDialog

在eclipse中建包

  1. com.itheima.gip.app;
  2. com.itheima.gip.controller
  3. com.itheima.gip.dao
  4. com.itheima.gip.domain
  5. com.itheima.gip.services
  6. com.itheima.gip.tools
  7. com.itheima.gip.view

1. com.itheima.gip.app中创建类MainApp

package com.itheima.gip.app;
import com.itheima.gip.controller.MainFrameController;
public class MainApp {


	/*
	  * 主程序类用来启动结束程序
      */
	public static void main(String[] args) {      
		//开启主窗体
		new MainFrameController().setVisible(true);
    } 
     
}

2. com.itheima.gip.controller中创建类AddLedgerControlle

package com.itheima.gip.controller;

import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JDialog;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Ledger;
import com.itheima.gip.services.LedgerServices;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractOperationLedgerDialog;

//添加账务对话框
@SuppressWarnings("all")
public class AddLedgerControlle extends AbstractOperationLedgerDialog {

	private static final long serialVersionUID = 1L;
	private SortService sortService = new SortService();
	private LedgerServices ledgerService = new LedgerServices();
	public AddLedgerControlle(JDialog dialog) {
		super(dialog);
		titleLabel.setText("添加账务");
		super.setTitle("添加分类");
		// TODO Auto-generated constructor stub
	}
	/*
	 *点击添加按钮,实现功能
	 *验证用户填写数据
	 *分类
	 *分类名称
	 *全额>0, 必须是数据
	 *账户,必须填写的
	 *
	 *用户填写的数据,封装成Ledger的对象
	 *传递给servises层,进行添加
	*/
	@Override
	public void comfirm() {
		String parent =parentBox.getSelectedItem().toString();
		String sname=sortBox.getSelectedItem().toString();
		String accout=accountTxt.getText();
		String createtime =createtimeTxt.getText();
		String sMoney=moneyTxt.getText();
		String ldesc=ldescTxt.getText();
		if(parent.equals("=请选择=")){
			JOptionPane.showMessageDialog(this, "请选择分类");
			return;
			
		}
		if(sname.equals("=请选择=")){
			JOptionPane.showMessageDialog(this, "请选择分类名称");
			return;
			
		}
		if(accout==null||accout.isEmpty()){
			JOptionPane.showMessageDialog(this, "请填写账户");
			return;
			
		}
		//获取到的金额,由String,转出double
		double money = 0;
		try {
			money =Double.parseDouble(sMoney);
			
		} 
		catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, "必须填写数字");
			return;
			
		}
		
		if(money<=0){
			JOptionPane.showMessageDialog(this, "全部金额必须大于0");
			return;
		}
		
		//将数据封装成Ledger对象getSidBySname(sname)
		//0,数据表主键,假数据,sid,是通过sname查询sort表获取,给假的
		int sid=ledgerService.getSidBySname(sname);
		Ledger ledger =new Ledger(0,parent,money,sid,accout,createtime,ldesc,sname);
		ledgerService.addLedger(ledger);
		this.dispose();
		JOptionPane.showMessageDialog(this, "添加账务成功");
		
	}
	public void changeParent() {
		// 获取收支的选项
		String parent = parentBox.getSelectedItem().toString();
		// parent选择,分类也是请选择
		if (parent.equals("=请选择=")) {
			sortBox.setModel(new DefaultComboBoxModel<>(new String[] { "=请选择=" }));
		}
		// 情况二根据收支选择,去数据库中,查询所有分类内容
		if (parent.equals("收入") || parent.equals("支出")) {
			// 调用services层方法querySortNameByParent(String parent)查询所有分类名称
			// 获取到一个List.toArray()集合,几何中的数据填充到下拉菜单中
			List<Object> list = sortService.querySortNameByParent(parent);
			list.add(0, "=请选择=");
			sortBox.setModel(new DefaultComboBoxModel(list.toArray()));
		}

	}

}

3.com.itheima.gip.controller创建AddSortController

package com.itheima.gip.controller;

import javax.swing.JDialog;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Sort;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractOperationSortDialog;
//添加分类对话框的控制器
public class AddSortController extends AbstractOperationSortDialog{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public AddSortController(JDialog dialog) {
		super(dialog);
		titlelLabel.setText("添加分类");
		super.setTitle("添加分类");
	}
	/*
	 * 添加分类确定按钮
	 * 实现步骤
	 * 1.数据验证
	 * 验证分类选项
	 * 验证分类名称
	 * 数据不符合要求,提示对话框,从新输入
	 * 2.将取到的数据封装Sort成对象
	 * lid成员,不需要设置值
	 * 3.将Sort对象传递给servises层除了处理
	 * 4.services获取Sort后,对象传递给Dao层
	 * 5.dao层中,将Sort对象中的数据写入数据表中insert
	 * 6.提示用户添加成功
	 * 7.从新加载分类功能--SortMngController这个对话框的addSort方法中操作
	 * @see com.iheima.gip.view.AbstractOperationSortDialog#comfirm()
	 */
	@Override
	public void comfirm() {
		//对添加功能的数据进行验证
		//获取分类下拉菜单,用户选择的值
		//getSelectedItem获取下拉菜单中选择的内容
		String parent=parentBox.getSelectedItem().toString();
		//获取分类名称
		String sname=snameTxt.getText();
		//
		String sdesc=sdescArea.getText();
		//选择内容不等于=请选择=
		if(parent.equals("=请选择=")){
			//弹出对话框,选择错误
			JOptionPane.showMessageDialog(this, "请选择分类");
			return;
		}
		//验证分类名称不能为空
		if(sname ==null||sname.equals("")){
			JOptionPane.showMessageDialog(this, "请填写分类名称");
		}
		//获取数据封装成SORt
		Sort sort=new Sort(0,sname,parent,sdesc);
		//调用service层SortService方法的addSort(),传递Sort对象
		SortService sortService=new SortService();
		//调用方法addSort传递封装好的Sort对象
		sortService.addSort(sort);
		//提示用户添加分类
		JOptionPane.showMessageDialog(this, "添加分类成功","操作成功",JOptionPane.PLAIN_MESSAGE);
		//关闭自己的对话框
		this.dispose();
		//调用SortService方法querySortAll()加载一次分类数据
		//sortService.querySortAll();
		
	}


}

4.com.itheima.gip.controller创建EditLedgerController

package com.itheima.gip.controller;

import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JDialog;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Ledger;
import com.itheima.gip.services.LedgerServices;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractOperationLedgerDialog;
@SuppressWarnings("all")
public class EditLedgerController extends AbstractOperationLedgerDialog {

	private static final long serialVersionUID = 1L;
	private SortService sortService=new SortService();
	private LedgerServices ledgerService = new LedgerServices();
	private Ledger ledger;
	public EditLedgerController(JDialog dialog ,Ledger ledger) {
		super(dialog);
		titleLabel.setText("编辑账务");
		super.setTitle("编辑账务");
		this.ledger=ledger;
		//编辑对话框中,全数据都显示
		parentBox.setSelectedItem(ledger.getParent());
		//获取到的分类名称,转字符传输组
		String [] items= {ledger.getSname()};
		//调用的是菜单的方法setModel,从新设置菜单数据
		sortBox.setModel(new DefaultComboBoxModel(items));
		
		accountTxt.setText(ledger.getAccount());
		moneyTxt.setText(ledger.getMoney()+"");
		createtimeTxt.setText(ledger.getCreatetime());
		ldescTxt.setText(ledger.getLdesc());
	}
	@Override
	public void changeParent() {
		// 获取收支的选项
		String parent = parentBox.getSelectedItem().toString();
		// parent选择,分类也是请选择
		if (parent.equals("=请选择=")) {
			sortBox.setModel(new DefaultComboBoxModel<>(new String[] { "=请选择=" }));
		}
		// 情况二根据收支选择,去数据库中,查询所有分类内容
		if (parent.equals("收入") || parent.equals("支出")) {
			// 调用services层方法querySortNameByParent(String parent)查询所有分类名称
			// 获取到一个List.toArray()集合,几何中的数据填充到下拉菜单中
			List<Object> list = sortService.querySortNameByParent(parent);
			list.add(0, "=请选择=");
			sortBox.setModel(new DefaultComboBoxModel(list.toArray()));
		}
	}
	/*
	 * 点击编辑的确定按钮调用的方法
	 *获取用户选择数据
	 *对数据进行验证
	 *数据封装成Ledgerd对象
	 *调用serveices
	 */
	@Override
	public void comfirm() {
		String parent =parentBox.getSelectedItem().toString();
		String sname=sortBox.getSelectedItem().toString();
		String account=accountTxt.getText();
		String createtime =createtimeTxt.getText();
		String sMoney=moneyTxt.getText();
		String ldesc=ldescTxt.getText();
		if(parent.equals("=请选择=")){
			JOptionPane.showMessageDialog(this, "请选择分类");
			return;
		}
		if(sname.equals("=请选择=")){
			JOptionPane.showMessageDialog(this, "请选择分类名称");
			return;
		}
		if(account==null||account.isEmpty()){
			JOptionPane.showMessageDialog(this, "请填写账户");
			return;
		}
		//获取到的金额,由String,转出double
		double money = 0;
		try {
			money =Double.parseDouble(sMoney);
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, "必须填写数字");
			return;
		}
		if(money<=0){
			JOptionPane.showMessageDialog(this, "全部金额必须大于0");
			return;
		}
		//将已有的数据封装到Ledger对象中
		ledger.setAccount(account);
		ledger.setCreatetime(createtime);
		ledger.setLdesc(ldesc);
		ledger.setMoney(money);
		ledger.setParent(parent);
		
		int sid =ledgerService.getSidBySname(sname);
		ledger.setSid(sid);
		//调用services方法editLedger
		ledgerService.editLedger(ledger);
		this.dispose();
		JOptionPane.showMessageDialog(this, "编辑成功");
	}
}

5.com.itheima.gip.controller创建EditSortController

package com.itheima.gip.controller;

import javax.swing.JDialog;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Sort;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractOperationSortDialog;
//编辑分类对话框
public class EditSortController extends AbstractOperationSortDialog{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Sort sort;
	public EditSortController(JDialog dialog, Sort sort) {
		super(dialog);
		titlelLabel.setText("编辑分类");
		super.setTitle("编辑分类");
		this .sort=sort;
		// 获取Sort对象中的数据,填充到对话框中
		//Sort对象中,封装的分类,填充到下拉菜单中
		//setSelectedItem,将菜单中,已有打项目,作为默认项目出现
		parentBox.setSelectedItem(sort.getParent());
		snameTxt.setText(sort.getSname());
		sdescArea.setText(sort.getSdesc());
	}
	@Override
	public void comfirm() {
		String parent =parentBox.getSelectedItem().toString();
		String sname=snameTxt.getText();
		String sdesc=sdescArea.getText();
		//此处数据是否符合要求
		if(parent.equals("=选择=")){
			JOptionPane.showMessageDialog(this, "请选择分类");
			return;
		}
		if(sname==null||sname.isEmpty()){
			JOptionPane.showMessageDialog(this, "请输入分类名称");
			return;
		}
		//或取到的数据封装成Sort对象
		sort.setParent(parent);
		sort.setSdesc(sdesc);
		sort.setSname(sname);
		//调用Services层,传递Sort
		SortService sortService=new SortService();
		sortService.editSort(sort);
		this.dispose();
		JOptionPane.showMessageDialog(this, "编辑成功");
		
	}
}

6.com.itheima.gip.controller创建 LedgerMngController

package com.itheima.gip.controller;

import java.util.List;
import java.util.Map;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Ledger;
import com.itheima.gip.domain.QueryForm;
import com.itheima.gip.services.LedgerServices;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractLedgerMngDialog;
//账务管理对话框的控制层
@SuppressWarnings("all")
public class LedgerMngController extends AbstractLedgerMngDialog{

	public LedgerMngController(JFrame frame) {
		super(frame);
	}
	private LedgerServices ledgerServices=new LedgerServices();
	private SortService sortService=new SortService();
	//点击添加账务按钮,弹出添加账务对话框
	@Override
	public void addLedger() {
		new AddLedgerControlle(this).setVisible(true);	
	}
	//点击编辑服务按钮,弹出编辑账务的对话框
	@Override
	public void editLedger() {
		// 获取所选择的行
		int row =ledgerDataTable.getSelectedRow();
		if(row<0){
			JOptionPane.showMessageDialog(this, "请选择要编辑的数据");
			return;
		}
		//调用父类里的方法getLedgerByTableRow,传递行号,获取到一个Ledger对象
		Ledger ledger=getLedgerByTableRow(row);
		if(ledger==null){
			JOptionPane.showMessageDialog(this,"选择的是空行");
			return;
		}
		//弹出编辑对话框,传递给Ledger对象,窗体开启的时候,显示出选择的数据
		new EditLedgerController(this, ledger).setVisible(true);
		queryLedger();
	}
	/**
	 * 点击查询按钮,实现查询功能
	 * 获取的是services层的查询结果
	 * 结果做成Map集合
	 * key :键名value :查询数据List集合
	 * key :键名value :所有收入总和
	 * key :键名value :所有支出总和
	 * map.put ("",数据库结果集List集合)
	 * map.put("",inMoney)
	 * map.put("",payMoney)
	 * 	 */
	@Override
	public void queryLedger() {
		//用户选择查询条件,封装到QueryForm对象中
		String begin=beginDateTxt.getText();
		String end=endDateTxt.getText();
		String parent=parentBox.getSelectedItem().toString();
		String sname=sortBox.getSelectedItem().toString();
		QueryForm form=new QueryForm(begin,end,parent,sname);
		//调用Services 层方法,queryLedgerByQueryForm
		//获取到Map集合,建 :ledger值List集合,填充在表格中
		Map<String, Object> data =ledgerServices.queryLedgerByQueryForm(form);
		List<Ledger> list =(List<Ledger>) data.get("ledger");
		double in=(double)data.get("in");
		double pay=(double)data.get("pay");
		//将查询数据List填充到表格JTable
		this.setTableModel(list);
		//计算后求和,填充到Label中
		inMoneyTotalLabel.setText("总收入"+in+" 元");
		payMoneyTotalLabel.setText("总支出"+pay+" 元");
	}
	//继承AbstractLedgerMngDialog,收支统计图触发器
	@Override
	public void pie() {
		new ShapeControler(this).setVisible(true);
	}
	//点击删除按钮
	@Override
	public void delLedger() {
		// 删除选择的行号
		int row =ledgerDataTable.getSelectedRow();
		if(row <0){
			JOptionPane.showMessageDialog(this, "没有选择数据");
			return;
		}
		//将选择中的行,封装成Ledger对象
		Ledger ledger =getLedgerByTableRow(row);
		if(ledger==null){
			JOptionPane.showMessageDialog(this, "选择的是空行");
			return;
		}
		//确认删除的提示对话框
		int result =JOptionPane.showConfirmDialog(this, "是否确认删除吗");
		if(result ==JOptionPane.OK_OPTION){
			//调用servises层方法deleteLedger,传递Lid值
			ledgerServices.deleteLedger(ledger.getLid());
			//this.dispose();
			JOptionPane.showMessageDialog(this, "删除成功");
		}
		queryLedger();
	}
	/*
	 * 菜单联动调用的方法
	 * 收支菜单,选择后,分类菜单,跟随他进行显示
	 * 情况一
	 * 收支:请选择
	 * 分类:请选择
	 * 情况二
	 * 收支:收入/支出
	 * 分类:所有支出和收入
	 * 根据收支选择,去数据库中,查询所有的分类内容
	 * 情况三
	 * 收支:收入,或者选择支出
	 * 分类:收支选择的是收入,显示收入,收支选择的是支出,显示支出
	 * 根据收支选择,去数据库中,查询所有分类内容
	 *  */
	
	@Override
	public void parentChange() {
		//获取收支的选项
		String parent=parentBox.getSelectedItem().toString();
		//parent选择,分类也是请选择
		if(parent.equals("=请选择=")){
			sortBox.setModel(new DefaultComboBoxModel<>(new String[]{"=请选择="}));
		}
		//情况二,根据数据库查询,收支:收入/支出,查询所有内容
		if(parent.equals("收入/支出")){
			//调用services层方法querySortnameAll()查询所有分类名称
			//获取到一个List。toArray()集合,集合中的数据,填充到下拉菜单中
			List< Object> list=sortService.querySortNameAll();
			list.add(0,"=请选择=");
			sortBox.setModel(new DefaultComboBoxModel(list.toArray()));
		}
		//情况三根据收支选择,去数据库中,查询所有分类内容
		if(parent.equals("收入")||parent.equals("支出")){
			//调用services层方法querySortNameByParent(String parent)查询所有分类名称
			//获取到一个List.toArray()集合,几何中的数据填充到下拉菜单中
			List< Object> list=sortService.querySortNameByParent(parent);
			list.add(0,"=请选择=");
			sortBox.setModel(new DefaultComboBoxModel(list.toArray()));
	
		}
		
	}

}

7.com.itheima.gip.controller创建MainFrameController

package com.itheima.gip.controller;

import com.itheima.gip.view.AbstractMainFrame;

public class MainFrameController extends AbstractMainFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//打开账务管理对话框
	@Override
	public void ledgerMng() {
		new LedgerMngController(this).setVisible(true);
		
	}
	//打开分类管理对话框
	@Override
	public void sortMng() {
		// TODO Auto-generated method stub
		//创建分类对话框的子类对象
		new SortMngController(this).setVisible(true);
	}
	
}
### com.itheima.gip.controller创建ShapeControler
package com.itheima.gip.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.JDialog;

import com.itheima.gip.services.LedgerServices;
import com.itheima.gip.tools.DateUtils;
import com.itheima.gip.tools.JFreeChartUtils;
import com.itheima.gip.view.AbstractShapeDialog;

public class ShapeControler extends AbstractShapeDialog{

	private LedgerServices ledgerServices=new LedgerServices();
	private static final long serialVersionUID = 1L;
	public ShapeControler(JDialog dialog) {
		
		super(dialog);
		initDialog();
	}
	/*
	 * 获取生成图片路径,路径存储到List集合
	 *问题谁生成图片JFreechartUtils静态方法pie();
	 *调用service层方法,获取需要的数据
	 */
	@Override
	public List<String> getImagePaths() {
		List< String> listPath=new ArrayList<String>();
		
		//调用service层方法,获取需要的数据
		Double moneyPay= ledgerServices.queryTotalMoneyByParent("支出");
		Map<String, Double> mapPay=ledgerServices.querySumMoneyBySort("支出");
		
		String title="支出占比图("+moneyPay+") ("+DateUtils.getYear()+"年)";
		String pathPay="pay.jpg";//存储图片路径
		JFreeChartUtils.pie(title,mapPay,moneyPay,pathPay);//调用生成图片函数
		listPath.add(pathPay);
		
		//调用service层方法,获取需要的数据
		Double moneyIn= ledgerServices.queryTotalMoneyByParent("收入");
		Map<String, Double> mapIn=ledgerServices.querySumMoneyBySort("收入");
		
		String titleIn="收入占比图("+moneyIn+") ("+DateUtils.getYear()+"年)";
		String pathIn="in.jpg";
		JFreeChartUtils.pie(titleIn, mapIn, moneyIn ,pathIn);
		listPath.add(pathIn);
		return listPath;
	}
	
}

8.com.itheima.gip.controller创建SortMngController

package com.itheima.gip.controller;

import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.itheima.gip.domain.Sort;
import com.itheima.gip.services.SortService;
import com.itheima.gip.view.AbstractSortMngDialog;
//分类管理对话框的子类
//实现分类管理功能
//显示分类管理界面,new这个子类
public class SortMngController extends AbstractSortMngDialog{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//成员位置,创建出
	private SortService sortService=new SortService();
	public SortMngController(JFrame frame) {
		super(frame);
		//像表格中填充数据
		/*
		 * 实现步骤
		 * 1.调用serive层方法,获取List集合
		 * 2.serive层调用dao层,获取List集合
		 * 3.dao层,查询数据库,数据表中的结果会变成List集合,返回
		 * 4.调用父类方法setTableModel,传递List集合
		 * 5.抽取一个方法,调用即可
		 */
		refrech();
	}
	//添加分类按钮,点击后 调用的方法
	//开启添加分类的对话框
	@Override
	public void addSort() {
		// TODO Auto-generated method stub
		new AddSortController(this).setVisible(true);
		refrech();
	}
	/*
	 * //编辑分类按钮点击后 调用的方法
	 * 开启编辑分类的对话框
	 * 
	 * 对用户选择分类数据进行控制
	 * 不选择
	 * 选择空行
	 * sortDataTable 表格中的方法getSelectRow()获取选择的行,返回-1,没有选择
	 * 选择空行
	 * getSortByTableRow()父类方法,传递选中的行号,返回这一行的数据,封装到Sort对象
	 *如果用户选择有效行,封装好的Sort 对象,传递给EditSortController对话框
	 *后面的实现和新增几乎一致
	 *  */
	@Override
	public void editSort() {
		//获取用户选择的行号
		int row =sortDataTable.getSelectedRow();
		if(row<0){
			JOptionPane.showMessageDialog(this, "请选择数据");
			return;
		}
		// getSortByTableRow()父类方法,传递选中的行号,返回这一行的数据,封装到Sort对象
		Sort sort=getSortByTableRow(row);
		if(sort==null){
			JOptionPane.showMessageDialog(this, "选择的是空行");
			return;
		}
		//sort对象,传递到,编辑分类对话框
		//System.out.println(row);
		new EditSortController(this,sort).setVisible(true);
		refrech();
	}
	/*
	 *点击删除按钮,调用方法
	 *实现步骤
	 *获取选择哪一行
	 *提示对话框,询问用户是否要删除
	 *调用services层方法deletesort,传递sort对象
	 * */
	@Override
	public void delSort() {
		//获取用户行号
		int row =sortDataTable.getSelectedRow();
		if(row<0){
			JOptionPane.showMessageDialog(this, "请选择数据");
			return;
		}
		// getSortByTableRow()父类方法,传递选中的行号,返回这一行的数据,封装到Sort对象
		Sort sort=getSortByTableRow(row);
		if(sort==null){
			JOptionPane.showMessageDialog(this, "选择的是空行");
			return;
		}
		//提示用户,整的要删除吗
		int i = JOptionPane.showConfirmDialog(this, "是否真的要删除吗","删除提示",JOptionPane.YES_NO_OPTION);
		if(i==JOptionPane.YES_NO_OPTION){
			//调用Services层方法deleteSort
			sortService.deleteSort(sort);
			JOptionPane.showMessageDialog(this, "删除成功");
			refrech();
		}
	}
	//刷新显示分类数据
	public void refrech(){
		List<Sort> list=sortService.querySortAll();
		setTableModel(list);
	}

}

9.com.itheima.gip.dao创建 LedgerDao

package com.itheima.gip.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.itheima.gip.domain.Ledger;
import com.itheima.gip.domain.QueryForm;
import com.itheima.gip.tools.JDBCUtils;
import com.itheima.gip.tools.DateUtils;


public class LedgerDao {

	private SortDao sortDao=new SortDao();
	private QueryRunner qr=new QueryRunner(JDBCUtils.getDataSource());
	/*
	 * getTOtalMoney
	 * 通过分类查询今年所有数据的总和,传递参数,收入还是支出
	 */
	public Double getTotalMoney(String parent){
		try {
			String sql="select SUM(money) from gjp_ledger where parent= ? and createtime like ?";
			Object [] params ={parent,DateUtils.getYear()+"%"};
			return (double)qr.query(sql, new ScalarHandler(),params);
		} catch (SQLException e){
			throw new RuntimeException(e);
		}
	}
	/*
	 * querySumMoneyBySort
	 * 通过分类名称查询所有分类数据的总和,传递参数,收入还是支出
	 */
	public List<Object[]>querySumMoneyBySort(String parent){
		try {
			String sql="select SUM(money), sid FROM gjp_ledger where "+
					"parent=? AND createtime like ? group by sid";
			Object [] params ={parent, DateUtils.getYear()+"%"};
			return qr.query(sql, new ArrayListHandler(),params);//返回params对象
		} catch (SQLException e){
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法:删除账务
	 * 传递lid对象
	 */
	public void deleteLedger(int lid) {
		try {
			qr.update("delete from gjp_ledger where lid=?",lid);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法:编辑账务
	 * 传递Ledger对象
	 */
	public void editLedger(Ledger ledger){
		try {
			String sql="update gjp_ledger set parent=?,money=?,sid=?,account=?,createtime=?,ldesc=?"+"where lid=?";
			Object[] params={ledger.getParent(),ledger.getMoney(),ledger.getSid(),ledger.getAccount(),ledger.getCreatetime(),ledger.getLdesc(),ledger.getLid()};
			qr.update(sql,params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}
	/*
	 * 定义方法:添加数据
	 * 传递Ledger对象
	 */
	public void addLedger(Ledger ledger){
		try {
			//编写添加账务SQL语句
			String sql="insert into gjp_ledger(parent,money,sid,account,createtime,ldesc)"+"values (?,?,?,?,?,?)";
			Object []params ={ledger.getParent(),ledger.getMoney(),ledger.getSid(),ledger.getAccount(),ledger.getCreatetime(),ledger.getLdesc()};
			qr.update(sql,params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法,实现查询功能
	 * 传递QueryForm对象
	 * 返回List集合
	 * 根据QueryForm封装的数据,进行SQL语句编写
	 */
	public List<Ledger> queryLedgerByQuerForm(QueryForm form){
		//查询语句中?占位符,也是一个不确定因素,参数选择容器进行储存
		List<String> params=new ArrayList<String>();
		StringBuffer builder=new StringBuffer();
		//查询条件,开始日期和结束日期,不需要理会,必选
		builder.append("select * from gjp_ledger where createtime between ? and ? ");
		params.add(form.getBegin());
		params.add(form.getEnd());
		
		//对查询条件收入或者支出的选择,组合SQL语句
		if(form.getParent().equals("收入")||form.getParent().equals("支出")){
			builder.append("and parent =?");
			params.add(form.getParent());
		}
		//对查询条件,分类名称的选择,进行SQL语句组合
		if(!form.getSname().equals("=请选择=")){
			//获取sname的值,去数据表中查找SId的值
			//调用一个方法SortDao 类的
			int sid=sortDao.getSidBySname(form.getSname());
			builder.append("and sid =?");
			params.add(sid+"");
		}
		try {
			List<Ledger> list=qr.query(builder.toString(), new BeanListHandler<Ledger> (Ledger.class),params.toArray());
			return list;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}	
	}
	/*public static void main(String[] args) {
		QueryForm form=new 
	}*/
}

10.在com.itheima.gip.dao中创建SortDao

package com.itheima.gip.dao;
/*
 * 访问数据库的类
 */

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.itheima.gip.domain.Sort;
import com.itheima.gip.tools.JDBCUtils;

/*
 * 访问数据库的类
 * sortDao类,负责分类功能
 */
@SuppressWarnings("all")

public class SortDao{

	//类的成员位置,定义 QueryRunner 对象,所有的方法都可以直接使用
	private QueryRunner qr= new QueryRunner(JDBCUtils.getDataSource());
	/*
	 * 定义方法,传递分类名称,返回分类ID
	 * 
	 */
	public int getSidBySname(String sname){
		try {
			String sql="select sid from gjp_sort where sname=?";
			return (int)qr.query(sql, new ScalarHandler(),sname);
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法,传递分类ID,返回分类名称
	 * 
	 */
	public String getSnameBySid(int sid){
		try {
			String sql="select sname from gjp_sort where sid=?";
			return (String)qr.query(sql, new ScalarHandler(),sid);
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法,查询所有分类名称,传递字符串查询条件
	 * 有services层调用
	 * 
	 */
	public List<Object> querySortNameByParent(String parent){
		try {
			String sql="select sname from gjp_sort where parent=?";
			return qr.query(sql, new ColumnListHandler(),parent);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}
	/*
	 * 定义方法,编辑分类数据库
	 * 方法传递参数,sort对象querySortNameAll()查询所有分类名称
	 * 返回services集合
	 * 
	 */
	public List<Object> querySortNameAll(){
		try {
			String sql="select sname from gjp_sort";
			return qr.query(sql, new ColumnListHandler());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}
	
	public void editSort(Sort sort){
		try {
			String sql="update gjp_sort set sname=?,parent=?,sdesc=? where sid=?";
			Object[] params={sort.getSname(),sort.getParent(),sort.getSdesc(),sort.getSid()};
			qr.update(sql,params);	
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法,删除分类数据
	 * 方法传递参数,SORT对象
	 * 由Services层调用
	 */
	public void deleteSort(Sort sort){
		try {
			String sql="delete from gjp_sort where sid=?";
			Object[] params={sort.getSid()};
			qr.update(sql,params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*
	 * 定义方法,添加分类数据
	 * 方法需要传递参数,Sort对象
	 * 添加的及时Sort对象中的数据
	 * 没有返回值
	 * 由services层调用
	 */
	public void addSort(Sort sort) {
		try {		
			//拼写SQL语句
			String sql="insert into gjp_sort(sname,parent,sdesc)"+" values (?,?,?)";
			//定义SQL语句中的参数,Object数组
			Object[] params={sort.getSname(),sort.getParent(),sort.getSdesc()};
			//QueryRunner方法update
			qr.update(sql,params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}	
	}
	public List<Sort> querySortAll(){
		try {
			String sql="select * from gjp_sort";
			List<Sort> list=qr.query(sql, new BeanListHandler<Sort>(Sort.class));
			return list;
		} catch (SQLException e){
			//手动抛出运行时期异常
			throw new RuntimeException(e);
		}		
	}
}

11.在com.itheima.gip.domain中创建 Ledger

package com.itheima.gip.domain;

public class Ledger {

	// TODO Auto-generated constructor stub
	private int lid;//账务Id
	private String parent;//
	private double money;
	private int sid;
	private String account;
	private String createtime;
	private String ldesc;
	private String  sname;
	public Ledger(){}
	public Ledger(int lid, String parent, double money, int sid,
			String account, String createtime, String ldesc,String sname) {
		super();
		this.lid = lid;
		this.parent = parent;
		this.money = money;
		this.sid = sid;
		this.account = account;
		this.createtime = createtime;
		this.ldesc = ldesc;
		this.sname=sname;
	}
	
	public int getLid() {
		return lid;
	}
	public void setLid(int lid) {
		this.lid = lid;
	}
	public String getParent() {
		return parent;
	}
	public void setParent(String parent) {
		this.parent = parent;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getAccount() {
		return account;
	}
	public void setAccount(String account) {
		this.account = account;
	}
	public String getCreatetime() {
		return createtime;
	}
	public void setCreatetime(String createtime) {
		this.createtime = createtime;
	}
	public String getLdesc() {
		return ldesc;
	}
	public void setLdesc(String ldesc) {
		this.ldesc = ldesc;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	@Override
	public String toString() {
		return "Ledger [lid=" + lid + ", parent=" + parent + ", money=" + money + ", sid=" + sid + ", account="
				+ account + ", createtime=" + createtime + ", ldesc=" + ldesc + ", sname=" + sname + "]";
	}
}

12.在com.itheima.gip.domain中创建 QueryForm

package com.itheima.gip.domain;
/*
 * 将账务中查询条件,封装成对象
 */
 
public class QueryForm {

	
	private String begin;
	public QueryForm(String begin, String end, String parent, String sname) {
		super();
		this.begin = begin;
		this.end = end;
		this.parent = parent;
		this.sname = sname;
	}
	private String end;
	private String parent;
	private String sname;
	public String getBegin() {
		return begin;
	}
	public void setBegin(String begin) {
		this.begin = begin;
	}
	public String getEnd() {
		return end;
	}
	public void setEnd(String end) {
		this.end = end;
	}
	public String getParent() {
		return parent;
	}
	public void setParent(String parent) {
		this.parent = parent;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	@Override
	public String toString() {
		return "QueryForm [begin=" + begin + ", end=" + end + ", parent=" + parent + ", sname=" + sname + "]";
	}
}

13.在com.itheima.gip.domain中创建 Sort

package com.itheima.gip.domain;


public class Sort {

	private int sid;
	private String sname;
	private String parent;
	private String sdesc;
	public Sort(){}
	public Sort(int sid, String sname, String parent, String sdesc) {
		super();
		this.setSid(sid);
		this.setSname(sname);
		this.setParent(parent);
		this.setSdesc(sdesc);
	}
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getParent() {
		return parent;
	}
	public void setParent(String parent) {
		this.parent = parent;
	}
	public String getSdesc() {
		return sdesc;
	}
	public void setSdesc(String sdesc) {
		this.sdesc = sdesc;
	}
	@Override
	public String toString() {
		return "Sort [sid=" + sid + ", sname=" + sname + ", parent=" + parent + ", sdesc=" + sdesc + "]";
	}
	
}

14.在com.itheima.gip.services中创建LedgerServices

package com.itheima.gip.services;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.itheima.gip.dao.LedgerDao;
import com.itheima.gip.dao.SortDao;
import com.itheima.gip.domain.Ledger;
import com.itheima.gip.domain.QueryForm;

public class LedgerServices {

	private LedgerDao ledgerDao=new LedgerDao();
	private SortDao sortDao=new SortDao();
	/*
	 *queryTotalMoneyByParent,
	 * 调用dao层getTotalMoney,获取收入支出所有金额总和
	 */
	public Double queryTotalMoneyByParent(String parent){
		return ledgerDao.getTotalMoney(parent);
	}
	/*
	 * 调用dao层querySumMoneyBySort,传递父分类,获取这个分类下的球和数据
	 * 每个分类的名称进行分组
	 * Map:键存储的是分类名称,之存储的是这个名称所有分类的总和
	 */
	public Map<String, Double> querySumMoneyBySort(String parent){
		List<Object[]> list=ledgerDao.querySumMoneyBySort(parent);
		//创建MAp集合键存储的是分类名称,之存储的是这个名称所有分类的总和
		Map<String, Double> map=new HashMap<String, Double>();
		//遍历集合List,获取Object数组(根据sid找sname)
		for(Object[] objects:list){
			Double money=(Double)objects[0];
			int sid =(int ) objects[1];
			String sname=sortDao.getSnameBySid(sid);
			map.put(sname, money);
		}
		return map;
	}
	/*
	 * 定义方法:删除账务
	 * deleteLedger,传递lid值
	 */
	public void deleteLedger( int lid){
		ledgerDao.deleteLedger(lid);
	}
	/*
	 * 定义方法:编辑账务
	 * editLedger,传递ledger对象
	 */
	public void editLedger(Ledger ledger){
		ledgerDao.editLedger(ledger);
	}
	/*
	 * 定义方法:添加账务
	 * addLedger,传递ledger对象
	 */
	public void addLedger(Ledger ledger){
		ledgerDao.addLedger(ledger);
	}
	/*
	 * 定义方法:调用sortDao方法getsidBySname
	 * 获取sid
	 */
	public int getSidBySname(String sname){
		return sortDao.getSidBySname(sname);
	}
	/*
	 * 定义方法:返回值是Map集合
	 * 作用,根据用户的条件,查询数据库(List集合)
	 * 遍历List集合,统计收入和支出的求和计算
	 * 存储到Map集合
	 * 调用dao方法 ,查询结果的List集合
	 * 
	 */
	public Map<String,Object> queryLedgerByQueryForm(QueryForm form){
		List< Ledger> list=ledgerDao.queryLedgerByQuerForm(form);
		double in=0;
		double pay=0;
		for(Ledger ledger:list){
			int sid =ledger.getSid();
			//调用Dao层SortDao方法getSnameBySid,传递sid,获取sname
			String sname=sortDao.getSnameBySid(sid);
			ledger.setSname(sname);
			if(ledger.getParent().equals("收入")){
				in+=ledger.getMoney();
			}else{
				pay+=ledger.getMoney();
			}
		}
		//创建Map集合,将数据,List,in,pay存储到Map集合中
		Map< String, Object> data=new HashMap<String, Object>();
		data.put("ledger", list);
		data.put("in", in);
		data.put("pay", pay);
		
		return data;
	}
	
}

15.在com.itheima.gip.services中创建SortService

package com.itheima.gip.services;
import java.util.List;

import com.itheima.gip.dao.SortDao;
import com.itheima.gip.domain.Sort;
//分类共能的业务层
public class SortService {

	//创建Dao层,SortDao类的对象
	private SortDao sortDao=new SortDao();
	/*
	 *  定义方法,调用dao层SortDao# querySortNameByParent(String parent获取所有分类名称
	 * 查询所有分类的名称,传递String参数,父分类
	 */
	public List<Object> querySortNameByParent(String parent){
		return sortDao.querySortNameByParent(parent);
	} 
	/*
	 * 定义方法,调用dao层SortDao# querySortNameAll()获取所有分类名称
	 * 返回的是list集合
	 */
	public List<Object> querySortNameAll(){
		return sortDao.querySortNameAll();
		
	}
	/*
	 * 定义方法,调用dao层SortDao#deletesort()获取所有分类数据
	 * 返回的是list集合,存储Sort对象
	 */
	public void deleteSort(Sort sort){
		sortDao.deleteSort(sort);
	}
	/*
	 * 定义方法,调用DAo层sortdao()实现编辑分类
	 * 传递Sort对象
	 * 是contorllerd调用services层传递Sort
	 */
	public void editSort(Sort sort){
		sortDao.editSort(sort);
	}
	/*
	 * 定义方法,调用dao层SortDao#addSort()添加分类
	 * 传递Sort对象
	 * services层方法中的Sort对象,是contorller传递的
	 */
	public void addSort(Sort sort){
		sortDao.addSort(sort);
	}
	/*
	 * 定义方法,调用dao层SortDao#querySortAll()获取所有分类数据
	 * 返回的是list集合,存储Sort对象
	 */	
	public List<Sort> querySortAll(){
		return sortDao.querySortAll();
	}
}

16.在com.itheima.gip.tools包中创建DateChooser

package com.itheima.gip.tools;
/**

 * 日历选择器

 */

import java.awt.BasicStroke;

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.Cursor;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.Polygon;

import java.awt.Stroke;

import java.awt.Toolkit;

import java.awt.event.FocusEvent;

import java.awt.event.FocusListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.Comparator;

import java.util.Date;

import java.util.List;

 

import javax.swing.BorderFactory;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

import javax.swing.Popup;

import javax.swing.PopupFactory;

import javax.swing.SwingUtilities;

import javax.swing.event.AncestorEvent;

import javax.swing.event.AncestorListener;

 

/** 

 * 日期选择器,可以指定日期的显示格式 

 */

public class DateChooser extends JPanel {

 

	private static final long serialVersionUID = 4529266044762990227L;

 

	private Date initDate;

	private Calendar now = Calendar.getInstance();

	private Calendar select;

	private JPanel monthPanel;//月历  

	private JP1 jp1;//四块面板,组成  

	private JP2 jp2;

	private JP3 jp3;

	private JP4 jp4;

	private Font font = new Font("宋体", Font.PLAIN, 12);

	private final LabelManager lm = new LabelManager();

	private SimpleDateFormat sdf;

	private boolean isShow = false;

	private Popup pop;

 

	private JComponent showDate;

 

	public static DateChooser getInstance() {

		return new DateChooser();

	}

 

	public static DateChooser getInstance(Date date) {

		return new DateChooser(date);

	}

 

	public static DateChooser getInstance(String format) {

		return new DateChooser(format);

	}

 

	public static DateChooser getInstance(Date date, String format) {

		return new DateChooser(date, format);

	}

 

	/** 

	 * Creates a new instance of DateChooser 

	 */

	private DateChooser() {

		this(new Date());

	}

 

	private DateChooser(Date date) {

		this(date, "yyyy-MM-dd");

	}

 

	private DateChooser(String format) {

		this(new Date(), format);

	}

 

	private DateChooser(Date date, String format) {

		initDate = date;

		sdf = new SimpleDateFormat(format);

		select = Calendar.getInstance();

		select.setTime(initDate);

		initPanel();

	}

 

	/** 

	 * 是否允许用户选择 

	 */

	public void setEnabled(boolean b) {

		super.setEnabled(b);

		showDate.setEnabled(b);

	}

 

	/** 

	 *得到当前选择框的日期 

	 */

	public Date getDate() {

		return select.getTime();

	}

 

	public String getStrDate() {

		return sdf.format(select.getTime());

	}

 

	public String getStrDate(String format) {

		sdf = new SimpleDateFormat(format);

		return sdf.format(select.getTime());

	}

 

	//根据初始化的日期,初始化面板  

	private void initPanel() {

		monthPanel = new JPanel(new BorderLayout());

		monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));

		JPanel up = new JPanel(new BorderLayout());

		up.add(jp1 = new JP1(), BorderLayout.NORTH);

		up.add(jp2 = new JP2(), BorderLayout.CENTER);

		monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER);

		monthPanel.add(up, BorderLayout.NORTH);

		monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH);

		this.addAncestorListener(new AncestorListener() {

			public void ancestorAdded(AncestorEvent event) {

 

			}

 

			public void ancestorRemoved(AncestorEvent event) {

 

			}

 

			//只要祖先组件一移动,马上就让popup消失  

			public void ancestorMoved(AncestorEvent event) {

				hidePanel();

			}

		});

	}

 

	public void register(final JComponent showDate) {

		this.showDate = showDate;

 

		showDate.setRequestFocusEnabled(true);

		showDate.addMouseListener(new MouseAdapter() {

			public void mousePressed(MouseEvent me) {

				showDate.requestFocusInWindow();

			}

		});

		this.setBackground(Color.WHITE);

		this.add(showDate, BorderLayout.CENTER);

		this.setPreferredSize(new Dimension(90, 25));

		this.setBorder(BorderFactory.createLineBorder(Color.GRAY));

		showDate.addMouseListener(new MouseAdapter() {

			public void mouseEntered(MouseEvent me) {

				if (showDate.isEnabled()) {

					showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));

					showDate.setForeground(Color.RED);

				}

			}

 

			public void mouseExited(MouseEvent me) {

				if (showDate.isEnabled()) {

					showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

					showDate.setForeground(Color.BLACK);

				}

			}

 

			public void mousePressed(MouseEvent me) {

				if (showDate.isEnabled()) {

					showDate.setForeground(Color.CYAN);

					if (isShow) {

						hidePanel();

					} else {

						showPanel(showDate);

					}

				}

			}

 

			public void mouseReleased(MouseEvent me) {

				if (showDate.isEnabled()) {

					showDate.setForeground(Color.BLACK);

				}

			}

		});

		showDate.addFocusListener(new FocusListener() {

			public void focusLost(FocusEvent e) {

				hidePanel();

			}

 

			public void focusGained(FocusEvent e) {

 

			}

		});

	}

 

	//根据新的日期刷新  

	private void refresh() {

		jp1.updateDate();

		jp2.updateDate();

		jp3.updateDate();

		jp4.updateDate();

		SwingUtilities.updateComponentTreeUI(this);

	}

 

	//提交日期  

	private void commit() {

		//TODO add other components here

		if (showDate instanceof JTextField) {

			((JTextField) showDate).setText(sdf.format(select.getTime()));

		}else if (showDate instanceof JLabel) {

			((JLabel) showDate).setText(sdf.format(select.getTime()));

		}

 

		hidePanel();

	}

 

	//隐藏日期选择面板  

	private void hidePanel() {

		if (pop != null) {

			isShow = false;

			pop.hide();

			pop = null;

		}

	}

 

	//显示日期选择面板  

	private void showPanel(Component owner) {

		if (pop != null) {

			pop.hide();

		}

		Point show = new Point(0, showDate.getHeight());

		SwingUtilities.convertPointToScreen(show, showDate);

		Dimension size = Toolkit.getDefaultToolkit().getScreenSize();

		int x = show.x;

		int y = show.y;

		if (x < 0) {

			x = 0;

		}

		if (x > size.width - 295) {

			x = size.width - 295;

		}

		if (y < size.height - 170) {

		} else {

			y -= 188;

		}

		pop = PopupFactory.getSharedInstance().getPopup(owner, monthPanel, x, y);

		pop.show();

		isShow = true;

	}

   /** 

    * 最上面的面板用来显示月份的增减 

    */

   private class JP1 extends JPanel {

   	private static final long serialVersionUID = -5638853772805561174L;

   	JLabel yearleft, yearright, monthleft, monthright, center, centercontainer;



   	public JP1() {

   		super(new BorderLayout());

   		this.setBackground(new Color(160, 185, 215));

   		initJP1();

   	}



   	private void initJP1() {

   		yearleft = new JLabel("  <<", JLabel.CENTER);

   		yearleft.setToolTipText("上一年");

   		yearright = new JLabel(">>  ", JLabel.CENTER);

   		yearright.setToolTipText("下一年");

   		yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));

   		yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));



   		monthleft = new JLabel("  <", JLabel.RIGHT);

   		monthleft.setToolTipText("上一月");

   		monthright = new JLabel(">  ", JLabel.LEFT);

   		monthright.setToolTipText("下一月");

   		monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));

   		monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));



   		centercontainer = new JLabel("", JLabel.CENTER);

   		centercontainer.setLayout(new BorderLayout());

   		center = new JLabel("", JLabel.CENTER);



   		centercontainer.add(monthleft, BorderLayout.WEST);

   		centercontainer.add(center, BorderLayout.CENTER);

   		centercontainer.add(monthright, BorderLayout.EAST);



   		this.add(yearleft, BorderLayout.WEST);

   		this.add(centercontainer, BorderLayout.CENTER);

   		this.add(yearright, BorderLayout.EAST);

   		this.setPreferredSize(new Dimension(295, 25));



   		updateDate();



   		yearleft.addMouseListener(new MouseAdapter() {

   			public void mouseEntered(MouseEvent me) {

   				yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));

   				yearleft.setForeground(Color.RED);

   			}



   			public void mouseExited(MouseEvent me) {

   				yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

   				yearleft.setForeground(Color.BLACK);

   			}



   			public void mousePressed(MouseEvent me) {

   				select.add(Calendar.YEAR, -1);

   				yearleft.setForeground(Color.WHITE);

   				refresh();

   			}



   			public void mouseReleased(MouseEvent me) {

   				yearleft.setForeground(Color.BLACK);

   			}

   		});

   		yearright.addMouseListener(new MouseAdapter() {

   			public void mouseEntered(MouseEvent me) {

   				yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));

   				yearright.setForeground(Color.RED);

   			}



   			public void mouseExited(MouseEvent me) {

   				yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

   				yearright.setForeground(Color.BLACK);

   			}



   			public void mousePressed(MouseEvent me) {

   				select.add(Calendar.YEAR, 1);

   				yearright.setForeground(Color.WHITE);

   				refresh();

   			}



   			public void mouseReleased(MouseEvent me) {

   				yearright.setForeground(Color.BLACK);

   			}

   		});

   		monthleft.addMouseListener(new MouseAdapter() {

   			public void mouseEntered(MouseEvent me) {

   				monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));

   				monthleft.setForeground(Color.RED);

   			}



   			public void mouseExited(MouseEvent me) {

   				monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

   				monthleft.setForeground(Color.BLACK);

   			}



   			public void mousePressed(MouseEvent me) {

   				select.add(Calendar.MONTH, -1);

   				monthleft.setForeground(Color.WHITE);

   				refresh();

   			}



   			public void mouseReleased(MouseEvent me) {

   				monthleft.setForeground(Color.BLACK);

   			}

   		});

   		monthright.addMouseListener(new MouseAdapter() {

   			public void mouseEntered(MouseEvent me) {

   				monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));

   				monthright.setForeground(Color.RED);

   			}



   			public void mouseExited(MouseEvent me) {

   				monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

   				monthright.setForeground(Color.BLACK);

   			}



   			public void mousePressed(MouseEvent me) {

   				select.add(Calendar.MONTH, 1);

   				monthright.setForeground(Color.WHITE);

   				refresh();

   			}



   			public void mouseReleased(MouseEvent me) {

   				monthright.setForeground(Color.BLACK);

   			}

   		});

   	}



   	private void updateDate() {

   		center.setText(select.get(Calendar.YEAR) + "年" + (select.get(Calendar.MONTH) + 1) + "月");

   	}

   }
	private class JP2 extends JPanel {

		private static final long serialVersionUID = -8176264838786175724L;

 

		public JP2() {

			this.setPreferredSize(new Dimension(295, 20));

		}

 

		protected void paintComponent(Graphics g) {

			g.setFont(font);

			g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10);

			g.drawLine(0, 15, getWidth(), 15);

		}

 

		private void updateDate() {

 

		}

	}
	private class JP3 extends JPanel {

		private static final long serialVersionUID = 43157272447522985L;

 

		public JP3() {

			super(new GridLayout(6, 7));

			this.setPreferredSize(new Dimension(295, 100));

			initJP3();

		}

 

		private void initJP3() {

			updateDate();

		}

 

		public void updateDate() {

			this.removeAll();

			lm.clear();

			Date temp = select.getTime();

			Calendar select = Calendar.getInstance();

			select.setTime(temp);

			select.set(Calendar.DAY_OF_MONTH, 1);

			int index = select.get(Calendar.DAY_OF_WEEK);

			int sum = (index == 1 ? 8 : index);

			select.add(Calendar.DAY_OF_MONTH, 0 - sum);

			for (int i = 0; i < 42; i++) {

				select.add(Calendar.DAY_OF_MONTH, 1);

				lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));

			}

			for (MyLabel my : lm.getLabels()) {

				this.add(my);

			}

			select.setTime(temp);

		}

	}
	private class MyLabel extends JLabel implements Comparator<MyLabel>, MouseListener, MouseMotionListener {

		private static final long serialVersionUID = 3668734399227577214L;

		private int year, month, day;

		private boolean isSelected;

 

		public MyLabel(int year, int month, int day) {

			super("" + day, JLabel.CENTER);

			this.year = year;

			this.day = day;

			this.month = month;

			this.addMouseListener(this);

			this.addMouseMotionListener(this);

			this.setFont(font);

			if (month == select.get(Calendar.MONTH)) {

				this.setForeground(Color.BLACK);

			} else {

				this.setForeground(Color.LIGHT_GRAY);

			}

			if (day == select.get(Calendar.DAY_OF_MONTH)) {

				this.setBackground(new Color(160, 185, 215));

			} else {

				this.setBackground(Color.WHITE);

			}

		}

 

		public boolean getIsSelected() {

			return isSelected;

		}

 

		public void setSelected(boolean b, boolean isDrag) {

			isSelected = b;

			if (b && !isDrag) {

				int temp = select.get(Calendar.MONTH);

				select.set(year, month, day);

				if (temp == month) {

					SwingUtilities.updateComponentTreeUI(jp3);

				} else {

					refresh();

				}

			}

			this.repaint();

		}

 

		protected void paintComponent(Graphics g) {

			if (day == select.get(Calendar.DAY_OF_MONTH) && month == select.get(Calendar.MONTH)) {

				//如果当前日期是选择日期,则高亮显示  

				g.setColor(new Color(160, 185, 215));

				g.fillRect(0, 0, getWidth(), getHeight());

			}

			if (year == now.get(Calendar.YEAR) && month == now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)) {

				//如果日期和当前日期一样,则用红框  

				Graphics2D gd = (Graphics2D) g;

				gd.setColor(Color.RED);

				Polygon p = new Polygon();

				p.addPoint(0, 0);

				p.addPoint(getWidth() - 1, 0);

				p.addPoint(getWidth() - 1, getHeight() - 1);

				p.addPoint(0, getHeight() - 1);

				gd.drawPolygon(p);

			}

			if (isSelected) {//如果被选中了就画出一个虚线框出来  

				Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);

				Graphics2D gd = (Graphics2D) g;

				gd.setStroke(s);

				gd.setColor(Color.BLACK);

				Polygon p = new Polygon();

				p.addPoint(0, 0);

				p.addPoint(getWidth() - 1, 0);

				p.addPoint(getWidth() - 1, getHeight() - 1);

				p.addPoint(0, getHeight() - 1);

				gd.drawPolygon(p);

			}

			super.paintComponent(g);

		}

 

		public boolean contains(Point p) {

			return this.getBounds().contains(p);

		}

 

		private void update() {

			repaint();

		}

 

		public void mouseClicked(MouseEvent e) {

		}

 

		public void mousePressed(MouseEvent e) {

			isSelected = true;

			update();

		}

 

		public void mouseReleased(MouseEvent e) {

			Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);

			lm.setSelect(p, false);

			commit();

		}

 

		public void mouseEntered(MouseEvent e) {

		}

 

		public void mouseExited(MouseEvent e) {

		}

 

		public void mouseDragged(MouseEvent e) {

			Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);

			lm.setSelect(p, true);

		}

 

		public void mouseMoved(MouseEvent e) {

		}

 

		public int compare(MyLabel o1, MyLabel o2) {

			Calendar c1 = Calendar.getInstance();

			c1.set(o1.year, o2.month, o1.day);

			Calendar c2 = Calendar.getInstance();

			c2.set(o2.year, o2.month, o2.day);

			return c1.compareTo(c2);

		}

	}


   private class LabelManager {

   	private List<MyLabel> list;



   	public LabelManager() {

   		list = new ArrayList<MyLabel>();

   	}



   	public List<MyLabel> getLabels() {

   		return list;

   	}



   	public void addLabel(MyLabel my) {

   		list.add(my);

   	}



   	public void clear() {

   		list.clear();

   	}



   	@SuppressWarnings("unused")

   	public void setSelect(MyLabel my, boolean b) {

   		for (MyLabel m : list) {

   			if (m.equals(my)) {

   				m.setSelected(true, b);

   			} else {

   				m.setSelected(false, b);

   			}

   		}

   	}



   	public void setSelect(Point p, boolean b) {

   		//如果是拖动,则要优化一下,以提高效率  

   		if (b) {

   			//表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和  

   			//将要显示的标签找到了就可以了  

   			boolean findPrevious = false, findNext = false;

   			for (MyLabel m : list) {

   				if (m.contains(p)) {

   					findNext = true;

   					if (m.getIsSelected()) {

   						findPrevious = true;

   					} else {

   						m.setSelected(true, b);

   					}

   				} else if (m.getIsSelected()) {

   					findPrevious = true;

   					m.setSelected(false, b);

   				}

   				if (findPrevious && findNext) {

   					return;

   				}

   			}

   		} else {

   			MyLabel temp = null;

   			for (MyLabel m : list) {

   				if (m.contains(p)) {

   					temp = m;

   				} else if (m.getIsSelected()) {

   					m.setSelected(false, b);

   				}

   			}

   			if (temp != null) {

   				temp.setSelected(true, b);

   			}

   		}

   	}



   }


	private class JP4 extends JPanel {

		private static final long serialVersionUID = -6391305687575714469L;

 

		public JP4() {

			super(new BorderLayout());

			this.setPreferredSize(new Dimension(295, 20));

			this.setBackground(new Color(160, 185, 215));

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

			final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));

			jl.setToolTipText("点击选择今天日期");

			this.add(jl, BorderLayout.CENTER);

			jl.addMouseListener(new MouseAdapter() {

				public void mouseEntered(MouseEvent me) {

					jl.setCursor(new Cursor(Cursor.HAND_CURSOR));

					jl.setForeground(Color.RED);

				}

 

				public void mouseExited(MouseEvent me) {

					jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

					jl.setForeground(Color.BLACK);

				}

 

				public void mousePressed(MouseEvent me) {

					jl.setForeground(Color.WHITE);

					select.setTime(new Date());

					refresh();

					commit();

				}

 

				public void mouseReleased(MouseEvent me) {

					jl.setForeground(Color.BLACK);

				}

			});

		}

		private void updateDate() {

		}

	}
	/*public static void main(String[] args) {

		DateChooser dateChooser1 = DateChooser.getInstance("yyyy-MM-dd");

		DateChooser dateChooser2 = DateChooser.getInstance("yyyy-MM-dd");

		JTextField showDate1 = new JTextField("单击选择日期");

		JLabel showDate2 = new JLabel("单击选择日期");

 

		dateChooser1.register(showDate1);

		dateChooser2.register(showDate2);

 

		JFrame jf = new JFrame("测试日期选择器");

		jf.add(showDate1, BorderLayout.NORTH);

		jf.add(showDate2, BorderLayout.SOUTH);

		jf.pack();

		jf.setLocationRelativeTo(null);

		jf.setVisible(true);

		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}*/
}


17.在com.itheima.gip.tools中创建DateUtils

package com.itheima.gip.tools;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateUtils {

	 //获取当前年
	public static int getYear(){
		return Calendar.getInstance().get(Calendar.YEAR);
	}
	//获取今年第一天
	public static String firstdayByYear(){
		int year = Calendar.getInstance().get(Calendar.YEAR);
		return year +"-01-01";
	}
	//获取今年最后一天
	public static String lastdayByYear(){
		int year =Calendar.getInstance().get(Calendar.YEAR);
		return year+"-12-31";
	}
	//把字符串专换成java.sql.date
	public static java.sql.Date toSQLDate(String str){
		return new java.sql.Date(string2Date(str).getTime());
	}
	//获取当前时间字符串
	public static String today(){
		return date2String(new java.util.Date());
	}
	//把Date类型转换成字符串类型
	private static String date2String(java.util.Date date) {
		// TODO Auto-generated method stub
		return String.format("%tF", date);
	}
	private static java.sql.Date string2Date(String str) {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		try {
			return (java.sql.Date) sdf.parse(str);
		} catch (ParseException e) {
			// TODO: handle exception
			throw new RuntimeException("日期字符格式错误:"+str); 
		}
	}
	//返回本月第一天
	public static java.util.Date getFirstDayofMethod(){
		Calendar c =Calendar.getInstance();//获取当前日期对象
		c.set(Calendar.DAY_OF_MONTH,1);//设置日期为1
		return c.getTime();
	}
	//返回本月最后1天
	public static java.util.Date getLastDayofMethod(){
		Calendar c =Calendar.getInstance();//获取当前日期对象
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}
}

18.在com.itheima.gip.tools中创建DateUtils

package com.itheima.gip.tools;
import java.awt.*;
//工具类
import javax.swing.JFrame;

import java.awt.Toolkit;

public class GUITools{

    //JAVA提供的GUI默认工具对象
	static Toolkit kit= Toolkit.getDefaultToolkit();
	//将指定组件屏幕居中
	public static void center(Component c){
		int x= (kit.getScreenSize().width-c.getWidth())/2;
		int y= (kit.getScreenSize().height-c.getHeight())/2;
		c.setLocation(x, y);
	}
	//为指定窗口设置图表标题
	public static void setTitleImage(JFrame frame ,String titleIconPath){
		frame.setIconImage(kit.createImage(titleIconPath));
	}
	
}

19.在com.itheima.gip.tools中创建 JDBCUtils

package com.itheima.gip.tools;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;

public class JDBCUtils {

	//加载驱动
	public static final String DRIVER_CLASS_NAME="com.mysql.jdbc.Driver";
	public static final String URL="jdbc:mysql://localhost:3306/gjp";
	public static final String USERNAME="root";
	public static final String PASSWORD="123456";
	
	private static final int MAX_IDLE=3;
	private static final long MAX_WAIT=5000;
	private static final int MAX_ACTIVE=5;
	private static final int INITIAL_SIZE=3;
	
	private static BasicDataSource dataSource=new BasicDataSource();
	static {
		dataSource.setDriverClassName(DRIVER_CLASS_NAME);
		dataSource.setUrl(URL);
		dataSource.setUsername(USERNAME);
		dataSource.setPassword(PASSWORD);
		
		dataSource.setMaxActive(MAX_ACTIVE);
		dataSource.setMaxWait(MAX_WAIT);
		dataSource.setMaxActive(MAX_IDLE);
		dataSource.setInitialSize(INITIAL_SIZE);
	}
	public static DataSource getDataSource(){
		return   dataSource;
	}
}

20.在com.itheima.gip.tools中创建 JFreeChartUtils

package com.itheima.gip.tools;
import java.io.File;
import java.util.Map;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

/*
	 * 使用jfreechart生成图片
	 * 
	 * @param title 标题
	 * 
	 * @param totalMap 数据(key:分类名称, value:该分类的汇总数据,例如分类名称为"工资收入",汇总数据为所有工资收入的和)
	 * 
	 * @param sum 汇总数据和(例如"工资收入汇总 + 股票收入汇总 + ....")
	 * 
	 * @param path 生成图片保存路径
	 */
public class JFreeChartUtils {

	public static void pie (String title ,Map<String ,Double>totalMap,double sum ,String path){
		DefaultPieDataset pieDataset =new DefaultPieDataset();
		for (String dataName :totalMap.keySet()){
			double dataValue =totalMap.get(dataName);
			String bf=String.format("%.2f%%", dataValue/sum*100);
			dataName=dataName +":"+dataValue+"元("+bf+")";//分块名称:(价钱总数)元 所占比例
			pieDataset.setValue(dataName, dataValue);//dataName分块名称,dataValue分块所占比例
		}
		JFreeChart chart=ChartFactory.createPieChart3D(title, pieDataset, true, true, false);//创建一个丙型3d图
		try {
			ChartUtilities.saveChartAsJPEG(new File(path), chart, 500, 300);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

21.在com.itheima.gip.tools中创建 ListTableModel< T >

package com.itheima.gip.tools;



import javax.swing.table.AbstractTableModel;
import org.apache.commons.beanutils.BeanUtils;



public class ListTableModel< T > extends AbstractTableModel{

	private static final long serialVersionUID=1L;
	private java.util.List<T> list;
	private String [] colNames;
	private String [] propNames;
	 
	
	public ListTableModel(java.util.List<T> list, Class<?> c, String[] colNames, String[] propNames) throws Exception {
		if(list==null){
			throw new Exception();
		}
		this.list = list;
		this.colNames = colNames;
		this.propNames = propNames;
	}
	@Override
	public int getRowCount() {
		int size =list.size();
		return size<10?10:size;
	}
	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return colNames.length;
	}
	public String getColumnName(int c){
		return colNames[c];
		
	}
	@Override
	public Object getValueAt(int r, int c) {
		if(r>=list.size())return null;
		try {
			return BeanUtils.getProperty(list.get(r), propNames[c]);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public T getInstance (int row) {//根据所选的行,生成一个数据封装实体对象
		if( row >=list.size())return null;
		return list.get(row);
		
	}
}

22.在com.itheima.gip.view;中创建 AbstractLedgerMngDialog

package com.itheima.gip.view;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Date;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;


import com.itheima.gip.domain.Ledger;
import com.itheima.gip.tools.DateChooser;
import com.itheima.gip.tools.DateUtils;
import com.itheima.gip.tools.GUITools;
import com.itheima.gip.tools.ListTableModel;
//管理帐务对话框
@SuppressWarnings("all")
public abstract class AbstractLedgerMngDialog extends JDialog{
		
	private static final long serialVersionUID = 1L;
	private DateChooser dateChooser=DateChooser.getInstance("yyyy-MM-dd");
	protected JTextField beginDateTxt =new JTextField(6);//开始查询时间
	protected JTextField endDateTxt =new JTextField(6);//结束查询时间
	
	protected JComboBox parentBox =new JComboBox();//父类下拉列表
	protected JComboBox sortBox =new JComboBox();//分类下拉列表
	protected JTable ledgerDataTable=new JTable();//账务数据列表
	protected JLabel inMoneyTotalLabel=new JLabel("总收入:0.00元");
	protected JLabel payMoneyTotalLabel=new JLabel("总支出:0.00元");
	
	private JButton queryBtn=new JButton("查询");
	private JButton pieBtn=new JButton("收/支比重统计");
	private JButton closeBtn=new JButton("关闭");
	
	private JButton addBtn=new JButton("添加");
	private JButton editBtn=new JButton("编辑");
	private JButton delBtn=new JButton("删除");
	
	public AbstractLedgerMngDialog(JFrame frame) {
		super(frame,true);
		this.initDialog();
	}
	public void initDialog(){
		init();
		addComponent();
		addListener();
	}
	//初始化操作
	private void init() {
		this.setResizable(false);
		this.setTitle("财务管理");
		this.setSize(680, 400);
		this.setLayout(null);
		GUITools.center(this);//居中
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	}
	//添加组件
	private void addComponent(){
		//设置标签标题
		JLabel titlelLabel =new JLabel();
		titlelLabel.setFont(new Font("宋体",Font.ITALIC,18));
		titlelLabel.setText("财务管理");
		titlelLabel.setBounds(280, 20, 165, 20);
		this.add(titlelLabel);
		// 起始日期
		JLabel beginDateLabel = new JLabel("起始:");
		beginDateLabel.setBounds(30, 70, 60, 28);
		this.beginDateTxt.setBounds(70, 70, 80, 28);
		this.beginDateTxt.setEditable(false);
		beginDateTxt.setText(String.format("%tF", DateUtils.getFirstDayofMethod()));
		dateChooser.getInstance().register(this.beginDateTxt);
		this.add(beginDateLabel);
		this.add(this.beginDateTxt);
		// 结束日期
		JLabel endDateLabel = new JLabel("至:");
		endDateLabel.setBounds(160, 70, 30, 28);
		this.endDateTxt.setBounds(190, 70, 80, 28);
		this.endDateTxt.setEditable(false);
		endDateTxt.setText(String.format("%tF", new Date()));
		dateChooser.getInstance().register(this.endDateTxt);
		this.add(endDateLabel);
		this.add(this.endDateTxt);
		//收支选择
		JLabel inAndPayLabel=new JLabel("收/支:");
		inAndPayLabel.setBounds(280, 70, 50, 28);
		parentBox.setModel(new DefaultComboBoxModel(new String[]{"=请选择=","收入","支出"}));
		this.parentBox.setBounds(320, 70, 90, 28);
		this.add(inAndPayLabel);
		this.add(parentBox);
		//收支项目
		JLabel sortLabel=new JLabel("分类");
		sortLabel.setBounds(420, 70, 50, 28);
		sortBox.setModel(new DefaultComboBoxModel(new String[]{"=请选择="}));//,"收入","支出"
		this.sortBox.setBounds(460, 70, 110, 28);
		this.add(sortLabel);
		this.add(this.sortBox);
		//查询按钮
		queryBtn.setBounds(580,70, 70, 28);
		this.add(queryBtn);
		// 滚动面版
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(30, 100, 620, 160);
		setTableModel(null);
		
		ledgerDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 单选
		ledgerDataTable.getTableHeader().setReorderingAllowed(false);// 列不能移动
		
		scrollPane.setViewportView(ledgerDataTable);
		this.add(scrollPane);
		//总收入标签
		this.inMoneyTotalLabel.setBounds(400, 260, 120, 28);
		this.add(inMoneyTotalLabel);
		//inMoneyTotalLabel.setForeground(new java.awt.color(0,1));
		//总支出标签
		this.payMoneyTotalLabel.setBounds(530, 260, 120, 28);
		this.add(payMoneyTotalLabel);
		//payMoneyTotalLabel.setForeground(new java.awt.color(25,1));
		//按钮
		addBtn.setBounds(30, 290, 140, 28);
		this.add(addBtn);
		editBtn.setBounds(270, 290, 140, 28);
		this.add(editBtn);
		delBtn.setBounds(510, 290, 140, 28);
		this.add(delBtn);
		//收支统计报表按钮
		pieBtn.setBounds(30, 330, 140, 28);
		this.add(pieBtn);
		//关闭按钮
		closeBtn.setBounds(30, 330, 140, 28);
		this.add(closeBtn);
	}
	@SuppressWarnings("all")//压制警告
	//编辑删除分类
	//传递选择的第几行
	//将选择的哪一行,所有数据封装成一个Sort对象
	protected Ledger getLedgerByTableRow(int row ){
		return ((ListTableModel<Ledger>)ledgerDataTable.getModel()).getInstance(row);	
	}
	//显示账务表格
	protected void setTableModel(List<Ledger> ledgerList){
		String [] colNames=new String[] {"ID","收/支","分类","金额","账户","创建时间","说明"};
		String [] propNames=new String[] {"lid","parent","money","sid","account","createtime","ldesc"};
		if(ledgerList==null||ledgerList.size()==0){
			ledgerDataTable.setModel(new DefaultTableModel(new Object[][]{
				{null,null,null,null,null,null,null},{null,null,null,null,null,null,null},
				{null,null,null,null,null,null,null},{null,null,null,null,null,null,null},
				{null,null,null,null,null,null,null},{null,null,null,null,null,null,null},
				{null,null,null,null,null,null,null},{null,null,null,null,null,null,null}}
				,colNames));
			ledgerDataTable.setEnabled(false);
			return;
		}
		try {
			ledgerDataTable.setModel(new ListTableModel<Ledger>(ledgerList,Ledger.class,colNames,propNames));
			ledgerDataTable.setEnabled(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
				
	}
	//添加监听器
	private void addListener(){
		//查询按钮
		queryBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				queryLedger();
			}	
		});
		//
		pieBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				pie();
			}	
		});
		//关闭
		closeBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				AbstractLedgerMngDialog.this.dispose();
			}	
		});
		//添加账务
		addBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				addLedger();
			}	
		});
		//编辑账务
		editBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				editLedger();
			}	
		});
		//删除账务
		delBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				delLedger();
			}	
		});
		//选择分类,父分类下拉菜单事件
		//实现联动
		parentBox.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				parentChange();
			}	
		});
		ledgerDataTable.addMouseListener(new MouseListener() {
			@Override
			public void mouseReleased(MouseEvent e) {		
			}
			@Override
			public void mousePressed(MouseEvent e) {
			}
			@Override
			public void mouseExited(MouseEvent e) {		
			}	
			@Override
			public void mouseEntered(MouseEvent e) {		
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				if(e.getButton()==1){
					if(e.getClickCount()>=2){
						editLedger();
					}
				}
				
			}
		});
	}
	//点击确定按钮时调用
	public abstract  void queryLedger();
	public abstract  void pie();//生成饼形图
	public abstract  void addLedger();
	public abstract  void editLedger();
	public abstract  void delLedger();
	public abstract  void parentChange();
	

}

23.在com.itheima.gip.view;中创建 AbstractMainFrame

package com.itheima.gip.view;

import java.awt.BorderLayout;
//import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.itheima.gip.tools.GUITools;


//主窗体,需要子类继承后显示
//包括两个按钮,功能由子类实现
import javax.swing.JLabel;
import javax.swing.JPanel;

public abstract class AbstractMainFrame  extends JFrame{


	private static final long serialVersionUID = 1L;//添加序列号,没用
	static {
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");//控制界面显示效果的类
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	//组件
	private JLabel titleLabel= new JLabel(new ImageIcon("D:\\Workspaces\\MyEclipse 2017 CI\\gjp\\gjp图片\\gip.jpg")) ;//标题
	private JButton ledgerBtn= new JButton("财务管理");//财务管理
	private JButton sortBtn= new JButton("分类管理");//分类管理
	
	public AbstractMainFrame() {
		this.init();//初始化操作
		this.addComponent();//添加组件
		this.addListener();//添加监听器
	}
	//初始化操作
	private void init(){
		this.setTitle("欢迎使用管家婆家庭记账软件");//标题
		this.setSize(600,400);//窗体大小
		GUITools.center(this);//居中
		this.setResizable(false);//窗体大小固定
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//setDefaultCloseOperation设置用户在此窗体上发起 "close" 时默认执行的操作。
		//EXIT_ON_CLOSE  退出应用程序默认窗口关闭操作。
	}
	//添加组件
	private void addComponent(){
		//窗体使用默认的边界布局,北区放图片
		this.add(this.titleLabel,BorderLayout.NORTH);
		//创建JPanel对象
		JPanel btnPanel = new JPanel();
		//清除布局使JPanel中的组件可以自定义位置
		btnPanel.setLayout(null);
		//将JPanel对象添加到窗体中
		this.add(btnPanel);
		//定义边界位置
		ledgerBtn.setBounds(40,20,120,50);
		sortBtn.setBounds(440,20,120,50);
		//Font font =new Font( "","Font","BOLD",20);
		//将按钮添加到JPanel对象中
		btnPanel.add(ledgerBtn);
		btnPanel.add(sortBtn);
	}
	//添加监听器
	private void addListener(){
		//账务管理模块开启按钮
		ledgerBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				ledgerMng();	
			}	
		});
		//分类管理模块
		sortBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				sortMng();	
			}	
		});
	}
	//展示管理界面方法
	public abstract  void ledgerMng();
	public abstract  void sortMng();
}

24.在com.itheima.gip.view;中创建 AbstractOperationLedgerDialog

package com.itheima.gip.view;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import com.itheima.gip.tools.DateChooser;
import com.itheima.gip.tools.GUITools;
//账务操作对话框,实现添加账务,操作账务
@SuppressWarnings("all")
public abstract class AbstractOperationLedgerDialog extends JDialog{

	private DateChooser dateChooser=DateChooser.getInstance("yyyy-MM-dd");
	protected JComboBox parentBox=new JComboBox();//大分类下拉表
	protected JComboBox sortBox=new JComboBox();//小分类下拉表
	protected JTextField accountTxt =new JTextField();//账户文本框
	protected JTextField moneyTxt =new JTextField("0.0");//金额文本框
	protected JTextField createtimeTxt =new JTextField();//创建日期文本框
	
	protected JTextArea ldescTxt=new JTextArea();//调用文本域
	protected JLabel titleLabel=new JLabel("需要子类设置");
	
	private JButton cancelBtn=new JButton("取消");
	private JButton submitBtn=new JButton("确定");
	
	public AbstractOperationLedgerDialog(JDialog dialog) {
		super(dialog,true);
		this.initDialog();
	}
	public void initDialog(){
		init();
		addComponent();
		addListener();
	}
	//初始化操作
	private void init() {
		this.setResizable(false);
		this.setSize(400, 450);
		this.setLayout(null);
		GUITools.center(this);//居中
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	}
	//添加组件
	private void addComponent(){
		//标题标签
		titleLabel.setFont(new Font("宋体",0,18));
		titleLabel.setBounds(160, 10, 120, 28);
		this.add(titleLabel);
		//选择下拉列表
		JLabel parentLabel= new JLabel("收/支:");
		parentLabel.setBounds(30, 50, 50, 28);
		parentBox.setModel(new DefaultComboBoxModel(new String[]{"=请选择=","收入","支出"}));
		parentBox.setBounds(70, 50, 100, 28);
		this.add(parentLabel);
		this.add(parentBox);
		//分类名称
		JLabel sortLabel=new JLabel("分类:");
		sortLabel.setBounds(30, 90, 50, 28);
		sortBox.setModel(new DefaultComboBoxModel(new String[]{"=请选择="}));
		sortBox.setBounds(70, 90, 100, 28);
		this.add(sortLabel);
		this.add(sortBox);
		//账户
		JLabel accountLabel=new JLabel("账户:");
		accountLabel.setBounds(30, 130, 50, 28);
		accountTxt.setBounds(70, 130, 200, 28);
		this.add(accountLabel);
		this.add(this.accountTxt);
		//金额
		JLabel moneyLabel=new JLabel("金额:");
		moneyLabel.setBounds(30, 170, 50, 28);
		moneyTxt.setBounds(70, 170, 100, 28);
		moneyTxt.setHorizontalAlignment(JTextField.RIGHT);//文本右对齐
		this.add(moneyLabel);
		this.add(this.moneyTxt);
		//时间
		JLabel createtimeLable=new JLabel("时间:");
		createtimeLable.setBounds(30, 210, 50, 28);
		createtimeTxt.setBounds(70, 210, 80, 28);
		createtimeTxt.setText(String.format("%tF",new Date()));
		dateChooser.getInstance().register(createtimeTxt);
		this.add(createtimeLable);
		this.add(this.createtimeTxt);
		//说明
		JLabel ldescLabel=new JLabel("说明:");
		ldescLabel.setBounds(30, 250, 50, 28);
		ldescTxt.setColumns(20);
		ldescTxt.setRows(5);
		JScrollPane scrollPane=new JScrollPane();
		scrollPane.setBounds(70, 250, 260, 80);
		scrollPane.setViewportView(ldescTxt);
		this.add(ldescLabel);
		this.add(scrollPane);
		//取消按钮
		cancelBtn.setBounds(30,340, 90, 28);
		this.add(cancelBtn);
		//确定按钮
		submitBtn.setBounds(260, 340, 90, 28);
		this.add(submitBtn);
		
	}
	//添加监听器
	private void addListener(){
		//取消按钮
		cancelBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				AbstractOperationLedgerDialog.this.dispose();	
			}	
		});
		//确定按钮
		submitBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				comfirm();
			}	
		});
		//分裂菜单监听器,实现联动
		parentBox.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				changeParent();
			}	
		});
	}
	//点击确定按钮时调用
	public abstract  void comfirm();
	public abstract  void changeParent();
	
}

25.在com.itheima.gip.view;中创建 AbstractOperationSortDialog

package com.itheima.gip.view;


import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import com.itheima.gip.tools.GUITools;
@SuppressWarnings("all")
public abstract class AbstractOperationSortDialog extends JDialog{
	
	
	private static final long serialVersionUID = 1L;
	protected JComboBox parentBox=new JComboBox(new DefaultComboBoxModel(new String[]{"=请选择=","收入","支出"}));
	protected JTextField snameTxt =new JTextField();//分类名称
	protected JTextArea sdescArea=new JTextArea();//调用文本域
	protected JLabel titlelLabel=new JLabel("需要子类设置");
	
	private JButton cancelBtn=new JButton("取消");
	private JButton submitBtn=new JButton("确定");
	
	public AbstractOperationSortDialog(JDialog dialog) {
		super(dialog,true);
		this.initDialog();
		// TODO Auto-generated constructor stub
	}
	public void initDialog(){
		init();
		addComponent();
		addListener();
	}
	//初始化操作
	private void init() {
		this.setResizable(false);
		this.setSize(350, 320);
		this.setLayout(null);
		GUITools.center(this);//居中
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	}
	//添加组件
	private void addComponent(){
		titlelLabel.setFont(new Font("宋体",0,10));
		titlelLabel.setBounds(140, 10, 120, 28);
		this.add(titlelLabel);
		//父分类名称
		JLabel parentLabel=new JLabel("父分类");
		parentLabel.setBounds(30, 50, 60, 28);
		parentBox.setBounds(100, 50, 150, 28);
		this.add(parentLabel);
		this.add(parentBox);
		//分类名称
		JLabel snameLabel=new JLabel("分类名称");
		snameLabel.setBounds(30, 90, 60, 28);
		snameTxt.setBounds(100, 90, 150, 28);
		this.add(snameLabel);
		this.add(snameTxt);
		//分类说明
		JLabel sdescLabel=new JLabel("分类说明");
		sdescLabel.setBounds(30, 130, 60, 28);
		sdescArea.setColumns(20);
		sdescArea.setRows(5);
		JScrollPane scrollPane=new JScrollPane();
		scrollPane.setBounds(100, 130, 200, 80);
		scrollPane.setViewportView(sdescArea);
		this.add(sdescLabel);
		this.add(scrollPane);
		//取消按钮
		cancelBtn.setBounds(80,220, 90, 28);
		this.add(cancelBtn);
		//确定按钮
		submitBtn.setBounds(210, 220, 90, 28);
		this.add(submitBtn);
		
	}
	//添加监听器
	private void addListener(){
		//取消按钮
		cancelBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				AbstractOperationSortDialog.this.dispose();	
			}	
		});
		//确定按钮
		submitBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				comfirm();
			}	
		});
	}
	//点击确定按钮时调用
	public abstract  void comfirm();
}

26.在com.itheima.gip.view;中创建 AbstractShapeDialog

package com.itheima.gip.view;

import java.awt.Image;
import java.io.File;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import com.itheima.gip.tools.GUITools;

public abstract class AbstractShapeDialog extends JDialog{
	
	
	private static final long serialVersionUID = 1L;
	public AbstractShapeDialog(JDialog dialog) {
		super(dialog) ;	
	}
	protected void initDialog(){
		this.addComponent();
		this.init();
	}
	
	private void init(){
		this.pack();
		GUITools.center(this);
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	}
	public abstract List<String> getImagePaths();
	/*
	 * 调用子类重写方法getImagePaths,获取出生成集合的路径
	 * 遍历集合List,获取所有图片路径
	 * 放到组建Lable中
	 */
	private void addComponent() {
		List<String> imagePaths=getImagePaths();
		if(imagePaths==null){
			return;
		}
		JPanel panel=new JPanel();
		this.add(panel);
		for(String imagePath:imagePaths){
			try {
				Image image=ImageIO.read(new File(imagePath));
				panel.add(new JLabel(new ImageIcon(image)));
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		
	}
}

27.在com.itheima.gip.view;中创建 AbstractSortMngDialog

package com.itheima.gip.view;


import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;

import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

import com.itheima.gip.domain.Sort;

import com.itheima.gip.tools.GUITools;
import com.itheima.gip.tools.ListTableModel;
//弹出分类管理对话框
public abstract class AbstractSortMngDialog extends JDialog{
	
	
	private static final long serialVersionUID = 1L;
	//在对话框显示数据表格,protected权限设置为子类使用
	protected  JTable sortDataTable= new JTable();//账户数据列表
	private JButton closeBtn= new JButton("关闭");//关闭按钮
	
	private JButton addBtn= new JButton("添加");
	private JButton editBtn= new JButton("编辑");
	private JButton delBtn= new JButton("删除");
	public AbstractSortMngDialog(JFrame frame ) {
		super(frame,true);//true模态窗口不关闭此窗口,无法操作其他窗口
		this.initDialog();//初始化窗体
	}
	protected void initDialog() {
		this.init();//初始化操作
		this.addComponent();//添加组件
		this.addListener();//添加监听器
		
	}
	//初始化操作
	private void init(){
		this.setTitle("分类管理");//标题
		this.setSize(680,400);//窗体大小
		GUITools.center(this);//居中
		this.setResizable(false);//窗体大小固定
		this.setLayout(null);
		this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		//setDefaultCloseOperation设置用户在此窗体上发起 "close" 时默认执行的操作。
		//EXIT_ON_CLOSE  退出应用程序默认窗口关闭操作。
	}
	//添加组件
	private void addComponent(){
		//设置标签标题
		JLabel titleLable=new JLabel();
		titleLable.setFont(new Font("宋体",Font.ITALIC,18));
		titleLable.setText("分类管理");
		titleLable.setBounds(280,20,165,20);
		this.add(titleLable);
		//滚动面版
		JScrollPane scrollPane =new JScrollPane();
		scrollPane.setBounds(30, 100, 620, 160);
		sortDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//单选
		sortDataTable.getTableHeader().setReorderingAllowed(false);//列不能移动
		//在带有滚动条的容器上设置表格
		scrollPane.setViewportView(sortDataTable);
		this.add(scrollPane);
		//按钮
		addBtn.setBounds(30,290,140,28);
		this.add(addBtn);
		editBtn.setBounds(270,290,140,28);
		this.add(editBtn);
		delBtn.setBounds(510,290,140,28);
		this.add(delBtn);
		//关闭按钮
		closeBtn.setBounds(570,330,80,28);
		this.add(closeBtn);
	}
	//显示分类表格
	protected void setTableModel(List<Sort> sortList){
		String [] colNames=new String[] {"ID","分类名称","父分类","说明"};
		String [] propNames=new String[] {"sid","sname","parent","sdesc"};
		if(sortList==null||sortList.size()==0){
			sortDataTable.setModel(new DefaultTableModel(new Object[][]{
				{null,null,null,null},{null,null,null,null},
				{null,null,null,null},{null,null,null,null},
				{null,null,null,null},{null,null,null,null},
				{null,null,null,null},{null,null,null,null}
			},colNames));
			sortDataTable.setEnabled(false);
			return;
		}
		try {
			sortDataTable.setModel(new ListTableModel<Sort>(sortList,Sort.class,colNames,propNames));
			sortDataTable.setEnabled(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
				
	}
	@SuppressWarnings("all")//压制警告
	//编辑删除分类
	//传递选择的第几行
	//将选择的哪一行,所有数据封装成一个Sort对象
	protected Sort getSortByTableRow(int row ){
		return ((ListTableModel<Sort>)sortDataTable.getModel()).getInstance(row);	
	}
	
	//添加监听器
	private void addListener(){
		//分类关闭按钮
		closeBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				AbstractSortMngDialog.this.dispose();
			}	
		});
		//分类管理添加
		addBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				addSort();	
			}	
		});
		//编辑
		editBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				editSort();	
			}	
		});
		//清除
		delBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// TODO Auto-generated method stub
				delSort();	
			}	
		});
		//鼠标双击
		sortDataTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e){
				if(e.getButton()==1){
					if(e.getClickCount()>=2){
						editSort();
					}
				}
			}
		});
	}
	//展示管理界面方法
	public abstract  void addSort();	
	public abstract  void editSort();
	public abstract  void delSort();	
}

java管家婆项目_第1张图片
java管家婆项目_第2张图片
java管家婆项目_第3张图片

你可能感兴趣的:(Java面向面试编程)