正在学习Java就花了两个星期写了一个1000行左右的代码,仿照大一上学期老师让我们在控制台下写的图书管理系统系统,用Java容器和数据库写一个带图形界面的图书管理系统,一开始以为可以写个两三千行,结果写到1094行就结束了,实训马上开始,所以就不对这份代码进行扩充。
功能介绍:菜单----常用功能 ----个人中心 ----系统维护 ----帮助 一级菜单
----浏览图书 ----我的空间 ----后台管理 ----帮助信息 二级菜单
----查找图书 ----登录 -
----注册 -
-后台->----图书管理 ----账户中心 ----帮助
----增加图书 ----注册新管理员 ----帮助信息
----删除图书 ----删除管理员
----删除用户
——————————————————————————————————————————
开始界面的菜单:
——————————————————————————————————————————
进入后台的菜单:
——————————————————————————————————————————
开始界面:
——————————————————————————————————————————
后台界面:
——————————————————————————————————————————
基本思路是,初始化界面——布局容器——添加容器——监听动作——控制动作
这里只列出部分代码,介绍一下我写Java时遇到的问题和写代码的心得
代码框架:
import javax.swing.*;import java.awt.event.*;import java.sql.*;import java.awt.*;public class menu extends JFrame implements ActionListener {//继承了JFrame //定义各个参数 public menu(/*传递参数*/) { init(); setLocation(250, 70); setVisible(true); setSize(800, 600); setDefaultCloseOperation(EXIT_ON_CLOSE); setResizable(false); } public void init() { //初始化参数 } public void actionPerformed(ActionEvent e) { try {//implements ActionListener后要重写actionPerformed //根据动作执行相应代码 } catch (Exception ee) { ee.printStackTrace();//抛出异常 } } }
主界面:menu.java
import javax.swing.*;import java.awt.event.*;import java.sql.*;import java.awt.*;public class menu extends JFrame implements ActionListener { JMenuBar menubar = new JMenuBar(); JMenu meArray[] = { new JMenu("常用功能"), new JMenu("个人中心"), new JMenu("系统维护"), new JMenu("帮助") }; JMenuItem item[] = { new JMenuItem("浏览图书",new ImageIcon("image/browse.jpg")), new JMenuItem("查找图书",new ImageIcon("image/query.jpg")), new JMenuItem("我的空间",new ImageIcon("image/user.jpg")),new JMenuItem("登录",new ImageIcon("image/login.jpg")), new JMenuItem("注册",new ImageIcon("image/key.jpg")), new JMenuItem("后台管理",new ImageIcon("image/admin.jpg")), new JMenuItem("帮助信息",new ImageIcon("image/help.jpg")) }; gaintb jsp; JScrollPane JSP; JPanel jpl; JLabel bgimg=new JLabel(new ImageIcon("image\\MAIN.jpg"));//开始界面 String namep=null; CardLayout card=new CardLayout(); JPanel cardPanel=new JPanel(); JLabel titback=new JLabel("选择还书名称"); JButton suback=new JButton("还书"); JTextField bid=new JTextField(); String sql=""; connectdt jdbc = new connectdt();//连接数据库类 Connection conn = jdbc.conn; Statement stmt = jdbc.stmt; public menu(String p1) { namep=p1; init(); cardPanel.add(bgimg); add(cardPanel); jsp = new gaintb("books"); JSP = jsp.rjsp(); JSP.setBounds(0, 0, 800, 550); cardPanel.add(JSP,"browse"); if(namep!=null){ zone cp6=new zone(namep); jpl=cp6.gainpl(); suback.setBounds(580, 440, 80, 30); titback.setBounds(400, 440, 100, 30); bid.setBounds(500, 440, 50, 30); jpl.add(suback); jpl.add(titback); jpl.add(bid); suback.addActionListener(this); bid.addActionListener(this); cardPanel.add(jpl,"zone"); card.show(cardPanel,"zone"); if(cp6.gainfine()>0){ JOptionPane.showMessageDialog(null, "请先交纳罚款"); return; } } setLocation(250, 70); setVisible(true); setSize(800, 600); setDefaultCloseOperation(EXIT_ON_CLOSE); setResizable(false); } public void init() { cardPanel.setLayout(card); setTitle("图书管理系统"); meArray[0].add(item[0]); meArray[0].add(item[1]); meArray[1].add(item[2]); meArray[1].add(item[3]); meArray[1].add(item[4]); meArray[2].add(item[5]); meArray[3].add(item[6]); for (int i = 0; i < item.length; i++) { item[i].addActionListener(this); } for (int i = 0; i < meArray.length; i++) { menubar.add(meArray[i]); } setJMenuBar(menubar); } public void actionPerformed(ActionEvent e) { try { if (e.getSource() == item[0]) {//浏览图书 card.show(cardPanel,"browse"); } else if (e.getSource() == item[1]) {//查找图书 new select_borrow(namep); } else if (e.getSource() == item[2]) {//空间 if(namep==null){ JOptionPane.showMessageDialog(null, "您还未登录呢"); return; }else{ card.show(cardPanel,"zone"); } } else if (e.getSource() == item[3]) {//登录 new login("readers","name","code","用户登录"); dispose(); }else if(e.getSource()==item[4]){//注册 new user_regist(); }else if(e.getSource()==item[5]){//后台 new login("admindt","username","password","管理员登录"); dispose(); } else if(e.getSource()==item[6]){//帮助 new menu_help(); }else if(e.getSource()==suback){//还书 String temp=bid.getText(); if(temp.equals("")){ JOptionPane.showMessageDialog(null, "输入不能为空"); return; } sql="select * from borrow where book='"+temp+"'"; ResultSet rs = stmt.executeQuery(sql); if(!rs.next()){ JOptionPane.showMessageDialog(null, "输入不存在"); return; } sql="delete from borrow where book='"+temp+"'"; stmt.executeUpdate(sql); sql="update books set STOCK=STOCK+1 where TITLE='"+temp+"';"; stmt.executeUpdate(sql); sql=""; JOptionPane.showMessageDialog(null, "还书成功"); } } catch (Exception ee) { ee.printStackTrace(); } } }
上面是主菜单的完整的代码着重介绍布局思想和动作监听
在public menu(){ }里面
setLocation(250, 70);//设置位置,250是从屏幕左边开始向右移动250像素,70是从上往下移动70像素setVisible(true);//设置窗口可见setSize(800, 600);//设置窗口大小为800宽600高setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭窗口为关闭所有setResizable(false);//不可调整窗口大小
init();为初始化函数,用来设置布局设置个部件在容器的位置,然后将各个部件添加到容器里。了解布局很重要,布局格式有FlowLayout(流式布局),BorderLayout(边界布局),GridLayout(网格布局),CardLayout(卡片布局)和空布局,我这里用到的是空布局和卡片式布局,空布局的特点是可以将各个部件精确定位,以一定格式排列在容器内,布局方便,容易控制,卡片式布局特点是每一张卡片互不干扰,我利用这个特点设置了“浏览图书”和“我的空间”,当用户点击浏览图书时,显示“browse”这张卡片,当用户点击我的空间时,显示“zone”这张卡片。
重写的actionPerformed函数,里ActionEvent e参数用来响应用户点击了哪一个子菜单,这里为什么说子菜单?因为主菜单无法响应,我第一次写监听的时候就监听了“个人中心”,结果鼠标点击时毫无反应,后来才只监听了子菜单。接下来就是连接数据库获取表格,因为我写的13个java文件里差不多都用到了数据库的连接,为了增加代码的重用率我将数据的连接单独写成了一个类,叫connentdt.java,在使用连接代码前,还需要给工程添加额外的jar包(mysql-connector-java-5.1.38-bin.jar)。
连接数据库类connentdt.java:
import java.sql.*;public class connectdt {//此类为连接数据库的类 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/database"; static final String USER = "username"; static final String PASS = "123456"; String struser = "username", strpass = "password", strtable1 = "admindt", strtable2 = "books",ID="id"; Connection conn = null; Statement stmt = null; public connectdt() { try { Class.forName(JDBC_DRIVER);// 工程要连接额外的jar包 conn = DriverManager.getConnection(DB_URL, USER, PASS); stmt = conn.createStatement(); } catch (Exception ee) { ee.printStackTrace(); } } }
连接数据库后,就开始获取表格,这里我将图书内容放在books表里,那么如何从数据库里获取表格呢?看如下代码,就是从数据库里获取表格的各个信息
<span style="white-space:pre"> </span>String sql = "select * from " + tb1; ResultSet rs = stmt.executeQuery(sql);//执行查询语句,返回值只能用rs.next()判断 ResultSetMetaData rsmd = rs.getMetaData();//结果集的具体信息 int column = rs.getMetaData().getColumnCount();//表格列数 Vector<Object> columnNames = new Vector<Object>(1); while (rs.next()) { for (int i = 0; i < column; i++) {//获取除表头的每一行 coldata.addElement(rs.getString(i + 1)); //System.out.println(coldata.get(i)); //输出获取内容,用来调试 } rowdata.addElement(coldata);//将获取的每一行添加到另一个数组里实现二维数组 coldata = new Vector<Object>(1);//清空原来的数组 } for (int i = 0; i < column; i++) {//获取表头 columnNames.add(rsmd.getColumnName(i + 1)); //System.out.println(columnNames.get(i)); } jtable = new JTable(rowdata, columnNames) {//创建表格 public boolean isCellEditable(int row, int column) { return false;/* 表格不允许被编辑 */} }; JSP = new JScrollPane(jtable); return JSP;
再介绍一个遇到的问题,我这个系统有个查询功能,根据输入信息查询相应图书然后输出,在输出的时候,遇到一点小问题,就是动作重复执行时容器会有“残留”,什么是残留呢?看图吧,第一次我查询编号为1的图书
第二次点击查询编号为1的图书
第三次在模糊查询里查询出版社关键词里有“中国”字样的图书
不仅仅是“残留”,整个输出表的地方像是被糊上一层看不见的“胶”,无法点击选中表格,所以,表格输出是不可考虑使用的,我立刻想到用卡片式布局来解决问题,可是我失败了,因为我无法实现动态增加容器,就是每点击查询按钮一次就为容器添加一张卡片,这个我做不到,所以我就想到了使用JTextArea控件,在每一次输出时通过置空内容,我就解决了这个问题。
其他代码都和框架类似,所以我不再赘述,帮助部分是用JTree做的,重写了鼠标监听,附图两张。