RFID作业,要求实现软硬结合,全部使用自己的页面完成; 找了几个教程发现安卓我做不到,就用了Java实现; 图书管理系统。 可以通过写卡来绑定15693卡和书籍,实现增删改查功能;刷卡会改变书的出入库状态;好像没了哈哈哈哈 首先感谢这位大佬的串口通信博文容华谢后使用Java实现串口通信(二) 当时遇到了问题也是看到了博主的评论才解决的,实在是万分感谢。
运行截图如下:
串口通信的包和sqlite的包都在【File->Project Structure->Moudle->Denpendicies】里的+号添加。 我的目录: 六个frame对应六个页面。三个Utils是博主的,我没有仔细去看;剩下两个分别是数据库和串口操作了。
硬件部分比较简单,单片机的代码是等待串口的数据,收到数据后存下来。在读到卡的时候写到卡里,实现交互。
串口操作
说实话我没仔细看,就是能够获取数据和传递数据就行了。是直接用的博主的代码 获取数据: 【其中,setText是让textview显示。append则是显示下一行】 而收到的数据是先保存在data里,然后显示在textview上,所以这里可以把data截下来做自己的事情;data是byte[]数组,先转成自己想要的类型。 我这里是把data作为参数插入数据库了。
private void openSerialPort(java.awt.event.ActionEvent evt) {
String commName = (String) mCommChoice.getSelectedItem();
int baudrate = 9600;
String bps = (String) mBaudrateChoice.getSelectedItem();
baudrate = Integer.parseInt(bps);
if (commName == null || commName.equals("")) {
ShowUtils.warningMessage("没有搜索到有效串口!");
} else {
try {
mSerialport = SerialPortManager.openPort(commName, baudrate);
if (mSerialport != null) {
mDataView.setText("串口已打开" + "\r\n");
mSerialPortOperate.setText("关闭串口");
}
} catch (PortInUseException e) {
ShowUtils.warningMessage("串口已被占用!");
}
}
SerialPortManager.addListener(mSerialport, new SerialPortManager.DataAvailableListener() {
@Override
public void dataAvailable() {
byte[] data = null;
try {
if (mSerialport == null) {
ShowUtils.errorMessage("串口对象为空,监听失败!");
} else {
data = SerialPortManager.readFromPort(mSerialport);
if (mDataASCIIChoice.isSelected()) {
mDataView.append(new String(data) + "\r\n");
new DBSqlite().insertsql(sendname,"在库",mDataInputAdress.getText(),ByteUtils.byteArrayToHexString(data));
}
if (mDataHexChoice.isSelected()) {
mDataView.append(ByteUtils.byteArrayToHexString(data) + "\r\n");
}
}
} catch (Exception e) {
ShowUtils.errorMessage(e.toString());
System.exit(0);
}
}
});
}
发送数据: 这里其实是把要发送的数据作为参数放到数据库了
private void sendData(java.awt.event.ActionEvent evt) {
String data = mDataInput.getText().toString();
if (mSerialport == null) {
ShowUtils.warningMessage("请先打开串口!");
return;
}
if ("".equals(data) || data == null) {
ShowUtils.warningMessage("请输入要发送的数据!");
return;
}
sendname=data;
if (mDataASCIIChoice.isSelected()) {
SerialPortManager.sendToPort(mSerialport, data.getBytes());
}
if (mDataHexChoice.isSelected()) {
SerialPortManager.sendToPort(mSerialport, ByteUtils.hexStr2Byte(data));
}
}
数据库操作
这个才是重点我觉得。 我也算是第一次用数据库做东西,但是数据库都是sql语句嘛,逻辑是很好理解的。 而且Java连sqlite的方式比较简单,连接然后执行就行了。 我的函数列表(方法?) 创建数据库: 【UNIQUE,一个表中这个值只允许出现一次;我的是15693的卡号,不允许一张卡出现两次。】
void createSql(){
Connection c = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:"+db);
System.out.println("create database success");
String sql = "CREATE TABLE Books4 " +
"(ID INTEGER PRIMARY KEY AUTOINCREMENT ," +
" NAME TEXT NOT NULL, " +
" STATUS TEXT NOT NULL, " +
" ADDRESS TEXT NOT NULL , " +
" IDCARD TEXT NOT NULL UNIQUE)";
Statement st = c.createStatement();
st.executeUpdate(sql);
c.close();
st.close();
} catch ( Exception e ) {
System.err.println( e.getMessage() );
}
}
插入:
public void insertsql(String name,String status,String address,String idcard){
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:"+db);
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "INSERT INTO Books4 (NAME,STATUS,ADDRESS,IDCARD) " +
"VALUES ('"+name+"','"+status+"','"+address+"','"+idcard+"');";
stmt.executeUpdate(sql);
stmt.close();
c.commit();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": :::" + e.getMessage() );
ShowUtils.errorMessage("卡号已存在,请注意!");
}
System.out.println("Records created successfully");
}
查询: like是模糊查询,=是限定查询 还可以自己加东西比如:
"select * from Books4 where status = '在库' AND name like '%"+name+"%';"
public String queryname(String name) throws ClassNotFoundException, SQLException {
String text="";
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:" + db);
Statement state = conn.createStatement();
ResultSet rs = state.executeQuery("select * from Books4 where name like '%"+name+"%';");
while (rs.next()) {
text=text+"ID = " + rs.getString("ID")
+ "NAME = " + rs.getString("NAME")
+ "STATUS = " + rs.getString("STATUS")
+ "ADDRESS = " + rs.getString("ADDRESS")
+ "IDCARD = " + rs.getString("IDCARD")+"\n";
}
rs.close();
conn.close();
return text;
}
修改:
public String updatastatus(String name) throws ClassNotFoundException, SQLException {
String text="修改成功!书籍信息如下:\n";
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:" + db);
Statement state = conn.createStatement();
ResultSet rs = state.executeQuery("select * from Books4 where name= '"+name+"';");
conn.setAutoCommit(false);
while (rs.next()) {
if("在库".equals(rs.getString("STATUS"))){
String sql = "UPDATE Books4 set status = '"+"出库"+"' where ID="+rs.getString("ID")+";";
state.executeUpdate(sql);
conn.commit();
}
else{
String sql = "UPDATE Books4 set status = '"+"在库"+"' where ID="+rs.getString("ID")+";";
state.executeUpdate(sql);
conn.commit();
}
ResultSet rs2 = state.executeQuery("select * from Books4 where name= '"+name+"';");
while (rs2.next()) {
text=text+"ID = " + rs2.getString("ID")
+ "NAME = " + rs2.getString("NAME")
+ "STATUS = " + rs2.getString("STATUS")
+ "ADDRESS = " + rs.getString("ADDRESS")
+"\n";}
}
rs.close();
conn.close();
return text;
}
删除:
public String deletesql(String name){
String text="";
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:"+db);
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "DELETE from Books4 where NAME='"+name+"';";
stmt.executeUpdate(sql);
c.commit();
text="删除成功!目前全部库存如下:\n"+queryname("");
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Operation done successfully");
return text;
}
GUI界面设计部分
,有一些乱,学过安卓会比较好理解。 拿其中一个举例。整个大弹窗是一个frame,然后可以包含一些控件(Java里是叫容器吧);上图蓝色框框是一个panel面板,她处于frame里,又包含着button这些控件;他们的位置是由上一级决定的,左上角的坐标是(0,0)
public final int WIDTH = 530;
public final int HEIGHT = 390;
private JButton querybutton = new JButton("查询");
private JButton deletebutton = new JButton("删除");
private JButton insertbutton = new JButton("增加");
private JButton updatabutton = new JButton("修改");
private JPanel userPanel = new JPanel();
private JTextField inputText=new JTextField();
private JTextArea sqlView = new JTextArea();
private JScrollPane sqlScrollDataView = new JScrollPane(sqlView);
private ButtonGroup mDataChoice = new ButtonGroup();
private JRadioButton statusChoice = new JRadioButton("在库");
private JRadioButton allChoice = new JRadioButton("全部",true);
public ManageFrame() throws SQLException, ClassNotFoundException {
initUserView();
initUserComponents();
actionUserListener();
}
private void initUserView() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
setBounds(p.x - WIDTH / 2, p.y - HEIGHT / 2, WIDTH, HEIGHT);
this.setLayout(null);
setTitle("图书管理系统-管理界面-查询");
}
private void initUserComponents() {
sqlView.setFocusable(false);
sqlScrollDataView.setBounds(10, 10, 505, 200);
add(sqlScrollDataView);
userPanel.setBorder(BorderFactory.createTitledBorder("行使您的管理权限"));
userPanel.setBounds(50, 220, 415, 130);
userPanel.setLayout(null);
add(userPanel);
inputText.setBounds(25, 25, 265, 50);
userPanel.add(inputText);
querybutton.setFocusable(false);
querybutton.setBounds(45, 95, 90, 20);
userPanel.add(querybutton);
statusChoice.setBounds(140, 95, 55, 20);
allChoice.setBounds(200, 95, 55, 20);
mDataChoice.add(statusChoice);
mDataChoice.add(allChoice);
userPanel.add(statusChoice);
userPanel.add(allChoice);
deletebutton.setFocusable(false);
deletebutton.setBounds(300, 15, 90, 30);
userPanel.add(deletebutton);
insertbutton.setFocusable(false);
insertbutton.setBounds(300, 55, 90, 30);
userPanel.add(insertbutton);
updatabutton.setFocusable(false);
updatabutton.setBounds(300, 95, 90, 30);
userPanel.add(updatabutton);
}
然后是按钮的监听事件,也是数据库执行的地方了。 【查询很长,但是是因为我分类比较多,其实可以去掉一半的,但是程序员的代码往往不敢动。反正每一个if与else里都是相同的东西。甚至可以只看前两个。】
querybutton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("".equals(inputText.getText().toString()) ) {
if(statusChoice.isSelected()){
try {
sqlView.setText(new DBSqlite().querystatusandname(inputText.getText().toString()));
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}else{
try {
sqlView.setText(new DBSqlite().queryname(inputText.getText().toString()));
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
else {
if(statusChoice.isSelected()){
try {
sqlView.setText(new DBSqlite().querystatusandname(inputText.getText().toString()));
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}else{
try {
sqlView.setText(new DBSqlite().queryname(inputText.getText().toString()));
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
});
删除比较简单,就是获得输入的字符串然后调用删除就行了。
deletebutton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("".equals(inputText.getText().toString()) ) {
ShowUtils.warningMessage("请输入要删除的书籍名!");
} else {
sqlView.setText(new DBSqlite().deletesql(inputText.getText().toString())) ;
}
}
});
更新我这里只贴一段,就是输入名字点击更新按钮,可以把状态改成相反的状态。if语句块是进入了另一个页面了,另一个页面是输入旧信息和新信息,后台把所有查到的名字或者位置都更新。
updatabutton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("".equals(inputText.getText().toString()) ) {
try {
new updateFrame().setVisible(true);
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
}
}else{
try {
sqlView.setText(new DBSqlite().updatastatus(inputText.getText()));
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
});
插入的是调用串口的那一段代码,前面已经写过。 基本上就这些吧 还有8u101的jdk和sqlite的jar包
https://pan.baidu.com/s/1pzKIT0ZNBxiHRMcq01iJTg#list/path=%2F 提取码:xega
|