首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >《Java 程序设计》课程设计:从实际问题到 AWT 界面程序实现

《Java 程序设计》课程设计:从实际问题到 AWT 界面程序实现

作者头像
啊阿狸不会拉杆
发布2026-01-21 12:53:19
发布2026-01-21 12:53:19
870
举报

一、课程设计的意义与目标

        在《Java 程序设计》课程学习结束后,课程设计是检验我们综合应用 Java 知识解决实际问题能力的重要环节。本次课程设计旨在引导同学们从实际生活生产中发现问题、分析问题,然后运用 Java 语言设计出可靠且高效的解决方案,并在此基础上添加简单直观的用户界面,提升程序的实用性。

        我们将避免使用 JavaFX,而是采用 JDK 自带的 AWT(Abstract Window Toolkit)包来实现可视化界面,这样可以让大家更专注于 Java 基础语法和面向对象编程思想的应用。

二、实际问题分析与选题

        在日常生活和生产中,我们会遇到各种各样可以通过程序解决的问题。本次课程设计我们选择一个非常贴近生活的场景:小型超市商品管理系统

2.1 问题描述

小型超市在日常运营中需要对商品信息进行管理,包括:

  • 商品的基本信息录入(名称、编号、价格、库存等)
  • 商品信息的查询与修改
  • 商品库存的增减记录
  • 简单的销售统计

        手动管理这些信息不仅效率低下,还容易出错。因此,我们需要设计一个程序来自动化管理这些工作。

2.2 系统功能需求

基于上述问题,我们的系统需要实现以下功能:

  1. 商品信息的添加
  2. 商品信息的查询(按编号或名称)
  3. 商品信息的修改
  4. 商品库存的更新
  5. 简单的数据统计与展示
  6. 数据的本地保存与读取

三、系统设计

3.1 系统整体架构
3.2 系统流程图
3.3 类图设计(PlantUML)
代码语言:javascript
复制
@startuml
class Product {
  -id: String
  -name: String
  -price: double
  -stock: int
  -category: String
  -productionDate: String
  +Product(id: String, name: String, price: double, stock: int, category: String, productionDate: String)
  +getId(): String
  +setId(id: String): void
  +getName(): String
  +setName(name: String): void
  +getPrice(): double
  +setPrice(price: double): void
  +getStock(): int
  +setStock(stock: int): void
  +getCategory(): String
  +setCategory(category: String): void
  +getProductionDate(): String
  +setProductionDate(date: String): void
  +toString(): String
}

class ProductManager {
  -products: List<Product>
  -dataFile: String
  +ProductManager()
  +addProduct(product: Product): boolean
  +findProductById(id: String): Product
  +findProductsByName(name: String): List<Product>
  +updateProduct(id: String, newProduct: Product): boolean
  +deleteProduct(id: String): boolean
  +getAllProducts(): List<Product>
  +getProductCountByCategory(): Map<String, Integer>
  +saveData(): boolean
  +loadData(): boolean
}

class MainFrame {
  -manager: ProductManager
  +MainFrame(manager: ProductManager)
  +initUI(): void
  +showAddProductFrame(): void
  +showQueryFrame(): void
  +showStatFrame(): void
}

class AddProductFrame {
  -manager: ProductManager
  -parentFrame: MainFrame
  +AddProductFrame(manager: ProductManager, parent: MainFrame)
  +initUI(): void
  +saveProduct(): void
}

class QueryFrame {
  -manager: ProductManager
  -parentFrame: MainFrame
  +QueryFrame(manager: ProductManager, parent: MainFrame)
  +initUI(): void
  +searchProduct(): void
  +updateProduct(): void
  +deleteProduct(): void
}

class StatFrame {
  -manager: ProductManager
  +StatFrame(manager: ProductManager)
  +initUI(): void
  +showStatistics(): void
}

ProductManager "1" -- "*" Product : manages
MainFrame "1" -- "1" ProductManager : uses
MainFrame "1" -- "1" AddProductFrame : creates
MainFrame "1" -- "1" QueryFrame : creates
MainFrame "1" -- "1" StatFrame : creates
AddProductFrame "1" -- "1" ProductManager : uses
QueryFrame "1" -- "1" ProductManager : uses
StatFrame "1" -- "1" ProductManager : uses
@enduml

四、系统实现

        下面我们将逐步实现这个超市商品管理系统。我们会使用 Java 的 AWT 库来构建用户界面,使用对象流来实现数据的本地存储。

4.1 商品类(Product.java)

首先实现商品的数据模型类,用于存储商品信息。

代码语言:javascript
复制
import java.io.Serializable;

public class Product implements Serializable {
    private String id;
    private String name;
    private double price;
    private int stock;
    private String category;
    private String productionDate;

    public Product(String id, String name, double price, int stock, String category, String productionDate) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.stock = stock;
        this.category = category;
        this.productionDate = productionDate;
    }

    // Getter & Setter
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
    public int getStock() { return stock; }
    public void setStock(int stock) { this.stock = stock; }
    public String getCategory() { return category; }
    public void setCategory(String category) { this.category = category; }
    public String getProductionDate() { return productionDate; }
    public void setProductionDate(String productionDate) { this.productionDate = productionDate; }

    @Override
    public String toString() {
        return "商品编号: " + id + "\n" +
                "商品名称: " + name + "\n" +
                "商品价格: " + price + "元\n" +
                "库存数量: " + stock + "\n" +
                "商品类别: " + category + "\n" +
                "生产日期: " + productionDate;
    }
}
4.2 商品管理类(ProductManager.java)

接下来实现商品管理类,负责商品的增删改查和数据持久化。

代码语言:javascript
复制
import java.io.*;
import java.util.*;

public class ProductManager {
    private List<Product> products;
    private String dataFile = "products.dat";

    public ProductManager() {
        products = new ArrayList<>();
        loadData();
    }

    public boolean addProduct(Product product) {
        for (Product p : products) {
            if (p.getId().equals(product.getId())) {
                return false;
            }
        }
        products.add(product);
        saveData();
        return true;
    }

    public Product findProductById(String id) {
        for (Product product : products) {
            if (product.getId().equals(id)) {
                return product;
            }
        }
        return null;
    }

    public List<Product> findProductsByName(String name) {
        List<Product> result = new ArrayList<>();
        for (Product product : products) {
            if (product.getName().contains(name)) {
                result.add(product);
            }
        }
        return result;
    }

    public boolean updateProduct(String id, Product newProduct) {
        Product oldProduct = findProductById(id);
        if (oldProduct != null) {
            if (!id.equals(newProduct.getId()) && findProductById(newProduct.getId()) != null) {
                return false;
            }
            int index = products.indexOf(oldProduct);
            products.set(index, newProduct);
            saveData();
            return true;
        }
        return false;
    }

    public boolean deleteProduct(String id) {
        Product product = findProductById(id);
        if (product != null) {
            products.remove(product);
            saveData();
            return true;
        }
        return false;
    }

    public List<Product> getAllProducts() {
        return new ArrayList<>(products);
    }

    public Map<String, Integer> getProductCountByCategory() {
        Map<String, Integer> countMap = new HashMap<>();
        for (Product product : products) {
            String category = product.getCategory();
            countMap.put(category, countMap.getOrDefault(category, 0) + 1);
        }
        return countMap;
    }

    private boolean saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dataFile))) {
            oos.writeObject(products);
            return true;
        } catch (IOException e) {
            System.out.println("保存数据失败: " + e.getMessage());
            return false;
        }
    }

    @SuppressWarnings("unchecked")
    private boolean loadData() {
        File file = new File(dataFile);
        if (!file.exists()) {
            return false;
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dataFile))) {
            products = (List<Product>) ois.readObject();
            return true;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("加载数据失败: " + e.getMessage());
            return false;
        }
    }
}
4.3 主界面(MainFrame.java)

实现系统的主界面,提供功能入口。

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 系统主界面
 */
public class MainFrame extends JFrame {
    // 商品管理器引用
    private ProductManager manager;

    /**
     * 构造方法
     * @param manager 商品管理器对象
     */
    public MainFrame(ProductManager manager) {
        super("超市商品管理系统");
        this.manager = manager;
        initUI(); // 初始化界面

        setSize(500, 400); // 设置窗口大小
        setLocationRelativeTo(null); // 窗口居中显示
        setDefaultCloseOperation(EXIT_ON_CLOSE); // 关闭时退出程序
        setVisible(true); // 显示窗口
    }

    /**
     * 初始化用户界面
     */
    private void initUI() {
        // 设置全局字体
        setFont(new Font("SimSun", Font.PLAIN, 16));

        // 创建主面板并设置布局
        JPanel mainPanel = new JPanel(new GridLayout(2, 2, 20, 20));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
        setContentPane(mainPanel);

        // 创建按钮
        JButton addBtn = new JButton("添加商品");
        JButton queryBtn = new JButton("查询/修改商品");
        JButton statBtn = new JButton("商品统计");
        JButton exitBtn = new JButton("退出系统");

        // 设置按钮字体
        Font btnFont = new Font("SimSun", Font.PLAIN, 16);
        addBtn.setFont(btnFont);
        queryBtn.setFont(btnFont);
        statBtn.setFont(btnFont);
        exitBtn.setFont(btnFont);

        // 设置按钮大小
        Dimension btnSize = new Dimension(120, 50);
        addBtn.setPreferredSize(btnSize);
        queryBtn.setPreferredSize(btnSize);
        statBtn.setPreferredSize(btnSize);
        exitBtn.setPreferredSize(btnSize);

        // 添加按钮到面板
        mainPanel.add(addBtn);
        mainPanel.add(queryBtn);
        mainPanel.add(statBtn);
        mainPanel.add(exitBtn);

        // 为按钮添加点击事件
        addBtn.addActionListener(e -> new AddProductFrame(this, manager));
        queryBtn.addActionListener(e -> new QueryFrame(this, manager));
        statBtn.addActionListener(e -> new StatFrame(this, manager));
        exitBtn.addActionListener(e -> System.exit(0));
    }

    /**
     * 主方法,程序入口
     */
    public static void main(String[] args) {
        // 在事件调度线程中创建UI组件(Swing最佳实践)
        SwingUtilities.invokeLater(() -> {
            // 创建商品管理器
            ProductManager manager = new ProductManager();
            // 创建并显示主窗口
            new MainFrame(manager);
        });
    }
}
4.4 添加商品界面(AddProductFrame.java)

实现添加商品的界面和功能。

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AddProductFrame extends JDialog {
    private ProductManager manager;
    private JFrame parentFrame;

    private JTextField idField, nameField, priceField, stockField, categoryField, dateField;

    public AddProductFrame(JFrame parent, ProductManager manager) {
        super(parent, "添加商品", true);
        this.manager = manager;
        this.parentFrame = parent;
        initUI();
        pack();
        setLocationRelativeTo(parent);
    }

    private void initUI() {
        FontUtils.setGlobalSwingFont();
        FontUtils.setChineseFont(this);

        JPanel contentPane = new JPanel(new GridBagLayout());
        contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        setContentPane(contentPane);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = GridBagConstraints.WEST;

        // 商品编号
        gbc.gridx = 0;
        gbc.gridy = 0;
        contentPane.add(new JLabel("商品编号:"), gbc);
        gbc.gridx = 1;
        idField = new JTextField(20);
        contentPane.add(idField, gbc);

        // 商品名称
        gbc.gridx = 0;
        gbc.gridy = 1;
        contentPane.add(new JLabel("商品名称:"), gbc);
        gbc.gridx = 1;
        nameField = new JTextField(20);
        contentPane.add(nameField, gbc);

        // 商品价格
        gbc.gridx = 0;
        gbc.gridy = 2;
        contentPane.add(new JLabel("商品价格(元):"), gbc);
        gbc.gridx = 1;
        priceField = new JTextField(20);
        contentPane.add(priceField, gbc);

        // 库存数量
        gbc.gridx = 0;
        gbc.gridy = 3;
        contentPane.add(new JLabel("库存数量:"), gbc);
        gbc.gridx = 1;
        stockField = new JTextField(20);
        contentPane.add(stockField, gbc);

        // 商品类别
        gbc.gridx = 0;
        gbc.gridy = 4;
        contentPane.add(new JLabel("商品类别:"), gbc);
        gbc.gridx = 1;
        categoryField = new JTextField(20);
        contentPane.add(categoryField, gbc);

        // 生产日期
        gbc.gridx = 0;
        gbc.gridy = 5;
        contentPane.add(new JLabel("生产日期(yyyy-mm-dd):"), gbc);
        gbc.gridx = 1;
        dateField = new JTextField(20);
        contentPane.add(dateField, gbc);

        // 按钮面板
        JPanel btnPanel = new JPanel();
        JButton saveBtn = new JButton("保存");
        JButton cancelBtn = new JButton("取消");
        btnPanel.add(saveBtn);
        btnPanel.add(cancelBtn);

        gbc.gridx = 0;
        gbc.gridy = 6;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.CENTER;
        contentPane.add(btnPanel, gbc);

        // 事件绑定
        saveBtn.addActionListener(e -> saveProduct());
        cancelBtn.addActionListener(e -> dispose());
    }

    private void saveProduct() {
        try {
            String id = idField.getText().trim();
            String name = nameField.getText().trim();
            double price = Double.parseDouble(priceField.getText().trim());
            int stock = Integer.parseInt(stockField.getText().trim());
            String category = categoryField.getText().trim();
            String date = dateField.getText().trim();

            if (id.isEmpty() || name.isEmpty() || category.isEmpty() || date.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请填写所有必填字段!", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            if (price < 0 || stock < 0) {
                JOptionPane.showMessageDialog(this, "价格和库存不能为负数!", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Product product = new Product(id, name, price, stock, category, date);
            if (manager.addProduct(product)) {
                JOptionPane.showMessageDialog(this, "商品添加成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                clearFields();
            } else {
                JOptionPane.showMessageDialog(this, "商品编号已存在,添加失败!", "提示", JOptionPane.ERROR_MESSAGE);
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "价格和库存必须是数字!", "提示", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void clearFields() {
        idField.setText("");
        nameField.setText("");
        priceField.setText("");
        stockField.setText("");
        categoryField.setText("");
        dateField.setText("");
    }
}
4.5 查询与修改界面(QueryFrame.java)

实现商品查询、修改和删除功能的界面。

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

public class QueryFrame extends JDialog {
    private ProductManager manager;
    private JFrame parentFrame;
    private Product currentProduct;

    private JTextField searchField;
    private JTextArea resultArea;
    private JTextField idField, nameField, priceField, stockField, categoryField, dateField;

    public QueryFrame(JFrame parent, ProductManager manager) {
        super(parent, "查询/修改商品", true);
        this.manager = manager;
        this.parentFrame = parent;
        initUI();
        pack();
        setLocationRelativeTo(parent);
    }

    private void initUI() {
        FontUtils.setGlobalSwingFont();
        FontUtils.setChineseFont(this);

        JPanel contentPane = new JPanel(new BorderLayout(10, 10));
        contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        setContentPane(contentPane);

        // 查询区域
        JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        searchPanel.add(new JLabel("输入商品编号或名称:"));
        searchField = new JTextField(20);
        searchPanel.add(searchField);
        JButton searchBtn = new JButton("查询");
        searchBtn.addActionListener(e -> searchProduct());
        searchPanel.add(searchBtn);
        contentPane.add(searchPanel, BorderLayout.NORTH);

        // 结果显示区域
        resultArea = new JTextArea(8, 40);
        resultArea.setEditable(false);
        resultArea.setLineWrap(true);
        resultArea.setWrapStyleWord(true);
        contentPane.add(new JScrollPane(resultArea), BorderLayout.CENTER);

        // 编辑区域
        JPanel editPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = GridBagConstraints.WEST;

        // 商品编号
        gbc.gridx = 0;
        gbc.gridy = 0;
        editPanel.add(new JLabel("商品编号:"), gbc);
        gbc.gridx = 1;
        idField = new JTextField(15);
        editPanel.add(idField, gbc);

        // 商品名称
        gbc.gridx = 2;
        gbc.gridy = 0;
        editPanel.add(new JLabel("商品名称:"), gbc);
        gbc.gridx = 3;
        nameField = new JTextField(15);
        editPanel.add(nameField, gbc);

        // 商品价格
        gbc.gridx = 0;
        gbc.gridy = 1;
        editPanel.add(new JLabel("商品价格(元):"), gbc);
        gbc.gridx = 1;
        priceField = new JTextField(15);
        editPanel.add(priceField, gbc);

        // 库存数量
        gbc.gridx = 2;
        gbc.gridy = 1;
        editPanel.add(new JLabel("库存数量:"), gbc);
        gbc.gridx = 3;
        stockField = new JTextField(15);
        editPanel.add(stockField, gbc);

        // 商品类别
        gbc.gridx = 0;
        gbc.gridy = 2;
        editPanel.add(new JLabel("商品类别:"), gbc);
        gbc.gridx = 1;
        categoryField = new JTextField(15);
        editPanel.add(categoryField, gbc);

        // 生产日期
        gbc.gridx = 2;
        gbc.gridy = 2;
        editPanel.add(new JLabel("生产日期:"), gbc);
        gbc.gridx = 3;
        dateField = new JTextField(15);
        editPanel.add(dateField, gbc);

        // 按钮面板
        JPanel btnPanel = new JPanel();
        JButton updateBtn = new JButton("更新");
        JButton deleteBtn = new JButton("删除");
        JButton clearBtn = new JButton("清空");
        btnPanel.add(updateBtn);
        btnPanel.add(deleteBtn);
        btnPanel.add(clearBtn);

        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 4;
        gbc.fill = GridBagConstraints.CENTER;
        editPanel.add(btnPanel, gbc);

        contentPane.add(editPanel, BorderLayout.SOUTH);

        // 初始禁用编辑
        disableEditFields();

        // 事件绑定
        updateBtn.addActionListener(e -> updateProduct());
        deleteBtn.addActionListener(e -> deleteProduct());
        clearBtn.addActionListener(e -> clearFields());
    }

    private void searchProduct() {
        String keyword = searchField.getText().trim();
        if (keyword.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入查询关键词!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        Product product = manager.findProductById(keyword);
        if (product != null) {
            resultArea.setText(product.toString());
            currentProduct = product;
            fillEditFields(product);
            enableEditFields();
            return;
        }

        List<Product> products = manager.findProductsByName(keyword);
        if (products.isEmpty()) {
            resultArea.setText("未找到匹配的商品!");
            currentProduct = null;
            clearFields();
            disableEditFields();
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("找到 ").append(products.size()).append(" 个匹配的商品:\n\n");
            for (Product p : products) {
                sb.append(p.toString()).append("\n\n");
            }
            resultArea.setText(sb.toString());
            currentProduct = null;
            clearFields();
            disableEditFields();
        }
    }

    private void updateProduct() {
        if (currentProduct == null) {
            JOptionPane.showMessageDialog(this, "请先查询并选择一个商品!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        try {
            String newId = idField.getText().trim();
            String newName = nameField.getText().trim();
            double newPrice = Double.parseDouble(priceField.getText().trim());
            int newStock = Integer.parseInt(stockField.getText().trim());
            String newCategory = categoryField.getText().trim();
            String newDate = dateField.getText().trim();

            if (newId.isEmpty() || newName.isEmpty() || newCategory.isEmpty() || newDate.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请填写所有必填字段!", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            if (newPrice < 0 || newStock < 0) {
                JOptionPane.showMessageDialog(this, "价格和库存不能为负数!", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Product updatedProduct = new Product(newId, newName, newPrice, newStock, newCategory, newDate);
            if (manager.updateProduct(currentProduct.getId(), updatedProduct)) {
                JOptionPane.showMessageDialog(this, "商品更新成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                currentProduct = updatedProduct;
                resultArea.setText(currentProduct.toString());
            } else {
                JOptionPane.showMessageDialog(this, "商品更新失败,新编号可能已存在!", "提示", JOptionPane.ERROR_MESSAGE);
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "价格和库存必须是数字!", "提示", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void deleteProduct() {
        if (currentProduct == null) {
            JOptionPane.showMessageDialog(this, "请先查询并选择一个商品!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        int confirm = JOptionPane.showConfirmDialog(this, "确定要删除该商品吗?", "确认删除", JOptionPane.YES_NO_OPTION);
        if (confirm == JOptionPane.YES_OPTION) {
            if (manager.deleteProduct(currentProduct.getId())) {
                JOptionPane.showMessageDialog(this, "商品删除成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                resultArea.setText("");
                currentProduct = null;
                clearFields();
                disableEditFields();
            } else {
                JOptionPane.showMessageDialog(this, "商品删除失败!", "提示", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void fillEditFields(Product product) {
        idField.setText(product.getId());
        nameField.setText(product.getName());
        priceField.setText(String.valueOf(product.getPrice()));
        stockField.setText(String.valueOf(product.getStock()));
        categoryField.setText(product.getCategory());
        dateField.setText(product.getProductionDate());
    }

    private void clearFields() {
        idField.setText("");
        nameField.setText("");
        priceField.setText("");
        stockField.setText("");
        categoryField.setText("");
        dateField.setText("");
    }

    private void enableEditFields() {
        idField.setEnabled(true);
        nameField.setEnabled(true);
        priceField.setEnabled(true);
        stockField.setEnabled(true);
        categoryField.setEnabled(true);
        dateField.setEnabled(true);
    }

    private void disableEditFields() {
        idField.setEnabled(false);
        nameField.setEnabled(false);
        priceField.setEnabled(false);
        stockField.setEnabled(false);
        categoryField.setEnabled(false);
        dateField.setEnabled(false);
    }
}
4.6 统计界面(StatFrame.java)

实现商品统计功能的界面。

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Map;

/**
 * 商品统计界面,基于Swing
 */
public class StatFrame extends JDialog {
    // 商品管理器引用
    private ProductManager manager;

    // 统计结果显示区域
    private JTextArea statArea;

    /**
     * 构造方法
     * @param parent 父窗口
     * @param manager 商品管理器
     */
    public StatFrame(JFrame parent, ProductManager manager) {
        super(parent, "商品统计", true); // 模态对话框
        this.manager = manager;
        initUI(); // 初始化界面
        showStatistics(); // 显示统计信息

        setSize(600, 500); // 设置窗口大小
        setLocationRelativeTo(parent); // 相对于父窗口居中
        setDefaultCloseOperation(DISPOSE_ON_CLOSE); // 关闭时释放资源
    }

    /**
     * 初始化用户界面
     */
    private void initUI() {
        // 获取内容面板面板并设置边框
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        setContentPane(contentPane);

        // 添加标题
        JLabel titleLabel = new JLabel("商品统计信息", SwingConstants.CENTER);
        titleLabel.setFont(new Font("SimSun", Font.BOLD, 16));
        contentPane.add(titleLabel, BorderLayout.NORTH);

        // 统计结果结果显示区域
        statArea = new JTextArea();
        statArea.setEditable(false); // 设置为不可编辑
        statArea.setLineWrap(true); // 自动换行
        statArea.setWrapStyleWord(true); // 按单词换行
        statArea.setFont(new Font("SimSun", Font.PLAIN, 14));
        contentPane.add(new JScrollPane(statArea), BorderLayout.CENTER);

        // 底部按钮
        JPanel btnPanel = new JPanel();
        JButton refreshBtn = new JButton("刷新统计");
        refreshBtn.setFont(new Font("SimSun", Font.PLAIN, 14));
        refreshBtn.addActionListener(e -> showStatistics());
        btnPanel.add(refreshBtn);
        contentPane.add(btnPanel, BorderLayout.SOUTH);
    }

    /**
     * 显示统计信息
     */
    private void showStatistics() {
        List<Product> products = manager.getAllProducts();
        int totalCount = products.size();

        // 计算总库存和总价值
        int totalStock = 0;
        double totalValue = 0.0;

        for (Product product : products) {
            totalStock += product.getStock();
            totalValue += product.getPrice() * product.getStock();
        }

        // 按类别统计
        Map<String, Integer> categoryCount = manager.getProductCountByCategory();

        // 构建统计信息字符串
        StringBuilder sb = new StringBuilder();
        sb.append("===== 商品总体统计 =====\n");
        sb.append("商品总数: ").append(totalCount).append(" 种\n");
        sb.append("库存总量: ").append(totalStock).append(" 件\n");
        sb.append("库存总价值: ").append(String.format("%.2f", totalValue)).append(" 元\n\n");

        sb.append("===== 商品类别统计 =====\n");
        if (categoryCount.isEmpty()) {
            sb.append("暂无商品数据\n");
        } else {
            for (Map.Entry<String, Integer> entry : categoryCount.entrySet()) {
                sb.append(entry.getKey()).append(": ").append(entry.getValue()).append(" 种\n");
            }
        }

        // 显示库存最多的商品
        sb.append("\n===== 库存最多的商品 =====\n");
        if (products.isEmpty()) {
            sb.append("暂无商品数据\n");
        } else {
            Product maxStockProduct = products.get(0);
            for (Product product : products) {
                if (product.getStock() > maxStockProduct.getStock()) {
                    maxStockProduct = product;
                }
            }
            sb.append("商品名称: ").append(maxStockProduct.getName()).append("\n");
            sb.append("库存数量: ").append(maxStockProduct.getStock()).append("\n");
        }

        // 显示到界面
        statArea.setText(sb.toString());
    }
}
4.7FontUtils.java(字体工具类,统一设置字体)
代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;

public class FontUtils {
    // 定义全局中文字体(宋体)
    public static final Font CHINESE_FONT = new Font("SimSun", Font.PLAIN, 14);

    // 递归为所有组件设置字体(适配复杂布局)
    public static void setChineseFont(Component... components) {
        for (Component comp : components) {
            setFontRecursive(comp);
        }
    }

    private static void setFontRecursive(Component comp) {
        comp.setFont(CHINESE_FONT);
        if (comp instanceof Container) {
            for (Component child : ((Container) comp).getComponents()) {
                setFontRecursive(child);
            }
        }
    }

    // 为 Swing 全局组件设置默认字体(可选增强)
    public static void setGlobalSwingFont() {
        UIManager.put("Button.font", CHINESE_FONT);
        UIManager.put("Label.font", CHINESE_FONT);
        UIManager.put("TextField.font", CHINESE_FONT);
        UIManager.put("TextArea.font", CHINESE_FONT);
        UIManager.put("Dialog.font", CHINESE_FONT);
    }
}

五、系统测试与运行说明

5.1 编译与运行步骤
  1. 将上述 6 个 Java 文件保存到同一个目录下
  2. 打开命令提示符(Windows)或终端(Linux/Mac),进入该目录
  3. 执行编译命令:javac *.java
  4. 运行程序:java MainFrame
5.2 系统功能测试
  1. 添加商品
    • 点击 "添加商品" 按钮
    • 填写商品信息(注意价格和库存需为数字)
    • 点击 "保存" 按钮
  2. 查询 / 修改商品
    • 点击 "查询 / 修改商品" 按钮
    • 输入商品编号或名称,点击 "查询"
    • 找到商品后,可以修改信息并点击 "更新",或点击 "删除" 移除商品
  3. 商品统计
    • 点击 "商品统计" 按钮
    • 查看各类统计信息
    • 数据更新后可点击 "刷新统计" 按钮更新数据
  4. 数据持久化
    • 所有操作都会自动保存到本地文件(products.dat)
    • 下次启动程序时会自动加载已保存的数据

六、总结与展望

        本课程设计实现了一个基于 AWT 的超市商品管理系统,该系统能够满足小型超市对商品信息进行管理的基本需求。通过这个项目,我们学习了:

  1. 如何从实际问题出发,分析需求并设计解决方案
  2. Java 面向对象编程的应用(封装、继承等)
  3. 使用 AWT 构建简单的用户界面
  4. 数据的持久化存储(对象序列化)
  5. 基本的事件处理机制

系统还有进一步改进的空间:

  1. 可以添加用户登录功能,区分管理员和普通员工权限
  2. 增加销售记录和报表生成功能
  3. 优化界面布局,提升用户体验
  4. 增加数据导入导出功能(如 Excel 格式)
  5. 考虑使用数据库替代文件存储,提高数据处理效率

        通过这个课程设计,我们不仅巩固了 Java 基础知识,更重要的是学会了如何运用编程技术解决实际问题,这将为我们今后的学习和工作打下坚实基础。

        希望本案例能为大家提供一些启发,祝大家课程设计顺利完成!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、课程设计的意义与目标
  • 二、实际问题分析与选题
    • 2.1 问题描述
    • 2.2 系统功能需求
  • 三、系统设计
    • 3.1 系统整体架构
    • 3.2 系统流程图
    • 3.3 类图设计(PlantUML)
  • 四、系统实现
    • 4.1 商品类(Product.java)
    • 4.2 商品管理类(ProductManager.java)
    • 4.3 主界面(MainFrame.java)
    • 4.4 添加商品界面(AddProductFrame.java)
    • 4.5 查询与修改界面(QueryFrame.java)
    • 4.6 统计界面(StatFrame.java)
    • 4.7FontUtils.java(字体工具类,统一设置字体)
  • 五、系统测试与运行说明
    • 5.1 编译与运行步骤
    • 5.2 系统功能测试
  • 六、总结与展望
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档