Java大作业——酒店管理系统(六):客户管理【完结】

Java大作业(一)介绍了全部功能点

一、Main类——用于启动整个程序

......代码于Java大作业(二)

二、LoginWindowWindow类——用于登录

......代码于Java大作业(二)

三、FunctionSelectionWindow类——用于选择对应的功能

......代码于Java大作业(二)

四、AccountManagementWindow类——用于管理酒店工作人员账户

......代码于Java大作业(三)

五、RoomManagementWindow类——用于办理预定、入住、退房

......代码于Java大作业(四)

六、DiningManagementWindow类——用于预定餐饮

......代码于Java大作业(五)

  

七、CustomerManagementWindow类——用于管理客户信息
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CustomerManagementWindow extends JFrame {

    private JButton checkInCustomerInfoButton;
    private JButton checkInCustomerDiningInfoButton;
    private JButton nonCheckInCustomerDiningInfoButton;

    //构建客户管理窗口,设置属性、布局,添加按钮及对应监听,
    // 添加键盘监听,确保窗口能接收键盘事件后设为可见。
    public CustomerManagementWindow() {
        super("客户管理");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel panel = new JPanel(new GridLayout(3, 1, 10, 10));
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        checkInCustomerInfoButton = new JButton("1. 查看历史入住客户信息");
        checkInCustomerDiningInfoButton = new JButton("2. 查看历史入住客户订餐信息");
        nonCheckInCustomerDiningInfoButton = new JButton("3. 查看历史未入住客户订餐信息");

        checkInCustomerInfoButton.addActionListener(e -> new CheckInCustomerInfoWindow().setVisible(true));
        checkInCustomerDiningInfoButton.addActionListener(e -> new CheckInCustomerDiningInfoWindow().setVisible(true));
        nonCheckInCustomerDiningInfoButton.addActionListener(e -> new NonCheckInCustomerDiningInfoWindow().setVisible(true));

        panel.add(checkInCustomerInfoButton);
        panel.add(checkInCustomerDiningInfoButton);
        panel.add(nonCheckInCustomerDiningInfoButton);

        setContentPane(panel);
        setVisible(true);

        // 添加键盘事件监听器
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                switch (keyCode) {
                    case KeyEvent.VK_1:
                        checkInCustomerInfoButton.doClick();
                        break;
                    case KeyEvent.VK_2:
                        checkInCustomerDiningInfoButton.doClick();
                        break;
                    case KeyEvent.VK_3:
                        nonCheckInCustomerDiningInfoButton.doClick();
                        break;
                }
            }
        });

        // 确保窗口可以接收键盘事件
        setFocusable(true);
        requestFocusInWindow();
    }

    // 创建展示历史入住客户信息的窗口,含表格、搜索、删除等功能,
    // 可加载、过滤、保存数据,处理相关操作与界面显示。
    private class CheckInCustomerInfoWindow extends JFrame {
        private DefaultTableModel model;
        private JTable table;
        private JTextField searchField;
        private JButton searchButton;
        private JButton backButton;

        public CheckInCustomerInfoWindow() {
            super("历史入住客户信息");
            setSize(1200, 600); // 增加宽度以适应更多列
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            setLocationRelativeTo(null);

            JPanel panel = new JPanel(new BorderLayout());

            JLabel label = new JLabel("历史入住客户信息");
            label.setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(label, BorderLayout.NORTH);

            String[] columnNames = {"序号", "房号", "姓名", "电话号码", "入住日期", "预计离开日期", "状态", "身份证号", "实际住店天数", "消费金额", "操作"};
            model = new DefaultTableModel(columnNames, 0);
            table = new JTable(model);

            // 调整身份证号列的宽度
            TableColumnModel columnModel = table.getColumnModel();
            columnModel.getColumn(7).setPreferredWidth(150); // 设置身份证号列的宽度

            JScrollPane scrollPane = new JScrollPane(table);
            panel.add(scrollPane, BorderLayout.CENTER);

            loadCheckInCustomerData(model);

            // 添加删除按钮
            ButtonColumn buttonColumn = new ButtonColumn(table, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = Integer.parseInt(e.getActionCommand());
                    model.removeRow(row);
                    renumberRows(model);
                    saveCheckInCustomerData(model);
                }
            }, columnNames.length - 1);

            // 添加搜索功能
            JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
            JLabel searchLabel = new JLabel("房号/姓名:");
            searchField = new JTextField(15);
            searchButton = new JButton("搜索");
            backButton = new JButton("返回"); // 添加返回按钮
            backButton.setVisible(false); // 默认隐藏返回按钮
            searchButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    performSearch();
                }
            });

            // 添加回车键监听
            searchField.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        performSearch();
                    }
                }
            });

            // 定义返回按钮的动作
            backButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    resetSearch();
                }
            });

            searchPanel.add(searchLabel);
            searchPanel.add(searchField);
            searchPanel.add(searchButton);
            searchPanel.add(backButton); // 将返回按钮添加到面板
            panel.add(searchPanel, BorderLayout.SOUTH);

            // 添加窗口关闭事件监听器
            addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    resetSearch();
                }
            });

            setContentPane(panel);
        }

        private void performSearch() {
            String searchText = searchField.getText().trim();
            if (!searchText.isEmpty()) {
                filterData(searchText);
                backButton.setVisible(true); // 显示返回按钮
            } else {
                loadCheckInCustomerData(model);
                backButton.setVisible(false); // 隐藏返回按钮
            }
            renumberRows(model);
        }

        private void resetSearch() {
            searchField.setText("");
            loadCheckInCustomerData(model);
            renumberRows(model);
            backButton.setVisible(false); // 隐藏返回按钮
        }

        private void renumberRows(DefaultTableModel model) {
            for (int i = 0; i < model.getRowCount(); i++) {
                model.setValueAt(i + 1, i, 0); // 重新设置序号
            }
        }

        private void loadCheckInCustomerData(DefaultTableModel model) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/CustomerHistory");
            for (String[] row : data) {
                model.addRow(row);
            }
        }

        private void filterData(String searchText) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/CustomerHistory");
            for (String[] row : data) {
                if (row[1].contains(searchText) || row[2].contains(searchText)) {
                    model.addRow(row);
                }
            }
        }

        private void saveCheckInCustomerData(DefaultTableModel model) {
            try (FileWriter writer = new FileWriter("Hotel management system/src/CustomerHistory")) {
                for (int i = 0; i < model.getRowCount(); i++) {
                    StringBuilder line = new StringBuilder();
                    for (int j = 0; j < model.getColumnCount() - 1; j++) { // 不包含最后一列(操作)
                        line.append(model.getValueAt(i, j)).append(",");
                    }
                    line.setLength(line.length() - 1); // 移除最后一个逗号
                    writer.write(line.toString());
                    writer.write("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class CheckInCustomerDiningInfoWindow extends JFrame {
        private DefaultTableModel model;
        private JTable table;
        private JTextField searchField;
        private JButton searchButton;
        private JButton backButton;
        // 构建展示历史入住客户订餐信息窗口,设置属性、布局,添加功能按钮,
        // 关联对应操作,加载数据后设置内容面板展示窗口。
        public CheckInCustomerDiningInfoWindow() {
            super("历史入住客户订餐信息");
            setSize(800, 600);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            setLocationRelativeTo(null);

            JPanel panel = new JPanel(new BorderLayout());

            JLabel label = new JLabel("历史入住客户订餐信息");
            label.setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(label, BorderLayout.NORTH);

            String[] columnNames = {"序号", "订餐日期", "房号", "姓名", "菜品", "菜品金额", "状态", "是否支付", "操作"};
            model = new DefaultTableModel(columnNames, 0);
            table = new JTable(model);

            JScrollPane scrollPane = new JScrollPane(table);
            panel.add(scrollPane, BorderLayout.CENTER);

            loadCheckInCustomerDiningData(model);

            // 添加删除按钮
            ButtonColumn buttonColumn = new ButtonColumn(table, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = Integer.parseInt(e.getActionCommand());
                    model.removeRow(row);
                    renumberRows(model);
                    saveCheckInCustomerDiningData(model);
                }
            }, columnNames.length - 1);

            // 添加搜索功能
            JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
            JLabel searchLabel = new JLabel("房号/姓名/菜名:");
            searchField = new JTextField(15);
            searchButton = new JButton("搜索");
            backButton = new JButton("返回"); // 添加返回按钮
            backButton.setVisible(false); // 默认隐藏返回按钮
            searchButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    performSearch();
                }
            });

            // 添加回车键监听
            searchField.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        performSearch();
                    }
                }
            });

            // 定义返回按钮的动作
            backButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    resetSearch();
                }
            });

            searchPanel.add(searchLabel);
            searchPanel.add(searchField);
            searchPanel.add(searchButton);
            searchPanel.add(backButton); // 将返回按钮添加到面板
            panel.add(searchPanel, BorderLayout.SOUTH);

            // 添加窗口关闭事件监听器
            addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    resetSearch();
                }
            });

            setContentPane(panel);
        }
        // 获取输入搜索文本,非空时依其过滤数据并显示返回按钮,
        // 为空则加载全部数据并隐藏返回按钮,重排行号。
        private void performSearch() {
            String searchText = searchField.getText().trim();
            if (!searchText.isEmpty()) {
                filterData(searchText);
                backButton.setVisible(true); // 显示返回按钮
            } else {
                loadCheckInCustomerDiningData(model);
                backButton.setVisible(false); // 隐藏返回按钮
            }
            renumberRows(model);
        }

        // 清空搜索框内容,重新加载全部订餐数据,隐藏返回按钮,
        // 对表格数据重新编号,用于恢复初始搜索状态。
        private void resetSearch() {
            searchField.setText("");
            loadCheckInCustomerDiningData(model);
            renumberRows(model);
            backButton.setVisible(false); // 隐藏返回按钮
        }

        //遍历表格模型的行,将每行序号列(第 1 列)值更新为当前行索引加 1,以重新编排数据序号。
        private void renumberRows(DefaultTableModel model) {
            for (int i = 0; i < model.getRowCount(); i++) {
                model.setValueAt(i + 1, i, 0); // 重新设置序号
            }
        }

        //先清空表格模型已有数据,再从指定文件读取数据,
        // 将每行数据添加到模型中,用于加载入住客户订餐信息。
        private void loadCheckInCustomerDiningData(DefaultTableModel model) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/Customeryrz");
            for (String[] row : data) {
                model.addRow(row);
            }
        }
        // 清空表格模型数据,按房号、姓名、菜名是否包含搜索文本筛选读取的数据,
        // 符合条件的添加到模型用于搜索展示。

        private void filterData(String searchText) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/Customeryrz");
            for (String[] row : data) {
                if (row[2].contains(searchText) || row[3].contains(searchText) || row[4].contains(searchText)) {
                    model.addRow(row);
                }
            }
        }

        // 将表格模型(除操作列)每行数据按格式拼接成字符串,
        // 写入指定文件,遇异常打印栈信息,用于保存订餐数据。
        private void saveCheckInCustomerDiningData(DefaultTableModel model) {
            try (FileWriter writer = new FileWriter("Hotel management system/src/Customeryrz")) {
                for (int i = 0; i < model.getRowCount(); i++) {
                    StringBuilder line = new StringBuilder();
                    for (int j = 0; j < model.getColumnCount() - 1; j++) { // 不包含最后一列(操作)
                        line.append(model.getValueAt(i, j)).append(",");
                    }
                    line.setLength(line.length() - 1); // 移除最后一个逗号
                    writer.write(line.toString());
                    writer.write("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class NonCheckInCustomerDiningInfoWindow extends JFrame {
        private DefaultTableModel model;
        private JTable table;
        private JTextField searchField;
        private JButton searchButton;
        private JButton backButton;

        // 构建展示历史未入住客户订餐信息窗口,设置属性、布局,添加功能按钮,
        // 关联操作,加载数据后设置面板展示窗口。
        public NonCheckInCustomerDiningInfoWindow() {
            super("历史未入住客户订餐信息");
            setSize(800, 600);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            setLocationRelativeTo(null);

            JPanel panel = new JPanel(new BorderLayout());

            JLabel label = new JLabel("历史未入住客户订餐信息");
            label.setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(label, BorderLayout.NORTH);

            String[] columnNames = {"序号", "订餐日期", "姓名", "菜品", "菜品金额", "状态", "支付方式", "操作"};
            model = new DefaultTableModel(columnNames, 0);
            table = new JTable(model);

            JScrollPane scrollPane = new JScrollPane(table);
            panel.add(scrollPane, BorderLayout.CENTER);

            loadNonCheckInCustomerDiningData(model);

            // 添加删除按钮
            ButtonColumn buttonColumn = new ButtonColumn(table, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = Integer.parseInt(e.getActionCommand());
                    model.removeRow(row);
                    renumberRows(model);
                    saveNonCheckInCustomerDiningData(model);
                }
            }, columnNames.length - 1);

            // 添加搜索功能
            JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
            JLabel searchLabel = new JLabel("姓名/菜名:");
            searchField = new JTextField(15);
            searchButton = new JButton("搜索");
            backButton = new JButton("返回"); // 添加返回按钮
            backButton.setVisible(false); // 默认隐藏返回按钮
            searchButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    performSearch();
                }
            });

            // 添加回车键监听
            searchField.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        performSearch();
                    }
                }
            });

            // 定义返回按钮的动作
            backButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    resetSearch();
                }
            });

            searchPanel.add(searchLabel);
            searchPanel.add(searchField);
            searchPanel.add(searchButton);
            searchPanel.add(backButton); // 将返回按钮添加到面板
            panel.add(searchPanel, BorderLayout.SOUTH);

            // 添加窗口关闭事件监听器
            addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    resetSearch();
                }
            });

            setContentPane(panel);
        }

        // 获取并判断搜索文本,非空则依其过滤数据并显示返回按钮,
        // 为空则加载全部数据并隐藏返回按钮,重排行号。
        private void performSearch() {
            String searchText = searchField.getText().trim();
            if (!searchText.isEmpty()) {
                filterData(searchText);
                backButton.setVisible(true); // 显示返回按钮
            } else {
                loadNonCheckInCustomerDiningData(model);
                backButton.setVisible(false); // 隐藏返回按钮
            }
            renumberRows(model);
        }

        // 清空搜索框,重新加载未入住客户订餐数据,隐藏返回按钮,
        // 对表格数据重新编号,用于恢复初始搜索状态。
        private void resetSearch() {
            searchField.setText("");
            loadNonCheckInCustomerDiningData(model);
            renumberRows(model);
            backButton.setVisible(false); // 隐藏返回按钮
        }

        // 遍历表格每行,将序号列(第 1 列)值更新为当前行索引加 1,
        // 以重新编排未入住客户订餐数据序号。
        private void renumberRows(DefaultTableModel model) {
            for (int i = 0; i < model.getRowCount(); i++) {
                model.setValueAt(i + 1, i, 0); // 重新设置序号
            }
        }

        // 先清空表格已有数据,再从指定文件读取数据,
        // 将每行添加到模型,用于加载未入住客户订餐信息。
        private void loadNonCheckInCustomerDiningData(DefaultTableModel model) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/Customerwrz");
            for (String[] row : data) {
                model.addRow(row);
            }
        }

        // 清空表格数据,按姓名、菜名是否含搜索文本筛选读取的数据,
        // 符合的添加到模型,用于搜索展示相应订餐信息。
        private void filterData(String searchText) {
            model.setRowCount(0); // 清空现有数据
            List<String[]> data = readFromFile("Hotel management system/src/Customerwrz");
            for (String[] row : data) {
                if (row[2].contains(searchText) || row[3].contains(searchText)) {
                    model.addRow(row);
                }
            }
        }

        // 将表格(除操作列)每行数据拼接成字符串,写入对应文件,
        // 遇异常打印栈信息,用于保存未入住客户订餐数据。
        private void saveNonCheckInCustomerDiningData(DefaultTableModel model) {
            try (FileWriter writer = new FileWriter("Hotel management system/src/Customerwrz")) {
                for (int i = 0; i < model.getRowCount(); i++) {
                    StringBuilder line = new StringBuilder();
                    for (int j = 0; j < model.getColumnCount() - 1; j++) { // 不包含最后一列(操作)
                        line.append(model.getValueAt(i, j)).append(",");
                    }
                    line.setLength(line.length() - 1); // 移除最后一个逗号
                    writer.write(line.toString());
                    writer.write("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 此方法从指定文件路径(filePath)读取内容,
    // 按逗号分割每行数据存进String数组列表,遇IOException打印栈信息后返回列表。
    private List<String[]> readFromFile(String filePath) {
        List<String[]> data = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                data.add(line.split(","));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    //
    private class ButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
        private JButton renderButton;
        private JButton editButton;
        private String label;
        private int rowIndex;
        private ActionListener actionListener;

        // 初始化按钮列相关属性,设置单元格渲染与编辑,
        // 为编辑按钮添加点击监听,用于处理表格中按钮相关交互逻辑。
        public ButtonColumn(JTable table, ActionListener actionListener, int column) {
            this.actionListener = actionListener;

            renderButton = new JButton("删除");
            editButton = new JButton("删除");
            editButton.setFocusPainted(false);
            editButton.setBackground(Color.LIGHT_GRAY);

            table.getColumnModel().getColumn(column).setCellRenderer(this);
            table.getColumnModel().getColumn(column).setCellEditor(this);

            editButton.addActionListener(e -> {
                rowIndex = table.convertRowIndexToModel(table.getEditingRow());
                fireEditingStopped();
                int option = JOptionPane.showConfirmDialog(
                    (JFrame) SwingUtilities.getWindowAncestor(table), 
                    "确定要删除此行吗?", 
                    "确认删除", 
                    JOptionPane.YES_NO_OPTION
                );
                if (option == JOptionPane.YES_OPTION) {
                    actionListener.actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, String.valueOf(rowIndex)));
                }
            });
        }

        // 依表格行选择状态设置渲染按钮的前景、背景色,
        // 返回按钮用于在表格中按对应样式渲染展示按钮外观。
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                renderButton.setForeground(table.getSelectionForeground());
                renderButton.setBackground(table.getSelectionBackground());
            } else {
                renderButton.setForeground(table.getForeground());
                renderButton.setBackground(UIManager.getColor("Button.background"));
            }
            return renderButton;
        }
        // 直接返回编辑按钮,
        // 使其能在表格相应单元格进入编辑状态时显示,用于提供可交互操作的编辑按钮。
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            return editButton;
        }

        // 返回label值(此处可能逻辑较简单),
        // 在结束单元格编辑获取编辑后的值时起作用,用于传递编辑结果相关信息。
        @Override
        public Object getCellEditorValue() {
            return label;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值