Java实验--基于Swing的简单的歌曲信息管理系统
Posted meiqing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实验--基于Swing的简单的歌曲信息管理系统相关的知识,希望对你有一定的参考价值。
原创不易,转载请注明出处。
在上一篇Java实验--基于Swing的简单的歌曲信息管理系统(四)中讲解了歌曲管理的页面布局,本篇讲解用户管理布局,大致和上一篇的差不多,不过这里是点击添加、修改按钮是弹出新的窗口进行操作。
布局设计如下:
这次我直接把窗体的布局设置成了边界布局,两个面板,左边的面板用来存放表格,右边的面板用来存放输入框和按钮。表格中的数据来自定义的实现了TableModel接口的内部类,具体代码如下:
/** * 这次使用自定义的TableModel来进行表格数据的填充, 表格的表头信息:id,用户名,密码 * */ private class userTableModel implements TableModel { private List<User> userList = null; // 数据 public userTableModel(List<User> users) { this.userList = users; } /** * JTable 列的数据类型 */ public Class<?> getColumnClass(int arg0) { return String.class; } /** * JTable的列数,3列 */ public int getColumnCount() { return 3; } /** * JTable的列名 */ public String getColumnName(int columnIndex) { if (columnIndex == 0) { return "用户id"; } else if (columnIndex == 1) { return "用户名"; } else if (columnIndex == 2) { return "密码"; } else { return "出错"; } } /** * JTable显示的数据行数 */ public int getRowCount() { return userList.size(); } /** * 获取指定行,指定列的值 */ public Object getValueAt(int rowIndex, int columnIndex) { User user = userList.get(rowIndex); if (columnIndex == 0) { return user.getId(); } else if (columnIndex == 1) { return user.getName(); } else if (columnIndex == 2) { return user.getPassword(); } else { return "出错"; } } /** * 设置单元格是否可编辑 */ public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } public void removeTableModelListener(TableModelListener l) { } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { } public void addTableModelListener(TableModelListener arg0) { } }
添加了一个显示刷新表格列表的方法,如下:
/** * 刷新JTable,并显示数据 * * @param users */ public void refreshTable(List<User> users) { if (users == null || users.size() == 0) { JOptionPane.showInternalMessageDialog(AdminUserManageView.this, "Sorry, 暂无数据", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } else { uModel = new userTableModel(users); // 这里一定要使用table中的setModel方法才可,不能使用table的构造方法,因为table已经在init中实例化了 table.setModel(uModel); System.out.println("refresh" + users); } }
布局完整代码如下:
public class AdminUserManageView extends JInternalFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel panelTabel; // 用来保存Jtable的一个面板 private JTable table; // 表格 private JPanel panelButton; // 按钮面板 private JTextField tfSearch; // 查询输入框 private JButton btnSearch; // 查询按钮 private JButton btnAdd; // 添加按钮 private JButton btnEdit; // 修改按钮 private JButton btnDelete; // 注销按钮 private JButton btnExit; // 退出按钮 private userTableModel uModel; // 自定义的tableModel private List<User> users; // 用来存储user private UserService userService; // UserService public AdminUserManageView() { userService = new UserServiceImpl(); init(); } private void init() { this.setTitle("用户信息管理"); this.setSize(600, 500); this.setIconifiable(true); // 窗体和最小化 this.setClosable(true); // 窗体可被关闭 this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); // this.setLayout(getLayout()); // 获取顶层布局管理器的样式 this.setLayout(new BorderLayout()); panelTabel = new JPanel(new BorderLayout()); // 创建面板 // 给面板设置边框 panelTabel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(null, null), "查询信息")); users = userService.findAll(); table = new JTable(); // 创建表格 refreshTable(users); // 初始化表格,里面的数据都是从数据库中查询出的 // table 需要放在滚动面板中 panelTabel.add(new JScrollPane(table), BorderLayout.CENTER); this.add(panelTabel, BorderLayout.CENTER); panelButton = new JPanel(new GridLayout(8, 1, 10, 30)); panelButton.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "查询条件")); panelButton.add(new JLabel("请输入用户名")); tfSearch = new JTextField(8); panelButton.add(tfSearch); btnSearch = new JButton("查询"); panelButton.add(btnSearch); btnAdd = new JButton("添加"); panelButton.add(btnAdd); btnEdit = new JButton("修改"); btnEdit.setEnabled(false); panelButton.add(btnEdit); btnDelete = new JButton("删除"); btnDelete.setEnabled(false); panelButton.add(btnDelete); btnExit = new JButton("退出"); panelButton.add(btnExit); panelButton.add(new JLabel()); this.add(panelButton, BorderLayout.EAST); this.setVisible(true); } }
实际效果如下:
做一些处理,当表格中没有行被选中,那么修改和删除按钮则不可用,只有在有行被选中的情况下,才可用。具体实现代码如下:
// 获取选中的表格中的行 table.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent event) { if (table.getSelectedRow() != -1) { btnEdit.setEnabled(true); btnDelete.setEnabled(true); } } });
为添加按钮添加事件监听器,当点击添加按钮时,出现一个新窗口。监听器代码如下:
/* * 增加 这里在一个JFrame中,调用另外一个JFrame,涉及到了线程问题。 即,如果不加任何东西,那么程序会在把btnAdd的事件执行完之后,才会 * new AddUserView,所以,我们看到的效果是,添加成功后,关闭了 被调用的那个JFrame,但是,数据根本就没有更新,需要重新查询,才可以 * 看到表格更新了。 * 1. 使用线程,sleep一下,但是效果不好 * 2. 使用notify和wait,但是没有涉及到同步问题,所以,失败 * 3. 使用SwingWork方法,没接触过,结果,失败 * 4. 在AddUser中使用,虽然解决了多线程,但是添加了耦合 * 综合一下,还是使用了方案4,具体版本,可以通过git倒退。 */ btnAdd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { btnEdit.setEnabled(false); btnDelete.setEnabled(false); // 使用线程 new AdminAddUserView(AdminUserManageView.this); } });
在新窗体中的增加按钮的事件监听器中,如果添加成功了话,则显示到用户管理的窗体中,虽然代码有耦合,但是解决了线程问题嘛。新窗体的布局采用绝对定位,其中对几个输入框也进行了新的添加事件监听器,用来检测输入是否争取,完整代码如下:
package shiyan6.view; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import shiyan6.entity.User; import shiyan6.service.UserService; import shiyan6.service.UserServiceImpl; import shiyan6.util.Common; public class AdminAddUserView extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel panelMain; // 主面板 private JLabel labName; // 用户名 private JLabel labPass; // 密码 private JLabel labConfirmpass; // 确认新密码 private JTextField tfName; // 用户名 private JPasswordField pfPass; // 旧密码输入框 private JPasswordField pfConfirmpass; // 确认密码输入 private JButton btnConcel; // 取消按钮 private JButton btnAdd; // 增加按钮 private AdminUserManageView adminUserManageView; private UserService userService; /** * 构造方法,因为考虑到显示效果更好,所以传入了一个AdminUserManageView * @param adminUserManageView */ public AdminAddUserView(AdminUserManageView adminUserManageView) { // 初始化userService userService = new UserServiceImpl(); this.adminUserManageView = adminUserManageView; init(); // 初始化控件 cancel(); // 取消按钮 addUser(); // 添加用户 } /** * 初始化各组件 */ private void init() { this.setTitle("添加用户"); // 设置窗体标题 this.setSize(380, 300); // 设置窗口大小 this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 关闭按钮 this.setLocationRelativeTo(null); // 设置窗体居中显示 // panelMain = new JPanel(new GridLayout(5, 1)); // 5行1列,效果极差 panelMain = new JPanel(null); // 使用绝对布局 labName = new JLabel("名字:"); labName.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labName.setBounds(40, 20, 80, 26); tfName = new JTextField(); tfName.setBounds(150, 20, 80, 26); panelMain.add(labName); panelMain.add(tfName); labPass = new JLabel("密码:"); labPass.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labPass.setBounds(40, 70, 80, 26); pfPass = new JPasswordField(); pfPass.setBounds(150, 70, 80, 26); panelMain.add(labPass); panelMain.add(pfPass); labConfirmpass = new JLabel("再次确认:"); labConfirmpass.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labConfirmpass.setBounds(40, 120, 80, 26); pfConfirmpass = new JPasswordField(); pfConfirmpass.setBounds(150, 120, 80, 26); panelMain.add(labConfirmpass); panelMain.add(pfConfirmpass); btnConcel = new JButton("取消"); btnConcel.setBounds(60, 170, 60, 30); btnAdd = new JButton("添加"); btnAdd.setBounds(170, 170, 60, 30); panelMain.add(btnConcel); panelMain.add(btnAdd); this.getContentPane().add(panelMain); this.setVisible(true); } /** * 取消按钮,将文本框的类容给清空 */ private void cancel() { btnConcel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // 将文本框清空 tfName.setText(""); pfPass.setText(""); pfConfirmpass.setText(""); } }); } /** * 添加用户 */ private void addUser() { tfName.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent e) { // 获取输入框中的值 String name = tfName.getText().trim(); // 查看用户名是否存在 if (userService.checkUser(name)) { JOptionPane.showMessageDialog(panelMain, "该用户已存在", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } } }); btnAdd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // 获取输入框中的值,包括用户名、密码、确认密码 String name = tfName.getText().trim(); String password = new String(pfPass.getPassword()); String compassword = new String(pfConfirmpass.getPassword()); // 如果他们中有空值,则弹出提示框,当然,这里也可以分别写在,每个输入框的focusLost事件中 if (name.equals("") || name == null || password.equals("") || password == null || compassword.equals("") || compassword == null) { JOptionPane.showMessageDialog(panelMain, "填入信息不能有空", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } // 判断两次输入的密码是否一致 if (!password.equals(compassword)) { JOptionPane.showMessageDialog(panelMain, "两次密码不一致", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } // 创建一个user对象,其中的id,是通过Common类下的getUuid方法得到一个8位的字符串,当然,普通用户肯定为1 User user = new User(Common.getUuid(), name, password, 1); System.out.println(user); // 把用户信息给添加到数据库中 if (userService.addUser(user)) { JOptionPane.showMessageDialog(panelMain, "添加成功", "消息提示框", JOptionPane.INFORMATION_MESSAGE); adminUserManageView.refreshTable(userService.findAll()); AdminAddUserView.this.dispose(); } else { JOptionPane.showMessageDialog(panelMain, "添加失败", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } } }); } }
效果:
修改用户信息,和添加用户一样。从选中的行中获取用户信息,再进行操作,只不过需要把用户名给显示到新窗体的名字的输入框中。
为修改按钮添加事件监听器,代码如下:
// 修改 btnEdit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int row = table.getSelectedRow(); String id = table.getValueAt(row, 0).toString().trim(); String name = table.getValueAt(row, 1).toString().trim(); String password = table.getValueAt(row, 2).toString().trim(); User user = new User(id, name, password, 1); new AdminEditUserView(user, AdminUserManageView.this); System.out.println(id); } });
新窗体的代码:
package shiyan6.view; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import shiyan6.entity.User; import shiyan6.service.UserService; import shiyan6.service.UserServiceImpl; /** * 修改用户信息窗体 * */ public class AdminEditUserView extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel panelMain; // 主面板 private JLabel labName; // 用户名 private JLabel labPass; // 密码 private JLabel labConfirmpass; // 确认新密码 private JTextField tfName; // 用户名 private JPasswordField pfPass; // 旧密码输入框 private JPasswordField pfConfirmpass; // 确认密码输入 private JButton btnConcel; // 取消按钮 private JButton btnEdit; // 修改按钮 private AdminUserManageView adminUserManageView; private UserService userService; private User user; /** * 构造器,传入user的目的是为了将用户的名字给显示到输入框中,当然也可以只传入用户的名字。 * adminUserManageView,为了显示效果,同时避免多线程,才传入的,当然增加了代码的耦合。 * @param user * @param adminUserManageView */ public AdminEditUserView(User user, AdminUserManageView adminUserManageView) { userService = new UserServiceImpl(); this.user = user; this.adminUserManageView = adminUserManageView; init(); // 初始化组件 cancel(); // 取消 editUser(); // 修改 } /** * 初始化各组件 */ private void init() { this.setTitle("修改用户"); // 窗体标题 this.setSize(380, 300); // 窗体大小 this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 关闭按钮 this.setLocationRelativeTo(null); // 设置窗体居中显示 // panelMain = new JPanel(new GridLayout(5, 1)); // 5行1列,效果极差 panelMain = new JPanel(null); // 使用绝对布局 labName = new JLabel("名字:"); labName.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labName.setBounds(40, 20, 80, 26); tfName = new JTextField(); tfName.setText(user.getName()); tfName.setBounds(150, 20, 80, 26); panelMain.add(labName); panelMain.add(tfName); labPass = new JLabel("密码:"); labPass.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labPass.setBounds(40, 70, 80, 26); pfPass = new JPasswordField(); pfPass.setBounds(150, 70, 80, 26); panelMain.add(labPass); panelMain.add(pfPass); labConfirmpass = new JLabel("再次确认:"); labConfirmpass.setFont(new Font("宋体", Font.BOLD, 15)); // 设置字体 labConfirmpass.setBounds(40, 120, 80, 26); pfConfirmpass = new JPasswordField(); pfConfirmpass.setBounds(150, 120, 80, 26); panelMain.add(labConfirmpass); panelMain.add(pfConfirmpass); btnConcel = new JButton("取消"); btnConcel.setBounds(60, 170, 60, 30); btnEdit = new JButton("修改"); btnEdit.setBounds(170, 170, 60, 30); panelMain.add(btnConcel); panelMain.add(btnEdit); this.getContentPane().add(panelMain); this.setVisible(true); } /** * 取消按钮,将文本框的类容给清空 */ private void cancel() { btnConcel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { tfName.setText(""); pfPass.setText(""); pfConfirmpass.setText(""); } }); } /** * 修改用户 */ private void editUser() { btnEdit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // 获取输入框中的值,包括用户名、密码和确认密码 String name = tfName.getText().trim(); String password = new String(pfPass.getPassword()); String compassword = new String(pfConfirmpass.getPassword()); // 如果其中有控值,则提示。当然放在输入框的FocusListener中的LostFocus中更好 if (name.equals("") || name == null || password.equals("") || password == null || compassword.equals("") || compassword == null) { JOptionPane.showMessageDialog(panelMain, "填入信息不能有空", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } // 判断两次密码是否一致 if (!password.equals(compassword)) { JOptionPane.showMessageDialog(panelMain, "两次密码不一致", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } // 重新为user赋值 user = new User(user.getId(), name, compassword, 1); System.out.println("修改后:" + user); // 把用户信息给添加到数据库中 if (userService.updateUserInfo(user)) { JOptionPane.showMessageDialog(panelMain, "修改成功", "消息提示框", JOptionPane.INFORMATION_MESSAGE); adminUserManageView.refreshTable(userService.findAll()); AdminEditUserView.this.dispose(); } else { JOptionPane.showMessageDialog(panelMain, "修改失败", "消息提示框", JOptionPane.INFORMATION_MESSAGE); return; } } }); } }
为删除按钮添加事件监听器,代码如下:
// 删除 btnDelete.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int row = table.getSelectedRow(); String id = table.getValueAt(row, 0).toString(); if (userService.deleteUser(id)) { JOptionPane.showInternalMessageDialog(panelTabel, "删除成功"); users = userService.findAll(); refreshTable(users); } else { JOptionPane.showInternalMessageDialog(panelTabel, "删除失败"); } } });
为退出按钮添加事件监听器,其实就是关闭窗口而已,代码如下:
// 退出按钮 btnExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 关闭窗体 AdminUserManageView.this.dispose(); } });
为查找按钮添加事件监听器,代码如下:
// 查找 btnSearch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { btnEdit.setEnabled(false); btnDelete.setEnabled(false); // users = null; String name = tfSearch.getText().trim(); users = userService.findByName(name); // table.removeAll(); System.out.println("查找到的数据" + users); refreshTable(users); } });
用户管理完整代码如下:
package shiyan6.view; import java.awt.BorderLayout; import java.awt.GridLayout; 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.BorderFactory; import javax.swing.JButton; importJava实验--基于Swing的简单的歌曲信息管理系统