Java SE 练习篇 P1 设备管理系统(awt,swing,数据库编程)

1 系统总览

1.1 需求分析

使用Java完成一个设备管理系统,要求可视化友善的图形操作界面,能够对数据内的表进行增删改查,能够准确地更改数据库内表的设备的状态

1.2 思路概述

采用awt+swing完成界面编程,整体采用MVC开发模式,将访问数据库的任务,提供给APP的方法,数据库表实体对象,界面设计,测试分离,尽量满足高内聚,低耦合

在这里插入图片描述

1.3 关系数据库表设计

设备基础信息表sys_device
sys_device主键为id,无外键
在这里插入图片描述
在这里插入图片描述
设备详细信息表sys_device_details
sys_device_details主键为id,外键关联sys_device表的id,
外键完整性约束选择CASCADE

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 实现效果

在这里插入图片描述

1.5 源码链接

链接:https://pan.baidu.com/s/1tlrmMfd33BkbnuJaV6khpg
提取码:abcd

2 系统结构

2.1 dao 访问数据库的操作,完成增删改查

(1) DeviceDao

访问表sys_device,完成对表的增删查改

package com.coisini.dao;

import com.coisini.model.Device;

import java.sql.*;

/**
 * @author 雫
 * @date 2021/1/16 - 17:55
 * @function 访问表sys_device
 */
public class DeviceDao {
    
    
    private Connection connection;
    private PreparedStatement preparedStatement;

    public DeviceDao() {
    
    }

    /**
     * @Author 雫
     * @Description 获取与数据库的连接
     * @Date 2021/1/16 18:05
     * @Param []
     * @return java.sql.Connection
     **/
    private Connection getConnection() throws ClassNotFoundException, SQLException {
    
    
        if(connection == null) {
    
    
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(
                    "jdbc:mysql://127.0.0.1:3306/device_control_system",
                    "root",
                    "111");
        }
        return connection;
    }


    /**
     * @Author 雫
     * @Description 添加一个设备到表sys_device中
     * @Date 2021/1/16 18:08
     * @Param [device]
     * @return void
     **/
    public void addOneDevice(Device device) throws SQLException, ClassNotFoundException {
    
    
        int id = device.getId();
        String name = device.getName();
        char state = device.getState();
        String ip = device.getIp();

        String sql = "INSERT INTO sys_device(id, name, state, ip)"
                        + " VALUE(" + "'" + id + "'" + ","
                                    + "'" + name + "'" + ","
                                    + "'" + state + "'" + ","
                                    + "'" + ip + "'" + ")";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }


    /**
     * @Author 雫
     * @Description 从表中根据id删除一个设备
     * @Date 2021/1/16 18:28
     * @Param [id]
     * @return void
     **/
    public void deleteOneDevice(int id) throws SQLException, ClassNotFoundException {
    
    
        String sql = "DELETE FROM sys_device"
                        + " WHERE id = " + "'" + id +"'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 更改表中某设备的工作状态
     * @Date 2021/1/16 18:38
     * @Param [state]
     * @return void
     **/
    public void updateOneDeviceState(int id, char state) throws SQLException, ClassNotFoundException {
    
    
        String sql = "UPDATE sys_device"
                        + " SET state = " + "'" + state + "'"
                        + " WHERE id = " + "'" + id + "'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 更改表中某设备的ip地址
     * @Date 2021/1/16 18:50
     * @Param [id, ip]
     * @return void
     **/
    public void updateOneDeviceIp(int id, String ip) throws SQLException, ClassNotFoundException {
    
    
        String sql = "UPDATE sys_device"
                + " SET ip = " + "'" + ip + "'"
                + " WHERE id = " + "'" + id + "'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 查询表中的所有设备
     * @Date 2021/1/16 18:57
     * @Param []
     * @return java.sql.ResultSet
     **/
    public ResultSet selectAllDevice() throws SQLException, ClassNotFoundException {
    
    
        String sql = "SELECT *"
                        + " FROM sys_device";
        this.preparedStatement = getConnection().prepareStatement(sql);
        ResultSet resultSet = this.preparedStatement.executeQuery();
        return resultSet;
    }

    /**
     * @Author 雫
     * @Description 根据id查询指定设备
     * @Date 2021/1/16 19:04
     * @Param []
     * @return java.sql.ResultSet
     **/
    public ResultSet selectOneDeviceById(int id) throws SQLException, ClassNotFoundException {
    
    
        String sql = "SELECT id, name, state, ip"
                        + " FROM sys_device"
                        + " WHERE id = " + "'" + id +"'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        ResultSet resultSet = this.preparedStatement.executeQuery();
        return resultSet;
    }

}

(2) DeviceDetailsDao

访问表sys_device_details,完成对表的增删查改

package com.coisini.dao;

import com.coisini.model.DeviceDetails;

import java.sql.*;

/**
 * @author 雫
 * @date 2021/1/16 - 17:56
 * @function 访问表sys_device_details
 */
public class DeviceDetailsDao {
    
    
    private Connection connection;
    private PreparedStatement preparedStatement;

    public DeviceDetailsDao() {
    
    }

    /**
     * @Author 雫
     * @Description 获取与数据库的连接
     * @Date 2021/1/16 19:15
     * @Param []
     * @return java.sql.Connection
     **/
    private Connection getConnection() throws ClassNotFoundException, SQLException {
    
    
        if(connection == null) {
    
    
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(
                    "jdbc:mysql://127.0.0.1:3306/device_control_system",
                    "root",
                    "111");
        }
        return connection;
    }

    /**
     * @Author 雫
     * @Description 添加一条设备详细信息到表中
     * @Date 2021/1/16 19:22
     * @Param [deviceDetails]
     * @return void
     **/
    public void addOneDeviceDetails(DeviceDetails deviceDetails) throws SQLException, ClassNotFoundException {
    
    
        int id = deviceDetails.getId();
        double temperature = deviceDetails.getTemperature();
        double humidity = deviceDetails.getHumidity();
        double power = deviceDetails.getPower();

        String sql = "INSERT INTO sys_device_details(id, temperature, humidity, power)"
                        + " VALUE(" + "'" + id + "'" + ","
                                    + "'" + temperature + "'" + ","
                                    + "'" + humidity + "'" + ","
                                    + "'" + power + "'" + ")";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 从表中根据id删除一条设备信息
     * @Date 2021/1/16 19:33
     * @Param [id]
     * @return void
     **/
    public void deleteOneDeviceDetails(int id) throws SQLException, ClassNotFoundException {
    
    
        String sql = "DELETE FROM sys_device_details"
                + " WHERE id = " + "'" + id +"'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 更新表中某设备的温湿度信息
     * @Date 2021/1/16 19:42
     * @Param [id, temperature, humidity]
     * @return void
     **/
    public void updateOneDeviceDetailsTandH(int id, double temperature, double humidity) throws SQLException, ClassNotFoundException {
    
    
        String sql = "UPDATE sys_device_details"
                        + " SET temperature = " + "'" + temperature + "'" + ","
                            + " humidity = " + "'" + humidity + "'"
                        + " WHERE id = " + "'" + id + "'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 更新表中某设备的功率信息
     * @Date 2021/1/16 19:46
     * @Param [id, power]
     * @return void
     **/
    public void updateOneDeviceDetailsPower(int id, double power) throws SQLException, ClassNotFoundException {
    
    
        String sql = "UPDATE sys_device_details"
                        + " SET power = " + "'" + power + "'"
                        + " WHERE id = " + "'" + id + "'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        this.preparedStatement.executeUpdate();
    }

    /**
     * @Author 雫
     * @Description 查询表中所有记录
     * @Date 2021/1/16 19:56
     * @Param []
     * @return java.sql.ResultSet
     **/
    public ResultSet selectAllDeviceDetails() throws SQLException, ClassNotFoundException {
    
    
        String sql = "SELECT *"
                + " FROM sys_device_details";
        this.preparedStatement = getConnection().prepareStatement(sql);
        ResultSet resultSet = this.preparedStatement.executeQuery();
        return resultSet;
    }

    /**
     * @Author 雫
     * @Description 查询指定id的设备信息
     * @Date 2021/1/16 19:59
     * @Param [id]
     * @return java.sql.ResultSet
     **/
    public ResultSet selectOneDeviceDetailsById(int id) throws SQLException, ClassNotFoundException {
    
    
        String sql = "SELECT id, temperature, humidity, power"
                + " FROM sys_device_details"
                + " WHERE id = " + "'" + id +"'";
        this.preparedStatement = getConnection().prepareStatement(sql);
        ResultSet resultSet = this.preparedStatement.executeQuery();
        return resultSet;
    }

}

2.2 model 表实体对应的实体类,字符串类

(1) Device

sys_device表对应的实体类

package com.coisini.model;

/**
 * @author 雫
 * @date 2021/1/16 - 17:41
 * @function sys_device 设备基础信息实体类
 */
public class Device {
    
    
    private int id;
    private String name;
    private char state;
    private String ip;

    public Device() {
    
    }

    public Device(int id, String name, char state, String ip) {
    
    
        this.id = id;
        this.name = name;
        this.state = state;
        this.ip = ip;
    }


    public int getId() {
    
    
        return id;
    }

    public Device setId(int id) {
    
    
        this.id = id;
        return this;
    }

    public String getName() {
    
    
        return name;
    }

    public Device setName(String name) {
    
    
        this.name = name;
        return this;
    }

    public char getState() {
    
    
        return state;
    }

    public Device setState(char state) {
    
    
        this.state = state;
        return this;
    }

    public String getIp() {
    
    
        return ip;
    }

    public Device setIp(String ip) {
    
    
        this.ip = ip;
        return this;
    }

    @Override
    public String toString() {
    
    
        return id + ", " + name + ", " + state + ", " + ip;
    }
}

(2) DeviceDetails

sys_device_details表对应的实体类

package com.coisini.model;

/**
 * @author 雫
 * @date 2021/1/16 - 17:42
 * @function sys_device_details 设备详细信息实体类
 */
public class DeviceDetails {
    
    
    private int id;
    private double temperature;
    private double humidity;
    private double power;

    public DeviceDetails() {
    
    }

    public DeviceDetails(int id, double temperature, double humidity, double power) {
    
    
        this.id = id;
        this.temperature = temperature;
        this.humidity = humidity;
        this.power = power;
    }

    public int getId() {
    
    
        return id;
    }

    public DeviceDetails setId(int id) {
    
    
        this.id = id;
        return this;
    }

    public double getTemperature() {
    
    
        return temperature;
    }

    public DeviceDetails setTemperature(double temperature) {
    
    
        this.temperature = temperature;
        return this;
    }

    public double getHumidity() {
    
    
        return humidity;
    }

    public DeviceDetails setHumidity(double humidity) {
    
    
        this.humidity = humidity;
        return this;
    }

    public double getPower() {
    
    
        return power;
    }

    public DeviceDetails setPower(double power) {
    
    
        this.power = power;
        return this;
    }

    @Override
    public String toString() {
    
    
        return id + ", " + temperature + ", " + humidity + ", " + power;
    }
}

(3) DeviceStr,DeviceDetailsStr

sys_device表对应的字符串类

package com.coisini.model;

/**
 * @author 雫
 * @date 2021/1/17 - 16:46
 * @function 设备基础信息的字符串实体类
 */
public class DeviceStr {
    
    
    private String id;
    private String name;
    private String state;
    private String ip;

    public DeviceStr() {
    
    }

    public DeviceStr(String id, String name, String state, String ip) {
    
    
        this.id = id;
        this.name = name;
        this.state = state;
        this.ip = ip;
    }


    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 String getState() {
    
    
        return state;
    }

    public void setState(String state) {
    
    
        this.state = state;
    }

    public String getIp() {
    
    
        return ip;
    }

    public void setIp(String ip) {
    
    
        this.ip = ip;
    }

    @Override
    public String toString() {
    
    
        return  id + "," + name + "," + state + "," + ip;
    }
}

sys_device_details表对应的字符串类

package com.coisini.model;

/**
 * @author 雫
 * @date 2021/1/17 - 17:29
 * @function 设备详细信息的字符串实体类
 */
public class DeviceDetailsStr {
    
    
    private String id;
    private String temperature;
    private String humidity;
    private String power;

    public DeviceDetailsStr() {
    
    }

    public DeviceDetailsStr(String id, String temperature, String humidity, String power) {
    
    
        this.id = id;
        this.temperature = temperature;
        this.humidity = humidity;
        this.power = power;
    }

    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getTemperature() {
    
    
        return temperature;
    }

    public void setTemperature(String temperature) {
    
    
        this.temperature = temperature;
    }

    public String getHumidity() {
    
    
        return humidity;
    }

    public void setHumidity(String humidity) {
    
    
        this.humidity = humidity;
    }

    public String getPower() {
    
    
        return power;
    }

    public void setPower(String power) {
    
    
        this.power = power;
    }

    @Override
    public String toString() {
    
    
        return id + "," + temperature + "," + humidity + "," + power;
    }
}

2.3 service 提供给app访问数据库的方法

(1) DeviceService

基于DeviceDao,为app服务

package com.coisini.service;

import com.coisini.dao.DeviceDao;
import com.coisini.model.Device;
import com.coisini.model.DeviceStr;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 雫
 * @date 2021/1/16 - 17:54
 * @function 设备基础信息服务类
 */
public class DeviceService {
    
    
    private DeviceDao deviceDao;

    public DeviceService() {
    
    
        this.deviceDao = new DeviceDao();
    }

    /**
     * @Author 雫
     * @Description 添加一个设备到表sys_device,需要一个完整的Device类对象
     * @Date 2021/1/16 17:58
     * @Param [device]
     * @return void
     **/
    public void addOneDevice(Device device) throws Throwable {
    
    
        this.deviceDao.addOneDevice(device);
    }

    /**
     * @Author 雫
     * @Description 从表sys_device中删除一个指定编号的设备
     * @Date 2021/1/16 18:25
     * @Param [id]
     * @return void
     **/
    public void deleteOneDevice(int id) throws Throwable {
    
    
        this.deviceDao.deleteOneDevice(id);
    }

    /**
     * @Author 雫
     * @Description 更改sys_device中一个设备的状态
     * @Date 2021/1/16 18:37
     * @Param [state]
     * @return void
     **/
    public void updateOneDeviceState(int id, char state) throws Throwable {
    
    
        this.deviceDao.updateOneDeviceState(id, state);
    }

    /**
     * @Author 雫
     * @Description 更改sys_device中一个设备的ip地址
     * @Date 2021/1/16 18:49
     * @Param [id, ip]
     * @return void
     **/
    public void updateOneDeviceIp(int id, String ip) throws Throwable {
    
    
        this.deviceDao.updateOneDeviceIp(id, ip);
    }

    /**
     * @Author 雫
     * @Description 查询sys_device表中所有设备
     * @Date 2021/1/16 18:54
     * @Param []
     * @return void
     **/
    public ResultSet selectAllDevice() throws Throwable {
    
    
        return this.deviceDao.selectAllDevice();
    }

    /**
     * @Author 雫
     * @Description 根据id号查询表sys_device中指定的设备
     * @Date 2021/1/16 19:03
     * @Param [id]
     * @return java.sql.ResultSet
     **/
    public ResultSet selectOneDeviceById(int id) throws Throwable {
    
    
        return this.deviceDao.selectOneDeviceById(id);
    }

    /**
     * @Author 雫
     * @Description 根据查询的结果集取得设备基础信息字符串列表
     * @Date 2021/1/17 16:35
     * @Param [resultSet]
     * @return java.util.List<com.coisini.model.Device>
     **/
    public List<DeviceStr> getDeviceStrList(ResultSet resultSet) throws Throwable {
    
    
        List<DeviceStr> deviceStrList = new ArrayList<>();

        while (resultSet.next()) {
    
    
            DeviceStr deviceStr = new DeviceStr();
            deviceStr.setId(resultSet.getString("id"));
            deviceStr.setName(resultSet.getString("name"));
            deviceStr.setState(resultSet.getString("state"));
            deviceStr.setIp(resultSet.getString("ip"));

            deviceStrList.add(deviceStr);
        }

        return deviceStrList;
    }

    /**
     * @Author 雫
     * @Description 根据查询得到的设备基础信息字符换列表,遍历以取得个数
     * @Date 2021/1/17 17:22
     * @Param [deviceStrList]
     * @return int
     **/
    public int getDeviceCountFromList(List<DeviceStr> deviceStrList) {
    
    
        int count = 0;

        for(int i = 1; i <= deviceStrList.size(); i++) {
    
    
            count = i;
        }
        return count;
    }


}

(2) DeviceDetailsService

基于DeviceDetailsDao,为app服务

package com.coisini.service;

import com.coisini.dao.DeviceDetailsDao;
import com.coisini.model.DeviceDetails;
import com.coisini.model.DeviceDetailsStr;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 雫
 * @date 2021/1/16 - 17:55
 * @function 设备详细信息服务类
 */
public class DeviceDetailsService {
    
    
    private DeviceDetailsDao deviceDetailsDao;

    public DeviceDetailsService() {
    
    
        this.deviceDetailsDao = new DeviceDetailsDao();
    }

    /**
     * @Author 雫
     * @Description 添加一个设备的详细信息到sys_device_details,需要一个完整的DeviceDetails类对象
     * @Date 2021/1/16 19:20
     * @Param [deviceDetails]
     * @return void
     **/
    public void addOneDeviceDetails(DeviceDetails deviceDetails) throws Throwable {
    
    
        this.deviceDetailsDao.addOneDeviceDetails(deviceDetails);
    }

    /**
     * @Author 雫
     * @Description 从表sys_device_details中删除一个指定编号的设备信息
     * @Date 2021/1/16 19:31
     * @Param [id]
     * @return void
     **/
    public void deleteOneDeviceDetails(int id) throws Throwable {
    
    
        this.deviceDetailsDao.deleteOneDeviceDetails(id);
    }

    /**
     * @Author 雫
     * @Description 从表sys_device_details中更新一个设备的温湿度信息
     * @Date 2021/1/16 19:37
     * @Param [id, temperature, humidity]
     * @return void
     **/
    public void updateOneDeviceDetailsTandH(int id, double temperature, double humidity) throws Throwable {
    
    
        this.deviceDetailsDao.updateOneDeviceDetailsTandH(id, temperature,humidity);
    }

    /**
     * @Author 雫
     * @Description 从表sys_device_details中更新一个设备的功率信息
     * @Date 2021/1/16 19:44
     * @Param [id, power]
     * @return void
     **/
    public void updateOneDeviceDetailsPower(int id, double power) throws Throwable {
    
    
        this.deviceDetailsDao.updateOneDeviceDetailsPower(id, power);
    }

    /**
     * @Author 雫
     * @Description 查询sys_device_details中所有信息
     * @Date 2021/1/16 19:54
     * @Param []
     * @return java.sql.ResultSet
     **/
    public ResultSet selectAllDeviceDetails() throws Throwable {
    
    
        return this.deviceDetailsDao.selectAllDeviceDetails();
    }

    /**
     * @Author 雫
     * @Description 根据id查询表sys_device_details中指定记录
     * @Date 2021/1/16 19:55
     * @Param [id]
     * @return java.sql.ResultSet
     **/
    public ResultSet selectOneDeviceDetailsById(int id) throws Throwable {
    
    
        return this.deviceDetailsDao.selectOneDeviceDetailsById(id);
    }

    /**
     * @Author 雫
     * @Description 根据查询的结果集取得设备详细信息字符串列表
     * @Date 2021/1/17 17:37
     * @Param [resultSet]
     * @return java.util.List<com.coisini.model.DeviceDetailsStr>
     **/
    public List<DeviceDetailsStr> getDeviceDetailsStrList(ResultSet resultSet) throws Throwable {
    
    
        List<DeviceDetailsStr> deviceDetailsStrList = new ArrayList<>();

        while(resultSet.next()) {
    
    
            DeviceDetailsStr deviceDetailsStr = new DeviceDetailsStr();
            deviceDetailsStr.setId(resultSet.getString("id"));
            deviceDetailsStr.setTemperature(resultSet.getString("temperature"));
            deviceDetailsStr.setHumidity(resultSet.getString("humidity"));
            deviceDetailsStr.setPower(resultSet.getString("power"));

            deviceDetailsStrList.add(deviceDetailsStr);
        }

        return deviceDetailsStrList;
    }

    /**
     * @Author 雫
     * @Description 根据查询得到的设备详细信息字符换列表,遍历以取得个数
     * @Date 2021/1/17 17:39
     * @Param [deviceDetailsStrList]
     * @return int
     **/
    public int getDeviceDetailsCountFromList(List<DeviceDetailsStr> deviceDetailsStrList) {
    
    
        int count = 0;

        for(int i = 1; i <= deviceDetailsStrList.size(); i++) {
    
    
            count = i;
        }
        return count;
    }

}

2.4 test 测试访问数据库有无异常,启动app

(1) DaoAndServiceTest

访问数据库有无异常

package com.coisini.test;

import com.coisini.model.DeviceDetailsStr;
import com.coisini.service.DeviceDetailsService;
import com.coisini.service.DeviceService;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 雫
 * @date 2021/1/16 - 18:19
 * @function 测试服务层和数据库
 */
public class DaoAndServiceTest {
    
    

    public static void main(String[] args) throws Throwable {
    
    

        DeviceService deviceService = new DeviceService();
        DeviceDetailsService deviceDetailsService = new DeviceDetailsService();

        
        List<DeviceDetailsStr> deviceDetailsStrList = new ArrayList<>();

        deviceDetailsStrList = deviceDetailsService.getDeviceDetailsStrList(deviceDetailsService.selectAllDeviceDetails());
        System.out.println(deviceDetailsStrList);
        System.out.println(deviceDetailsStrList.size());

        deviceDetailsStrList = deviceDetailsService.getDeviceDetailsStrList(deviceDetailsService.selectOneDeviceDetailsById(1));
        System.out.println(deviceDetailsStrList);
        System.out.println(deviceDetailsStrList.size());
    }

}

(2) DeviceControlSystemTest

启动app

package com.coisini.test;

import com.coisini.util.ViewNotFoundException;
import com.coisini.view.DeviceControlSystemView;

/**
 * @author 雫
 * @date 2021/1/16 - 17:23
 * @function 设备管理系统测试
 */
public class DeviceControlSystemTest {
    
    

    public static void main(String[] args) throws ViewNotFoundException {
    
    
        DeviceControlSystemView deviceControlSystemView = new DeviceControlSystemView();
        deviceControlSystemView.initView().showView();


    }
}

2.5 view 视图窗口(交互界面)

(1) 视图接口

窗口实现了一个接口

public interface IMecView {
    
    
    Font TOPIC_FONT = new Font("微软雅黑", 1, 26);
    Font NORMAL_FONT = new Font("宋体", 0, 16);
    Font SMALL_FONT = new Font("宋体", 0, 12);
    int MARGIN = 8;
    int TOPIC_FONT_SIZE = TOPIC_FONT.getSize();
    int NORMAL_FONT_SIZE = NORMAL_FONT.getSize();
    int SMALL_FONT_SIZE = SMALL_FONT.getSize();
    Color TOPIC_COLOR = new Color(13, 8, 180);
    Cursor HAND_CURSOR = new Cursor(12);

    void init();

    void dealAction();

    JFrame getFrame();

    void afterShowView();

    default void beforeCloseView() {
    
    
    }

    default void afterCloseView() {
    
    
    }

    default IMecView initView() {
    
    
        this.init();
        this.dealAction();
        return this;
    }

    default void showView() throws ViewNotFoundException {
    
    
        JFrame jfrmView = this.getFrame();
        if (jfrmView == null) {
    
    
            throw new ViewNotFoundException("视图不存在!");
        } else {
    
    
            jfrmView.setVisible(true);
            this.afterShowView();
        }
    }

    default void closeView() throws ViewNotFoundException {
    
    
        JFrame jfrmView = this.getFrame();
        if (jfrmView == null) {
    
    
            throw new ViewNotFoundException("视图不存在!");
        } else {
    
    
            this.beforeCloseView();
            jfrmView.dispose();
            this.afterCloseView();
        }
    }
}

(2) 完成抽象方法init(),实现窗口的设计

@Override
    public void init() {
    
    
        /*主窗口初始化*/
        this.jfrmMain = new JFrame("设备管理系统");
        this.jfrmMain.setSize(WIDTH, HEIGHT);
        this.jfrmMain.setResizable(false);
        this.jfrmMain.setLocationRelativeTo(null);
        this.jfrmMain.setLayout(new BorderLayout());
        this.jfrmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*主窗口北部填充主标题*/
        JLabel jlblTopic = new JLabel("雫-设备管理系统", JLabel.CENTER);
        jlblTopic.setFont(NORMAL_FONT);
        jlblTopic.setForeground(Color.BLUE);
        this.jfrmMain.add(jlblTopic, BorderLayout.NORTH);

        /*主窗口中央画板,分为录入画板和显示画板*/
        JPanel jpnlCenter = new JPanel(new GridLayout(1, 2));
        jpnlCenter.setBackground(Color.GRAY);
        this.jfrmMain.add(jpnlCenter, BorderLayout.CENTER);

        /*主窗口中央画板左侧的录入信息画板*/
        JPanel jpnlInputInfo = new JPanel(null);
        jpnlCenter.add(jpnlInputInfo);

        int top = 0;
        int lblWidth = 4 * NORMAL_FONT_SIZE;
        int lblHeight = NORMAL_FONT_SIZE;

        JLabel jlblId = new JLabel("编  号");
        jlblId.setFont(NORMAL_FONT);
        jlblId.setBounds(0, 0, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblId);

        this.jtxtId = new JTextField();
        this.jtxtId.setFont(NORMAL_FONT);
        this.jtxtId.setBounds(lblWidth + MARGIN, 0,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jtxtId);

        top += this.jtxtId.getHeight() + 2 * MARGIN;

        JLabel jlblName = new JLabel("名  称");
        jlblName.setFont(NORMAL_FONT);
        jlblName.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblName);

        this.jtxtName = new JTextField();
        this.jtxtName.setFont(NORMAL_FONT);
        this.jtxtName.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jtxtName);

        top += this.jtxtName.getHeight() + 2 * MARGIN;

        JLabel jlblState = new JLabel("状  态");
        jlblState.setFont(NORMAL_FONT);
        jlblState.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblState);

        this.jrbtWork = new JRadioButton("工作");
        this.jrbtWork.setFont(NORMAL_FONT);
        this.jrbtWork.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE / 2, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jrbtWork);

        this.jrbtSleep = new JRadioButton("待机");
        this.jrbtSleep.setFont(NORMAL_FONT);
        this.jrbtSleep.setBounds(lblWidth + MARGIN + jrbtWork.getWidth(), top,
                TEXT_LENGTH * NORMAL_FONT_SIZE / 2, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jrbtSleep);

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(jrbtWork);
        buttonGroup.add(jrbtSleep);

        top += this.jrbtSleep.getHeight() + 2 * MARGIN;

        JLabel jlblIP = new JLabel("地  址");
        jlblIP.setFont(NORMAL_FONT);
        jlblIP.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblIP);

        this.jtxtIP = new JTextField();
        this.jtxtIP.setFont(NORMAL_FONT);
        this.jtxtIP.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jtxtIP);

        top += this.jtxtIP.getHeight() + 2 * MARGIN;

        JLabel jlblTemperature = new JLabel("温  度");
        jlblTemperature.setFont(NORMAL_FONT);
        jlblTemperature.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblTemperature);

        this.jcmbTemperature = new JComboBox<>();
        this.jcmbTemperature.setFont(NORMAL_FONT);
        this.jcmbTemperature.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jcmbTemperature);

        top += this.jcmbTemperature.getHeight() + 2 * MARGIN;

        JLabel jlblHumidity = new JLabel("湿  度");
        jlblHumidity.setFont(NORMAL_FONT);
        jlblHumidity.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblHumidity);

        this.jcmbHumidity = new JComboBox<>();
        this.jcmbHumidity.setFont(NORMAL_FONT);
        this.jcmbHumidity.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jcmbHumidity);

        top += this.jcmbHumidity.getHeight() + 2 * MARGIN;

        JLabel jlblPower = new JLabel("功  率");
        jlblPower.setFont(NORMAL_FONT);
        jlblPower.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblPower);

        this.jcmbPower = new JComboBox<>();
        this.jcmbPower.setFont(NORMAL_FONT);
        this.jcmbPower.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jcmbPower);

        top += this.jcmbPower.getHeight() + 2 * MARGIN;

        JLabel jlblSelect = new JLabel("查  询");
        jlblSelect.setFont(NORMAL_FONT);
        jlblSelect.setForeground(Color.BLUE);
        jlblSelect.setBounds(0, top, lblWidth, lblHeight);
        jpnlInputInfo.add(jlblSelect);

        this.jcmbSelect = new JComboBox<>();
        this.jcmbSelect.setFont(NORMAL_FONT);
        this.jcmbSelect.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jcmbSelect);

        top += this.jcmbSelect.getHeight() + MARGIN;

        this.jbtnSelect = new JButton("搜索");
        this.jbtnSelect.setFont(NORMAL_FONT);
        this.jbtnSelect.setForeground(Color.BLUE);
        this.jbtnSelect.setBounds(lblWidth + MARGIN, top,
                TEXT_LENGTH * NORMAL_FONT_SIZE, NORMAL_FONT_SIZE + 4);
        jpnlInputInfo.add(this.jbtnSelect);

        /*主窗口中央画板右侧的显示信息画板*/
        JPanel jpnlShowInfo = new JPanel(new BorderLayout());
        jpnlShowInfo.setBackground(Color.BLACK);
        jpnlCenter.add(jpnlShowInfo);

        this.jtatShowInfo = new JTextArea();
        this.jtatShowInfo.setFont(NORMAL_FONT);
        this.jtatShowInfo.setForeground(Color.RED);
        this.jtatShowInfo.setBackground(Color.BLACK);

        this.jscpShowInfo = new JScrollPane(this.jtatShowInfo);
        TitledBorder ttbdSystemMessage = new TitledBorder("系统信息");
        ttbdSystemMessage.setTitleFont(NORMAL_FONT);
        ttbdSystemMessage.setTitleColor(Color.BLUE);
        ttbdSystemMessage.setTitlePosition(TitledBorder.TOP);
        ttbdSystemMessage.setTitleJustification(TitledBorder.CENTER);
        this.jscpShowInfo.setBorder(ttbdSystemMessage);

        jpnlShowInfo.add(this.jscpShowInfo, BorderLayout.CENTER);

        /*主窗口南部画板,用于放置功能按键*/
        JPanel jpnlFooter = new JPanel(new FlowLayout());
        jpnlFooter.setBackground(Color.BLUE);
        this.jfrmMain.add(jpnlFooter, BorderLayout.SOUTH);

        this.jbtnAdd = new JButton("添加");
        this.jbtnAdd.setFont(NORMAL_FONT);
        this.jbtnAdd.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnAdd);

        this.jbtnDelete = new JButton("删除");
        this.jbtnDelete.setFont(NORMAL_FONT);
        this.jbtnDelete.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnDelete);

        this.jbtnReset = new JButton("重置");
        this.jbtnReset.setFont(NORMAL_FONT);
        this.jbtnReset.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnReset);

        this.jbtnModify = new JButton("修改");
        this.jbtnModify.setFont(NORMAL_FONT);
        this.jbtnModify.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnModify);

        this.jbtnConfrim = new JButton("确认");
        this.jbtnConfrim.setFont(NORMAL_FONT);
        this.jbtnConfrim.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnConfrim);

        this.jbtnExit = new JButton("退出");
        this.jbtnExit.setFont(NORMAL_FONT);
        this.jbtnExit.setForeground(Color.BLUE);
        jpnlFooter.add(this.jbtnExit);
    }

(3) 完成抽象方法afterShowView(),对控件初始化

@Override
    public void afterShowView() {
    
    
        /*刚进入窗口的初始化*/
        this.jtxtId.requestFocus();
        this.jrbtWork.setSelected(true);

        initTemperature();
        initHumidity();
        initPower();
        try {
    
    
            initSelect();
        } catch (Throwable throwables) {
    
    
            System.out.println("初始化查询栏失败");
        }

        this.jbtnAdd.setEnabled(false);
        this.jbtnDelete.setEnabled(false);
        this.jbtnReset.setEnabled(false);
        this.jbtnModify.setEnabled(false);
        this.jbtnConfrim.setEnabled(false);

        this.jtatShowInfo.setEditable(false);
        showSystemMessage("雫-设备管理系统-V1.2.0");
    }

(4) 完成抽象方法dealAction(),实现事件监听

@Override
    public void dealAction() {
    
    

        /*编号文本框检测到回车,名称文本框获取焦点, 底部删除,修改按键可用*/
        this.jtxtId.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                jtxtName.requestFocus();

                jbtnDelete.setEnabled(true);
                jbtnModify.setEnabled(true);
            }
        });

        /*编号文本框获取焦点,编号文本框被全部选中*/
        this.jtxtId.addFocusListener(new FocusAdapter() {
    
    
            @Override
            public void focusGained(FocusEvent e) {
    
    
                jtxtId.selectAll();
            }
        });

        /*名称文本框检测到回车,地址文本框获取焦点*/
        this.jtxtName.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                jtxtIP.requestFocus();
            }
        });

        /*名称文本框获取焦点,名称文本框被全部选中*/
        this.jtxtName.addFocusListener(new FocusAdapter() {
    
    
            @Override
            public void focusGained(FocusEvent e) {
    
    
                jtxtName.selectAll();
            }
        });

        /*地址文本框检测到回车,底部 增 重置 按键变为可操作*/
        this.jtxtIP.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                jbtnAdd.setEnabled(true);
                jbtnReset.setEnabled(true);
            }
        });

        /*地址文本框获取焦点,地址文本框被全部选中*/
        this.jtxtIP.addFocusListener(new FocusAdapter() {
    
    
            @Override
            public void focusGained(FocusEvent e) {
    
    
                jtxtIP.selectAll();
            }
        });

        /*搜索键检测到回车,根据jcmbSelect的值进行查询*/
        this.jbtnSelect.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                int count = (int) jcmbSelect.getSelectedItem();
                if(count != 0) {
    
    
                    try {
    
    
                        showOneDevice(count);
                    } catch (Throwable throwables) {
    
    
                        System.out.println("检索异常");
                    }
                } else {
    
    
                    try {
    
    
                        showAllDevice();
                    } catch (Throwable throwables) {
    
    
                        System.out.println("检索异常");
                    }
                }
            }
        });

        /*添加键检测到回车,将当前界面内信息录入数据库*/
        this.jbtnAdd.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    deviceService.addOneDevice(getDeviceInfoFromView());
                    deviceDetailsService.addOneDeviceDetails(getDeviceDetailsFromView());
                    showAllDevice();
                    clearInputWindow();
                } catch (Throwable throwable) {
    
    
                }
            }
        });

        /*删除键检测到回车,删除该ID对应的设备信息和设备详细信息*/
        this.jbtnDelete.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    int id = getDeviceInfoFromView().getId();
                    deviceService.deleteOneDevice(id);
                    showAllDevice();
                    clearInputWindow();
                } catch (Throwable throwable) {
    
    
                }
            }
        });

        /*重置键检测到回车,重置输入文本框*/
        this.jbtnReset.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    clearInputWindow();
                } catch (Throwable throwable) {
    
    
                }
            }
        });

        /*修改键检测到回车,调整按键状态,等待确认*/
        this.jbtnModify.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                clearJTextArea();
                jtxtId.setEditable(false);
                jtxtName.setEditable(false);
                jbtnSelect.setEnabled(false);
                jbtnAdd.setEnabled(false);
                jbtnDelete.setEnabled(false);
                jbtnConfrim.setEnabled(true);
                jbtnExit.setEnabled(false);
                showSystemMessage("请修改该设备的信息");
            }
        });

        /*确认键检测到回车,修改设备状态,成功修改打印结果*/
        this.jbtnConfrim.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    changeDeviceInfo();
                    clearJTextArea();
                    showAllDevice();
                    jtxtId.setEditable(true);
                    jtxtName.setEditable(true);
                    jbtnSelect.setEnabled(true);
                    jbtnAdd.setEnabled(true);
                    jbtnDelete.setEnabled(true);
                    jbtnModify.setEnabled(true);
                    jbtnExit.setEnabled(true);
                    clearInputWindow();
                } catch (Throwable throwable) {
    
    
                }
            }
        });

        /*退出键检测到回车,退出界面*/
        this.jbtnExit.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                jfrmMain.dispose();
            }
        });

    }

(5) 系统依赖的方法

	/**
     * @Author 雫
     * @Description 将信息显示到系统信息文本区
     * @Date 2021/1/17 11:27
     * @Param [message]
     * @return void
     **/
    private void showSystemMessage(String message) {
    
    
        this.jtatShowInfo.append(message + "\n");
        this.jtatShowInfo.setCaretPosition(this.jtatShowInfo.getText().length());
    }

    /**
     * @Author 雫
     * @Description 清空系统信息文本区的内容
     * @Date 2021/1/17 14:52
     * @Param []
     * @return void
     **/
    private void clearJTextArea() {
    
    
        this.jtatShowInfo.setText("");
    }

    /**
     * @Author 雫
     * @Description 重置信息录入界面
     * @Date 2021/1/18 9:46
     * @Param []
     * @return void
     **/
    private void clearInputWindow() throws Throwable {
    
    
        this.jtxtId.setText("");
        this.jtxtName.setText("");
        this.jtxtIP.setText("");

        initTemperature();
        initHumidity();
        initPower();
        initSelect();
    }

    /**
     * @Author 雫
     * @Description 初始化温度选择栏
     * @Date 2021/1/17 11:42
     * @Param []
     * @return void
     **/
    private void initTemperature() {
    
    
        double theLowestTemperature = -20;
        double theHighestTemperature = 100;

        jcmbTemperature.removeAllItems();
        for(double temperature = theLowestTemperature; temperature <= theHighestTemperature; temperature++) {
    
    
            jcmbTemperature.addItem(temperature);
        }
    }

    /**
     * @Author 雫
     * @Description 初始化湿度选择栏
     * @Date 2021/1/17 11:59
     * @Param []
     * @return void
     **/
    private void initHumidity() {
    
    
        double theLowestHumidity = 10;
        double theHighestHumidity = 60;

        jcmbHumidity.removeAllItems();
        for(double humidity = theLowestHumidity; humidity <= theHighestHumidity; humidity++) {
    
    
            jcmbHumidity.addItem(humidity);
        }
    }

    /**
     * @Author 雫
     * @Description 初始化功率选择栏
     * @Date 2021/1/17 12:01
     * @Param []
     * @return void
     **/
    private void initPower() {
    
    
        double theLowestPower = 10;
        double theHighestPower = 400;

        jcmbPower.removeAllItems();
        for(double power = theLowestPower; power <= theHighestPower; power+=5) {
    
    
            jcmbPower.addItem(power);
        }
    }

    /**
     * @Author 雫
     * @Description 初始化查询选择栏
     * @Date 2021/1/17 18:02
     * @Param []
     * @return void
     **/
    private void initSelect() throws Throwable {
    
    
        int count = this.deviceService.
                            getDeviceCountFromList(this.deviceService.
                                    getDeviceStrList(this.deviceService.selectAllDevice()));

        jcmbSelect.removeAllItems();
        for(int i = 0; i <= count; i++) {
    
    
            jcmbSelect.addItem(i);
        }
    }

    /**
     * @Author 雫
     * @Description 从当前界面的信息取得一个Device类对象
     * @Date 2021/1/18 9:29
     * @Param []
     * @return com.coisini.model.Device
     **/
    private Device getDeviceInfoFromView() {
    
    
        int id = Integer.valueOf(this.jtxtId.getText());
        String name = this.jtxtName.getText();
        char state = this.jrbtWork.isSelected() ? '1' : '0';
        String ip = this.jtxtIP.getText();

        Device device = new Device(id, name, state, ip);

        return device;
    }

    /**
     * @Author 雫
     * @Description 从当前界面的信息取得一个DeviceDetails类对象
     * @Date 2021/1/18 9:36
     * @Param []
     * @return com.coisini.model.DeviceDetails
     **/
    private DeviceDetails getDeviceDetailsFromView() {
    
    
        int id = Integer.valueOf(this.jtxtId.getText());
        double temperature = (double) this.jcmbTemperature.getSelectedItem();
        double humidity = (double) this.jcmbHumidity.getSelectedItem();
        double power = (double) this.jcmbPower.getSelectedItem();

        DeviceDetails deviceDetails = new DeviceDetails(id, temperature, humidity, power);

        return deviceDetails;
    }

    /**
     * @Author 雫
     * @Description 根据当前信息输入界面的内容,修改设备信息及详细信息
     * @Date 2021/1/18 10:23
     * @Param []
     * @return void
     **/
    private void changeDeviceInfo() throws Throwable {
    
    
        int id = Integer.valueOf(this.jtxtId.getText());

        char state = this.jrbtWork.isSelected() ? '1' : '0';
        deviceService.updateOneDeviceState(id, state);

        String ip = this.jtxtIP.getText();
        deviceService.updateOneDeviceIp(id, ip);

        double temperature = (double) this.jcmbTemperature.getSelectedItem();
        double humidity = (double) this.jcmbHumidity.getSelectedItem();
        deviceDetailsService.updateOneDeviceDetailsTandH(id, temperature, humidity);

        double power = (double) this.jcmbPower.getSelectedItem();
        deviceDetailsService.updateOneDeviceDetailsPower(id, power);
    }

    /**
     * @Author 雫
     * @Description 显示需要查询的一个设备的信息,jcmbSelect不为0时
     * @Date 2021/1/17 18:09
     * @Param [i]
     * @return void
     **/
    private void showOneDevice(int i) throws Throwable {
    
    
        clearJTextArea();

        DeviceStr deviceStr = this.deviceService.
                        getDeviceStrList(this.deviceService.
                                selectOneDeviceById(i)).get(0);

        showSystemMessage("ID: " + deviceStr.getId() +
                            " Name: " + deviceStr.getName() +
                            " State: " + deviceStr.getState() +
                            " IP: " +deviceStr.getIp());

        DeviceDetailsStr deviceDetailsStr = this.deviceDetailsService.
                                                    getDeviceDetailsStrList(this.deviceDetailsService.
                                                            selectOneDeviceDetailsById(i)).get(0);

        showSystemMessage("T: " + deviceDetailsStr.getTemperature() +
                                " H: " + deviceDetailsStr.getHumidity() +
                                " P: " + deviceDetailsStr.getPower());

    }

    /**
     * @Author 雫
     * @Description 显示现存的所有设备的信息,jcmbSelect为0时
     * @Date 2021/1/17 21:52
     * @Param []
     * @return void
     **/
    private void showAllDevice() throws Throwable {
    
    
        clearJTextArea();

        for(DeviceStr deviceStr : this.deviceService.getDeviceStrList(this.deviceService.selectAllDevice())) {
    
    
            showSystemMessage("ID: " + deviceStr.getId() +
                    " Name: " + deviceStr.getName() +
                    " State: " + deviceStr.getState() +
                    " IP: " +deviceStr.getIp());
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_43541094/article/details/112766549