【任务描述】

在水果超市中,有着各种各样的水果,为了便于管理,会将水果信息记录在水果超市管理系统中进行统一管理,通过系统可以方便地实现对水果信息的增删改查操作。其中,水果信息包括水果编号、水果名称、水果单价和计价单位等。本任务要求使用所学 GUI 知识,编写一个水果超市管理系统。

水果超市管理系统共包括系统欢迎界面和超市货物管理界面两个界面,在系统欢迎界面通过单击“进入系统”按钮,加入超市货物管理界面,在货物管理界面就可以对水果信息实现具体的操作,如果超时重的水果没有了就删除该水果信息,或者数量价格等需要变更时进行修改,这写操作都可以在管理系统中完成。

【实现思路】

  1. 系统欢迎窗口是一个窗体,可以通过 JFrame 组件来实现。该窗口主要分为两部分,一个是北区图片区,里面包含一张图片,另一个正文区,包含一个“进入系统”按钮。北区图片可以放置在 JLabel 组件中,而按钮可以通过 JButton 组件实现。其中,“进入系统”按钮上需要添加一个监听器,单击时触发跳转到货物管理窗口的事件。可以定义一个继承自 JFrame 的抽象类,在类中定义方法,令其实现窗口中的组件和功能。
  2. 在完成系统欢迎窗口类定义后,可以定义一个测试类,在类中创建窗体对象并显示窗体,为了演示效果,单击“进入系统”按钮时,可以输出一句话。
  3. 超市欢迎窗口实现后,接下来需要实现超市货物管理窗口的界面展示。该窗口可以通过 JDialog 组件来实现,这里一个定义一个继承自 JDialog 的抽象类,在类中需要使用 JTable 组件创建表格来显示水果列表,表格可以放在 JScrollPane 组件中。在表格下方需要定义标签、文本框以及按钮等组件。
  4. 完成了货物管理窗口类的定义后,也可以定义一个测试类来查看显示效果。
  5. 当系统的两个窗口界面都能够显示出后,接下来就要实现两个窗口的具体功能。由于弹出窗口的功能实现比较简单,这里可以先是新实现货物管理的窗口中增删改的功能。
  6. 在添加水果信息时,所添加的数据可以存储在集合中,所以可以定义一个用于存储数据的类,类中使用集合来存储数据。
  7. 有了存储数据功能的类后,就需要实现在货物管理窗口中对水果数据的查询、添加和删除等操作。这里可以将实现这些操作功能。这里可以将实现这些操作功能的类通过包来分为 3 层,这 3 层分别用于存放数据操作的类、存放实现业务逻辑的服务类和实现管理员操作的控制类。
  8. 实现了货物管理窗口中的功能后,接下来就可以实现单击“进入系统”按钮后,弹出货物管理界面功能后,此处可以创建一个类来处理单击按钮的事件。
  9. 最后定义主方法,运行程序并输入数据进行测试。

    【实现代码】

    1、创建项目,实现系统欢迎窗口类的定义

    在 Eclipse 中,创建一个名称为 fruitstore 的 Java project,在项目的 src 目录下创建一个名称为 fruitstore.view 的包,并在包中创建一个继承自 JFrame 的抽象类 AbstractMainFrame,在类中实现系统欢迎窗口的显示。如下所示。
    1. import java.awt.BorderLayout;
    2. import java.awt.event.*;
    3. import javax.swing.*;
    4. /**
    5. * 主窗口类
    6. */
    7. public abstract class AbstractMainFrame extends JFrame {
    8. private JLabel titleLabel = new JLabel(new ImageIcon("FruitStore.jpg"));
    9. private JButton btn = new JButton("进入系统");
    10. //构造函数
    11. public AbstractMainFrame() {
    12. this.init(); //初始化操作
    13. this.addComponent(); //添加组件
    14. this.addListener(); //添加监听器
    15. }
    16. //初始化操作
    17. private void init() {
    18. this.setTitle("水果超市欢迎您!"); //设置标题
    19. this.setSize(600, 400); //设置窗体大小
    20. this.setResizable(false); //设置窗体大小固定
    21. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    22. }
    23. //添加组件
    24. private void addComponent() {
    25. //窗体使用默认的边界布局管理器,在 NORTH 区域放入图片
    26. this.add(this.titleLabel, BorderLayout.NORTH);
    27. //创建 JPanel 对象
    28. JPanel btnPanel = new JPanel();
    29. //清除布局,使 JPanel 中的组件可以自定义位置
    30. btnPanel.setLayout(null);
    31. //将 JPanel 中的组件添加到窗体中
    32. this.add(btnPanel);
    33. //定义边界位置
    34. btn.setBounds(240, 20, 120, 50);
    35. //将按钮添加到 JPanel 对象中
    36. btnPanel.add(btn);
    37. }
    38. //添加监听器
    39. private void addListener() {
    40. btn.addActionListener(new ActionListener() {
    41. showAdminDialog();
    42. }
    43. });
    44. }
    45. //展示管理员界面方法
    46. public abstract void showAdminDialog();
    47. }
    上述代码块中,第 8 行和第 9 行代码分别定义了存放主题图片的标签和“进入系统”按钮这两个组件,其中所需的图片需放置在项目的根目录中。第 11~15 行代码定义了一个构造行数,其中调用了初始化窗口,添加组件及添加监听器的方法。第 24~37 行代码用于添加组件,将主题图片标签和“进入系统”按钮加入到窗体中。第 39~44 行代码用于为 “进入系统”按钮添加监听器,其中调用了 showAdminDialog()方法。在第 46 行代码定义了 showAdminDialog()方法,该方法时一个展示管理员界面的抽象方法,它的具体功能需要在子类中实现。

2、定义主窗口测试类

系统欢迎窗口类编写完成之后,可以编写一个测试类来验证其效果和功能。在 src 下创建一个名称为 fruitstore.test 的包,在包中创建一个名称为 AbstractMainFrameTest 的类,该类继承了抽象类 AbstractMainFrame,其实现代码如下所示。

import fruit.view.AbstractMainFrame;
/**
 * 主窗口测试类
 */
public class AbstractMainFrameTest extends AbstractMainFrame{
    //定义主方法
    public static void main(String[] args) {
        new AbstractMainFrameTest().setVisible(true);
    }
    //覆盖父类中展示管理员界面的方法
    public void showAdminDialog() {
        System.out.println("进入管理界面");
    }
}

在上述代码块中,第 9 行代码在创建对象时会执行父类 AbstractMainFrame 的构造方法,完成窗体的初始化、添加组件、和添加监听器操作,然后调用 setVisible(true)来显示窗体。第 111~13 行代码覆盖了父类中展示管理员的方法。为了确定方法是否被调用,使用了输出语句。运行该类后,其展示界面如下如所示。
QQ截图20200704145744.png
从上图可以看出,欢迎界面基本语句实现成功。当单击“进入系统”按钮后,控制台显示如图。
QQ截图20200704151704.png
可以看到,控制条已经输出了单击按钮时监听方法中所要输出的内容。虽然系统欢迎窗口已经展示了出来,但是从第一张图可以看出,窗口的左上角图标还是初始化的,还需要进行修改。此外,程序运行展示窗口后时,窗口默认时显示在显示器左上角的,这种显示显然很不友好,所以可以定义方法,使显示的窗口在屏幕居中。考虑到其他窗口也需要居中显示,那么就可以创建一个工具类,使用该工具类来控制指定组件的居中显示。同时也可以将窗口左上角的图标的显示放置在该工具类中,用于其他窗口的指定图标。

在项目的 src 目录下,创建一个名称为 fruitstore.tools 的包,在该包中创建一个名称为 GUITools 的类,类中定义了窗口组件居中的方法以及显示窗口的图标的方法,其编写代码如下所示。

import java.awt.Component;
import java.awt.Toolkit;
import javax.swing.JFrame;
/**
 * 工具类
 *
 */
public class GUIToos {
    //Java 提供的 GUI 默认工具类对象
    static Toolkit kit = Toolkit.getDefaultToolkit();
    //将指定组件屏幕居中
    public static void center(Component c) {
        int x = (kit.getScreenSize().width - c.getWidth()) / 2;
        int y = (kit.getScreenSize().height - c.getHeight()) / 2;
        c.setLocation(x, y);
    }
    //为指定窗口设置图标标题
    public static void setTitleImage(JFrame frame, String titleIconPath) {
        frame.setIconImage(kit.createImage(titleIconPath));
    }
}

定义完工具类后,就可以使用该工具类欢迎窗口居中了。该工具类的使用也很简单,只需要在 AbstractMainFrame.java 的初始化方法 init()中使用即可,如下所示。

//初始化操作
private void init() {
    this.setTitle("水果超市欢迎您!");    //标题
    this.setSize(600, 400);    //窗体大小
    this.setResizable(false);    //设置窗体大小固定
    GUIToos.center(this);    //设置窗体在屏幕上的位置
    GUIToos.setTitleImage(this, "title.png");    //设置窗体的标题图标
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //关闭窗口默认操作
}

在上述代码中,使用工具类设置了欢迎窗口居中显示,并设置了窗口标题图标。需要注意的是,此图标也需要放置在项目的根目录中。重新运行程序后,欢迎窗口就可以居中显示了,并且标题图标也会变成所设置的图标。

3、定义超市货物管理窗口类

在 fruitstore.view 中,创建一个名称为 AbstractAdminDialog 的类,该类是一个抽象类,继承了 JDialog,其实现代码如下所示。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import fruitstore.tools.GUIToos;
/**
 *管理窗口类
 */
public abstract class AbstractAdminDialog extends JDialog {
    //定义界面使用到的组件作为成员变量
    public JLabel tableLabel = new JLabel("水果列表");    //水果列表标题
    public JScrollPane tablePane = new JScrollPane();    //滚动视口
    protected JTable table = new JTable();    //水果列表
    private JLabel numberLabel = new JLabel("水果编号");    //编号标题
    private JLabel nameLabel = new JLabel("水果名称");    //名称标题
    private JLabel priceLabel = new JLabel("水果单价");    //单价标题
    private JLabel unitLabel = new JLabel("计价单位");    //计价单位标题
    //添加功能组件
    protected JTextField addNumberText = new JTextField(6);    //添加编号文本框
    protected JTextField addNameText = new JTextField(6);    //添加名称文本框
    protected JTextField addPriceText = new JTextField(6);    //添加单价文本框
    protected JTextField addUnitText = new JTextField(6);    //添加计价单位文本框
    private JButton addBtn = new JButton("添加水果");    //添加按钮
    //修改功能组件
    protected JTextField updateNumberText = new JTextField(6);    //修改编号文件框
    protected JTextField updateNameText = new JTextField(6);    //修改名称文本框
    protected JTextField updatePriceText = new JTextField(6);    //修改单价文本框
    protected JTextField updateUnitText = new JTextField(6);    //修改单位文本框
    private JButton updateBtn = new JButton("修改水果");    //修改按钮
    //删除功能组件
    protected JTextField delNumberText = new JTextField(6);    //添加编号文本
    private JButton delBtn = new JButton("删除水果");    //删除按钮
    //构造方法
    public AbstractAdminDialog() {
        this(null, true);
    }
    public AbstractAdminDialog(Frame owner, boolean modal) {
        super(owner, modal);
        this.init();    //初始化操作
        this.addComponent();    //添加组件
        this.addListener();    //添加监听器
    }
    //初始化操作
    public void init() {
        this.setTitle("超市货物管理");    //设置标题
        this.setSize(600, 400);    //设置窗体大小
        GUIToos.center(this);    //设置窗体在屏幕上的位置
        this.setResizable(false);    //设置窗体大小固定
    }
    //添加组件
    private void addComponent() {
        //取消布局
        this.setLayout(null);
        //表格标题
        tableLabel.setBounds(265, 20, 70, 25);    
        this.add(tableLabel);
        //表格
        table.getTableHeader().setReorderingAllowed(false);    //列不可移动
        table.getTableHeader().setResizingAllowed(false);    //不可拉动表格
        table.setEnabled(false);    //不可编辑数据
        tablePane.setBounds(50, 50, 500, 200);    
        tablePane.setViewportView(table);    //视口装入表格
        this.add(tablePane);
        //字段标题
        numberLabel.setBounds(50, 250, 70, 25);
        nameLabel.setBounds(150, 250, 70, 25);
        priceLabel.setBounds(250, 250, 70, 25);
        unitLabel.setBounds(350, 250, 70, 25);
        this.add(numberLabel);
        this.add(nameLabel);
        this.add(priceLabel);
        this.add(unitLabel);
        //添加组件
        addNumberText.setBounds(50, 280, 80, 25);
        addNameText.setBounds(150, 280, 80, 25);
        addPriceText.setBounds(250, 280, 80, 25);
        addUnitText.setBounds(350, 280, 80, 25);
        this.add(addNumberText);
        this.add(addNameText);
        this.add(addPriceText);
        this.add(addUnitText);
        addBtn.setBounds(460, 280, 90, 25);
        this.add(addBtn);
        //修改组件
        updateNumberText.setBounds(50, 310, 80, 25);
        updateNameText.setBounds(150, 310, 80, 25);
        updatePriceText.setBounds(250, 310, 80, 25);
        updateUnitText.setBounds(350, 310, 80, 25);
        this.add(updateNumberText);
        this.add(updateNameText);
        this.add(updatePriceText);
        this.add(updateUnitText);
        updateBtn.setBounds(460, 310, 90, 25);
        this.add(updateBtn);
        //删除组件
        delNumberText.setBounds(50, 340, 90, 25);
        this.add(delNumberText);
        delBtn.setBounds(460, 340, 90, 25);
        this.add(delBtn);
    }
    //添加监听器
    private void addListener() {
        //添加按钮监听
        addBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //调用添加方法
                addFruitItem();
            }
        });
        //修改按钮监听
        updateBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //调用修改方法
                updateFruitItem();
            }
        });
        //删除按钮监听
        delBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //调用删除方法
                delFruitItem();
            }
        });
    }
    //查询方法
    public abstract void queryFruitItem();
    //添加方法
    public abstract void addFruitItem();
    //修改方法
    public abstract void updateFruitItem();
    //删除方法
    public abstract void delFruitItem();
}

上述代码块中,9~31 行代码定义了组成系统管理窗口所需的组件和成员变量,其中功能方法使用到的成员变量定义为 protected,是为了方便窗口的子类重写方法后仍然可以访问;第 33~41 行代码定义了该类的构造方法,使用构造方法来完成窗口初始化信息、组件的组件的添加和添加监听器的功能;第 43~123 行代码分别定义了构造方法中调用的初始化操作、添加组件和添加监听的方法,其中组件的添加和监听都定义了添加、修改和删除的方法;第 125~131 行代码分别定义了查询、添加、修改和删除的方法。

  • 第 34 行代码:不理解

    4、定义超市货物管理窗口测试类

    超市货物管理窗口类编写完成之后,可以编写一个测试类来验证效和功能。在 fruitstore.test 包中创建一个 AbstractAdminDialogTest 的类,该类继承了 AbstractAdminDialog 类,其实现代码如下所示。
    import javax.swing.table.*;
    import fruitstore.view.AbstractAdminDialog;
    /**
    *管理界面测试
    */
    public class AbstractAdminDialogTest extends AbstractAdminDialog{
      //定义构造方法初始化数据
      public AbstractAdminDialogTest() {
          super();
          queryFruitItem();    //测试数据
      }
      //加入测试 table 数据
      public void queryFruitItem() {
          String[] thead = new String[] {"水果编号", "水果名称", "水果单价(/元)", "计价单位"};
          String[][] tbody = new String[][] {
              {"1", "苹果", "5.0", "kg"},
              {"2", "葡萄", "3.2", "斤"}, 
              {"3", "雪梨", "3.8", "斤"}, 
              {"4", "泰国大榴莲", "120", "个"}
          }; 
          TableModel data = new DefaultTableModel(tbody, thead);
          table.setModel(data);
      }
      public void addFruitItem() {
      }
      public void updateFruitItem() {
      }
      public void delFruitItem() {
      }
      //定义主方法运行程序
      public static void main(String[] args) {
          //创建界面并显示
          new AbstractAdminDialogTest().setVisible(true);
      }
    }
    
    上述代码块中,第 8~11 行代码定义了构造方法来初始化数据,为了能够查看窗口中表格数据的显示效果。第 13~23 行代码定义了一个测试方法 queryFruitItem(),在该方法中加入了一些水果信息的初始信息。由于该类继承了 AbstractAdminDialog 类,所有类中需要重写添加、修改和删除的方法。最后通过第 31~34 行代码定义主方法来运行程序,实现界面显示。

运行程序后,其界面显示如下图所示。
QQ截图20200706002615.png

5、编写水果项的实体类

在 src 目录下创建一个名称为 fruitstore.domain 的包,在包中创建又给名称为 FruitItem 的实体类,其代码如下所示。

/**
 * 水果数据模型
 */
public class FriutItem {
    //属性
    private String number;    //编号
    private String name;    //名称
    private double price;    //单价
    private String unit;    //单位
    //构造方法
    public FriutItem() {
    }
    public FriutItem(String number, String name, double price, String unit) {
        super();
        this.number = number;
        this.name = name;
        this.price = price;
        this.unit = unit;
    }
    //get/set 方法
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    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 String getUnit() {
        return unit;
    }
    public void setUnit(String unit) {
        this.unit = unit;
    }
}

在上述代码块中定义了水果的编号、名称等属性,并生成了各个属性的 getter 和 setter 方法,同时还定义了水果类无参和有参的构造方法。

6、定义存储数据类

在 src 目录下,创建一个名称为 fruitstore.data 的包,在包中创建一个名称为 DataBase 的类,该类使用集合来模仿数据库存储数据的功能。其代码如下所示。

import java.util.ArrayList;
import fruitstore.domian.FriutItem;
/**
 * 存储数据
 */
public class DataBase {
    public static ArrayList<FriutItem> data = new ArrayList<FriutItem>();
    //初始数据
    static {
        data.add(new FriutItem("1", "apple", 5.0, "kg"));
    }
}

7、分层编写存放数据的操作类、存放实现业务逻辑的服务类和实现管理员操作的控制类

(1)创建数据访问类

在 src 目录下,创建一个名称为 fruitstore.dao 的包,在包中创建一个名称为 AdminDao 的类,使用该类与初始的数据进行交互操作。其代码如下所示。

import java.util.ArrayList;
import fruitestore.data.DataBase;
import fruitstore.domian.FriutItem;
/**
 * 管理员数据访问类
 */
public class AdminDao {
    //获取所有数据
    public ArrayList<FriutItem> queryAllData() {
        return DataBase.data;
    }
    //添加数据
    public void addFruitItem(FriutItem fruitItem) {
        DataBase.data.add(fruitItem);
    }
    //删除数据
    public void delFruitItem(String delNumber) {
        //查询集合中数据
        for (int i = 0; i < DataBase.data.size(); i++) {
            FriutItem thisFruitItem = DataBase.data.get(i);
            //如果有水果项与传入编号相同,则从集合中删除
            if (thisFruitItem.getNumber().equals(delNumber)) {
                DataBase.data.remove(i);
            }
        }
    }
}

(2)创建管理服务类

在 src 目录下,创建一个名称为 fruitstore.service 的包,在包中创建一个名称为 AdminSerive 的类,该类主要用于实现窗口界面查询、添加等服务操作。其代码如下所示。

import java.util.ArrayList;
import fruitstore.dao.AdminDao;
import fruitstore.domian.FruitItem;
/**
 * 管理员服务类
 */
public class AdminService {
    private AdminDao adminDao = new AdminDao();
    //查询服务
    public ArrayList<FruitItem> querryFruitItem() {
        //调用 Dao 层的获取所有数据方法获取所有数据
        ArrayList<FruitItem> data = adminDao.queryAllData();
        return data;
    }
    //添加服务
    public boolean addFruitItem(String number, String name, String price, String unit) {
        //调用 Dao 层的获取所有数据方法获取所有数据
        ArrayList<FruitItem> data = querryFruitItem();
        //使用输入的序号与所有数据对比
        for (int i = 0; i < data.size(); i++) {
            FruitItem fruitItem = data.get(i);
            if (number.equals(fruitItem.getNumber())) {
                //如果存在重复编号,则添加不成功
                return false;
            }
        }
        //如果没有重复编号,将数据封装为 FruitItem 对象
        FruitItem thisFruitItem = new FruitItem(number, name, Double.parseDouble(price), unit);
        //调用 Dao 层的添加数据方法
        adminDao.addFruitItem(thisFruitItem);
        //在添加数据后,返回添加成功
        return true;
    }
    //修改服务
    public boolean updateFruitItem(String number, String name, String price, String unit) {
        //调用 Dao 层的获取所有数据方法获取所有数据
        ArrayList<FruitItem> data = querryFruitItem();
        //使用输入的编号与所有数据对比
        for (int i = 0; i < data.size(); i++) {
            FruitItem fruitItem = data.get(i);
            //如果存在相同编号,则可以修改
            if (number.equals(fruitItem.getNumber())) {
                //调用 Dao 层的删除指定编号数据方法
                adminDao.delFruitItem(number);
                //将修改后的数据封装为 FruitItem 对象
                FruitItem thisFruitItem = new FruitItem(number, name, Double.parseDouble(price), unit);
                //调用 Dao 层的添加数据方法
                adminDao.addFruitItem(thisFruitItem);
                //在修改数据后,返回成功
                return true;
            }
        }
        //如果不存在相同编号,则修改失败
        return false;
    }
    //删除服务
    public boolean delFruitItem(String delNumber) {
        //调用 Dao 层的获取所有数据方法获取所有数据
        ArrayList<FruitItem> data = querryFruitItem();
        //使用输入的编号与所有数据对比
        for (int i = 0; i < data.size(); i++) {
            FruitItem fruitItem = data.get(i);
            //如果存在相同编号,则可以删除
            if (delNumber.equals(fruitItem.getNumber())) {
                //调用 Dao 层的删除指定编号数据方法
                adminDao.delFruitItem(delNumber);
                //在删除成功后,返回成功
                return true;
            }
        }
        //如果不存在相同编号数据,则删除失败
        return false;
    }
}

(3)创建管理员界面操作类

在 src 目录下,创建一个名称为 fruitstore.controller 的包,在包中创建一个名称为 AdminDialogController 的类。实际上,该类就是测试类 AbstractAdminDialogTest 中的内容,只是这里实现了测试类所有需要完成的具体方法。其代码如下所示。

package fruitstore.controller;
import java.awt.Frame;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.table.*;
import fruitstore.domian.FruitItem;
import fruitstore.service.AdminService;
import fruitstore.view.AbstractAdminDialog;
/**
 * 管理员界面操作类
 */
public class AdminDialogController extends AbstractAdminDialog{
    //定义服务类,提供完整功能服务
    private AdminService adminService = new AdminService();
    //构造方法
    public AdminDialogController() {
        super();
    }
    public AdminDialogController(Frame owner, boolean modal) {
        super(owner, modal);
        //创建对象时显示数据
        queryFruitItem();
    }
    //查询方法
    @Override
    public void queryFruitItem() {
        //定义表格头
        String[] thead = {"水果编号","水果名称","水果单价(/元)","计价单位"};
        //调用 adminService 的查询服务
        ArrayList<FruitItem> datalList = adminService.querryFruitItem();
        //调用 list2Array 方法,将查询到的集合转为数组,方便为 JTable 赋值
        String[][] tbody = list2Array(datalList);
        //将查询到的结果为 table 赋值
        TableModel dataModel = new DefaultTableModel(tbody, thead);
        table.setModel(dataModel);
    }
    //集合数据转为二维数组方法
    private String[][] list2Array(ArrayList<FruitItem> list) {
        //根据 FruitItem 的 model 与集合数据定义 JTable 的数据二维数组
        String[][] tbody = new String[list.size()][4];
        for (int i = 0; i < list.size(); i++) {
            FruitItem fruitItem = list.get(i);
            tbody[i][0] = fruitItem.getNumber();
            tbody[i][1] = fruitItem.getName();
            tbody[i][2] = fruitItem.getPrice() + "";
            tbody[i][3] = fruitItem.getUnit();
        }
        return tbody;
    }
    //添加方法
    @Override
    public void addFruitItem() {
        //获取数据
        String addNumber = addNumberText.getText();
        String addName = addNameText.getText();
        String addPrice = addPriceText.getText();
        String addUnit = addUnitText.getText();
        //调用 adminService 的添加服务
        boolean addSuccess = adminService.addFruitItem(addNumber, addName, addPrice, addUnit);
        //如果添加成功
        if (addSuccess) {
            //添加后刷新表格
            queryFruitItem();
        }else {
            //没有成功则弹窗错误提示
            JOptionPane.showMessageDialog(this, "水果编号不能重复,请检查数据!");
        }
    }
    //修改方法
    @Override
    public void updateFruitItem() {
        //获取数据
        String updateNumber = addNumberText.getText();
        String updateName = addNameText.getText();
        String updatePrice = addPriceText.getText();
        String updataUnit = addUnitText.getText();
        //调用 adminService 的修改服务
        boolean updateSuccess = adminService.updateFruitItem(updateNumber, updateName, updatePrice, updataUnit);
        //如果修改成功
        if (updateSuccess) {
            //修改成功后刷新表格
            queryFruitItem();
        }else {
            //没有修改成功则弹窗错误提示
            JOptionPane.showMessageDialog(this, "没有这个编号的水果,请检查数据!");
        }
    }
    //删除方法
    @Override
    public void delFruitItem() {
        //获取数据
        String delNumber = delNumberText.getText();
        //调用 adminService 的删除服务
        boolean delSuccess = adminService.delFruitItem(delNumber);
        //如果删除成功
        if (delSuccess) {
            //删除成功后刷新表格
            queryFruitItem();
        }else {
            //没有删除成功则弹窗错误提示
            JOptionPane.showMessageDialog(this, "没有这个编号的水果,请检查数据!");
        }
    }
}

8、创建主界面操作类

在 fruitstore.concroller 包中创建一个名称为 MainFrameController 的类。实际上,该类就是测试类 AbstractMainFrameTest 的内容,只是实现了其中的具体方法。其代码如下所示。

import fruitstore.view.AbstractMainFrame;
/**
 *主界面操作类
 */
public class MainFrameController extends AbstractMainFrame{
    @Override
    public void showAdminDialog() {
        //在该方法中创建管理员界面并显示
        //this 为父类窗口(主界面) true:设置为模态窗口显示
        new AdminDialogController(this, true).setVisible(true);
    }
}

9、定义 main 方法,运行项目

在 src 目录下,创建一个名称为 fruitstore.app 的包,在包中创建一个名称为 MainApp 的类,该类是项目的执行入口,其代码如下所示。

import fruitstore.controller.MainFrameController;

public class MainApp {
    public static void main(String[] args) {
        new MainFrameController().setVisible(true);
    }
}

在上述代码块中,定义了一个主函数,运行主函数后,首先显示的是欢迎窗口,此时单击“进入系统”按钮后,会弹出超市货物管理窗口,这时窗口中表格显示的是存储数据类中的初始数据。分别测试水果的添加、修改和删除功能,添加一条数据后,其界面列表中的内容如下图所示。
QQ截图20200707140104.png