文章目录
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());
}
}