一、功能界面切换
右边操作一共有5个不同的界面,每一个界面分别置于一个底层容器Jpanel上。置于如何切换不同界面,我没有找到什么好方法,设置一个标记变量,然后左边点击不同导航按钮时候,在响应函数里面更换标记,再重新刷新。
类成员变量设置:
//根据左边按钮选择显示哪一个界面 //1是查询,2是当前借阅,3是历史借阅信息,4是证件信息,5是推荐 private int ShowSelect=1;
刷新函数设置:
public void FreshShow() { // booktypeJcb = new JComboBox(); // booktypeJcb.setFont(new Font("宋体", Font.PLAIN, 35)); //********************选择右边显示的界面*******************************/ switch(ShowSelect) { case 1: splitPane.add(OperationJp, JSplitPane.RIGHT); CredentialInfoJP.setVisible(false); PreBorrowJP.setVisible(false); RecomJP.setVisible(false); HisBorrowJP.setVisible(false); OperationJp.setVisible(true); break; case 2: splitPane.setRightComponent(PreBorrowJP); CredentialInfoJP.setVisible(false); OperationJp.setVisible(false); RecomJP.setVisible(false); HisBorrowJP.setVisible(false); PreBorrowJP.setVisible(true); break; case 3: splitPane.setRightComponent(HisBorrowJP); CredentialInfoJP.setVisible(false); OperationJp.setVisible(false); RecomJP.setVisible(false); PreBorrowJP.setVisible(false); HisBorrowJP.setVisible(true); break; case 4: splitPane.setRightComponent(CredentialInfoJP); OperationJp.setVisible(false); RecomJP.setVisible(false); PreBorrowJP.setVisible(false); HisBorrowJP.setVisible(false); CredentialInfoJP.setVisible(true); break; default:splitPane.setRightComponent(RecomJP); CredentialInfoJP.setVisible(false); PreBorrowJP.setVisible(false); OperationJp.setVisible(false); HisBorrowJP.setVisible(false); RecomJP.setVisible(true); break; } }
类构造函数在按钮响应函数调用,例如:
RecomJB.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ResetValue(); ShowSelect=5; FreshShow(); //刷新界面 } });
这里记住一件事情:所有的界面在构造函数执行以后已经生成好了,只是没有setVisible(true),这里刷新只是根据条件显示不同面板。这也是使用底层容器,做到分类放置不同控件的好处。
二、查询界面实现
所有的界面都差不多,以查询界面为例。
首先放置一个JcomboBox用于在bookType关系表里面将所有的图书类型显示出来,提供条件查询一个变量。然后放置一个Jtxt作为书名输入,作为条件查询主键。再放一个按钮和一张Jtable用于显示查询结果。如前面所说,Jtable位于JscrollPanel内,用于滚动列表:
JButton SearchBookJB = new JButton("\u67E5\u8BE2"); //按钮响应事件,点击后执行查询 SearchBookJB.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { BookSearchActionPerformed(evt); } }); SearchBookJB.setIcon(new ImageIcon(userMainFrm.class.getResource("/manager/image/search.png"))); SearchBookJB.setFont(new Font("宋体", Font.PLAIN, 35)); //JScrollPane用于放置表格 JScrollPane BookSearchJsp = new JScrollPane(); GroupLayout gl_OperationJp = new GroupLayout(OperationJp); //布局 gl_OperationJp.setHorizontalGroup( gl_OperationJp.createParallelGroup(Alignment.LEADING) .addGroup(gl_OperationJp.createSequentialGroup() .addGap(159) .addGroup(gl_OperationJp.createParallelGroup(Alignment.TRAILING, false) .addComponent(BookSearchJsp, Alignment.LEADING) .addGroup(Alignment.LEADING, gl_OperationJp.createSequentialGroup() .addComponent(booktypeJcb, GroupLayout.PREFERRED_SIZE, 269, GroupLayout.PREFERRED_SIZE) .addGap(74) .addComponent(BookNameJL, GroupLayout.PREFERRED_SIZE, 162, GroupLayout.PREFERRED_SIZE) .addPreferredGap(ComponentPlacement.UNRELATED) .addComponent(BookNameTxt, GroupLayout.PREFERRED_SIZE, 1112, GroupLayout.PREFERRED_SIZE) .addGap(89) .addComponent(SearchBookJB, GroupLayout.PREFERRED_SIZE, 208, GroupLayout.PREFERRED_SIZE))) .addContainerGap(945, Short.MAX_VALUE)) ); gl_OperationJp.setVerticalGroup( gl_OperationJp.createParallelGroup(Alignment.LEADING) .addGroup(gl_OperationJp.createSequentialGroup() .addGap(131) .addGroup(gl_OperationJp.createParallelGroup(Alignment.BASELINE) .addComponent(booktypeJcb, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addComponent(BookNameJL, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addComponent(BookNameTxt, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addComponent(SearchBookJB, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE))//修改第四个参数可以改大小 .addGap(111) .addComponent(BookSearchJsp, GroupLayout.PREFERRED_SIZE, 1017, GroupLayout.PREFERRED_SIZE) .addContainerGap(409, Short.MAX_VALUE)) ); //放置表格 BookSearchJT = new JTable(); //表格行选中事件,用于将选中的那一行数据导入,用于后面的借阅功能指明借阅哪本书 BookSearchJT.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { bookSearchJTMousePressed(e); } }); //表格模式设置,也就是最上方有几列,以及各自列名是什么 BookSearchJT.setModel(new DefaultTableModel( new Object[][] { }, new String[] { "图书ID","\u56FE\u4E66\u540D\u79F0", "\u56FE\u4E66\u4F5C\u8005", "\u51FA\u7248\u793E", "\u56FE\u4E66\u63CF\u8FF0", "\u5269\u4F59\u672C\u6570" } ) { boolean[] columnEditables = new boolean[] { false, false, false, false, false }; @Override public boolean isCellEditable(int row, int column) { return columnEditables[column]; } }); BookSearchJT.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //修改表头大小和字体大小,用于适应我的高分辨率屏幕 BookSearchJT.getTableHeader().setPreferredSize(new Dimension((int)(1*enlargement_x),(int)(40*enlargement_y))); BookSearchJT.getTableHeader().setFont(new Font("宋体", Font.PLAIN, (int)(35*enlargement_y))); BookSearchJT.setRowHeight((int)(80*enlargement_y)); BookSearchJT.getColumnModel().getColumn(0).setPreferredWidth(200); BookSearchJT.getColumnModel().getColumn(1).setPreferredWidth(266); BookSearchJT.getColumnModel().getColumn(2).setPreferredWidth(217); BookSearchJT.getColumnModel().getColumn(3).setPreferredWidth(285); BookSearchJT.getColumnModel().getColumn(4).setPreferredWidth(523); BookSearchJT.getColumnModel().getColumn(5).setPreferredWidth(249); //表格里面字体设置 BookSearchJT.setFont(new Font("宋体", Font.PLAIN, 35)); //BookSearchJsp.add(BookSearchJT); BookSearchJsp.setViewportView(BookSearchJT); OperationJp.setLayout(gl_OperationJp);
下面重点来了——导入表格数据
//************************初始化表格数据**************************************/ /** * 初始化表格数据 * @param book */ private void fillTable(Book book) { DefaultTableModel dtm=(DefaultTableModel) BookSearchJT.getModel();//获取模型 dtm.setRowCount(0); // 设置成0行 Connection con=null; try{ con=dbUtil.getCon(); //OperationJp ResultSet rs=bookDao.list(con, book);//根据条件查询,获取所有记录 while(rs.next()){ Vector v=new Vector();//一定按表格所显示的顺序写,填入每一个数据项 v.add(rs.getString("id")); v.add(rs.getString("bookName")); v.add(rs.getString("author")); v.add(rs.getString("publisher")); v.add(rs.getString("bookDesc")); v.add(rs.getString("number")); dtm.addRow(v);//加一行 } }catch(Exception e){ e.printStackTrace(); }finally{ try { dbUtil.closeCon(con); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
导入下拉框的数据。不过要说明一点,下拉框第一个选项设置为“请选择.."用于提示,这个时候ID=-1,也用于之后查询时候判断有没有输入图书类别这一条件。如果发现JcombBox选中的ID=-1,说明没有这个条件:
/** * 初始化图书类别下拉框 */ private void fillBookType(){ Connection con=null; BookType bookType=null; try{ con=dbUtil.getCon();//与数据库建立连接 ResultSet rs=bookTypeDao.list(con, new BookType());//查询bookType表格,列出所有信息 //添加第一项ID=-1 bookType=new BookType(); bookType.setBookTypeName("请选择..."); bookType.setId(-1);//请选择的ID为-1 BookTypeJcb.addItem(bookType);//按顺序添加到下拉框中 while(rs.next()) { bookType=new BookType(); bookType.setId(rs.getInt("id"));//下拉框每一选项的ID,只用于后台标识 bookType.setBookTypeName(rs.getString("bookTypeName"));//下拉框中每一行显示的内容就是图书类别的名字 this.booktypeJcb.addItem(bookType);//添加项 BookTypeJcb.addItem(bookType); } }catch(Exception e){ e.printStackTrace(); }finally{ } }
(附注:
若要清空表格数据:
//清空表格 DefaultTableModel model =(DefaultTableModel) bookTable.getModel(); while(model.getRowCount()>0) { model.removeRow(model.getRowCount()-1);
}
同理,清空下拉框数据:
if(this.bookTypeJCB.getItemCount()>0)//图书类别项大于0,才操作 { this.bookTypeJCB.setSelectedIndex(0);//选中第一项 }
)
图书检索按钮的响应函数:
private void BookSearchActionPerformed(ActionEvent evt) { String bookName=this.BookNameTxt.getText();//从输入框获得图书名称 //String author=this.S_AuthorTxt.getText(); BookType bookType=(BookType) this.booktypeJcb.getSelectedItem();//获得选中了哪一个图书类别。返回object类,强转 int bookTypeId=bookType.getId(); Book book=new Book(bookName,bookTypeId); this.fillTable(book); //刷新表格 }
关于如何检索图书类别表格,如何根据不同条件检索图书,专门放在后面写一个JDBC有关数据库操作总结。
三、其他版面的界面:
基本原理都差不多,不再记录。借阅历史中有两张统计图,之后再说。
关于“证件信息”界面中还有个缴纳费用按钮。为了保证并发操作性,要求只能打开一个缴纳费用窗口。所以我在类中设置一个标记变量,标记是否点击过这个按钮,点击过后设为true。但是如何置会比较麻烦,因为执行到打开缴纳费用窗口时候主函数并不停下了,而是执行完毕,那个窗口是另一个线程。按道理要加一个监听,观察什么时候缴纳费用窗口关闭了再置回。但是我不会,没空仔细研究。只好采用将这个变量传到缴纳窗口这一个Jframe的继承类中,由那边退出响应按钮置回:
/** * 缴纳罚款 * @param pay */ private void payactionPerformed(ActionEvent pay) { // TODO Auto-generated method stub if(IsOpened) { Dialogutil attention=new Dialogutil(null,"Attention!","已经打开该窗口!"); return; } else { if(StringUtil.isEmpty(PresentUser)) { Dialogutil attention=new Dialogutil(null,"Attention!","用户信息获取失败!"); return; } else { this.payfrm=new PayFrm(PresentUser,this); payfrm.setVisible(true); IsOpened=true; } } }
关于PayFrm类,也就是缴纳窗口,在充值成功退出前置回标记变量:
//修改用户余额 user.setBalance(payNum); int num=UserDao.Recharge(con, user); if(pay==1&&num==1) { showMessageFrame SucNote=new showMessageFrame(null,"缴纳费用成功!",showMessageFrame.NORMAL); dispose(); this.userMainFrm.balanceTxt.setText(Float.toString(user.getBalance())); this.userMainFrm.IsOpened=false;//还原标记变量 return; }