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);
    }
}
View Code

  实际效果如下:  

  

  做一些处理,当表格中没有行被选中,那么修改和删除按钮则不可用,只有在有行被选中的情况下,才可用。具体实现代码如下:

// 获取选中的表格中的行
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;
                }
            }
        });
    }
}
View Code

  效果:

  

  修改用户信息,和添加用户一样。从选中的行中获取用户信息,再进行操作,只不过需要把用户名给显示到新窗体的名字的输入框中。

  为修改按钮添加事件监听器,代码如下:

// 修改
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;
                }
            }
        });
    }
}
View Code

  为删除按钮添加事件监听器,代码如下:

// 删除
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的简单的歌曲信息管理系统

Java实验--基于Swing的简单的歌曲信息管理系统

Java实验--基于Swing的简单的歌曲信息管理系统

Java Swing 课程设计 ---- 实验室设备管理系统

关于java Swing 的学生管理信息系统的问题

使用 Java Swing 编写 IpChat, 基于 IP Messenger 协议,支持 IPv6