zsh_root
2025-01-06 7857a444de69124e9f7fb45f98b0ae818b107f23
国产UWB扫描器上位机V1.1
首次提交
已添加42个文件
已修改1个文件
4452 ■■■■■ 文件已修改
.gitignore 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
image/scan.png 补丁 | 查看 | 原始文档 | blame | 历史
image/warn.png 补丁 | 查看 | 原始文档 | blame | 历史
lib/RXTXcomm.jar 补丁 | 查看 | 原始文档 | blame | 历史
src/Anchor/Anchor.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Anchor/anchor_Dell.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/META-INF/MANIFEST.MF 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Baowen.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_55AA03.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_55AA34.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_55AA39.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_55AA40.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_Baowen.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_uanshi_byt.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/Dell_udpReceive.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/WriteReadAnchor.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/baowen/YuanshiByt.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/GCUWBreadIndex.java 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/JPanelMoudle/ComMoudleComp.java 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/JPanelMoudle/anchorListComp.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/JPanelMoudle/readParamsComp.java 361 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/JPanelMoudle/showDataComp.java 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/JPanelMoudle/versionUpgradeComp.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/Timer100.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index/homeMain.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/AutoCloseDialog.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ChuanKou/CRC16.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ChuanKou/SerialPortManager.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ChuanKou/SerialPortParameter.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ChuanKou/SerialPortUtil.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ChuanKou/Xmodem.java 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/CustomProgressBar.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/GetNowTime.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/Jiaoyan.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/Judge/JugeIn.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/Judge/JugeNumber.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/ShowMessage.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/Tools.java 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/ymodem/CRC16.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/ymodem/YModemUpgradeThread.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/ymodem/getFilesDataBytes.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/ymodem/netWorkUpgradeThread.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/ymodem/ymodem.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -9,3 +9,5 @@
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
/.idea
/out
image/scan.png
image/warn.png
lib/RXTXcomm.jar
Binary files differ
src/Anchor/Anchor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package Anchor;
public class Anchor {
    String anchorId;//信标ID
    String distance;//测距距离
    public String getAnchorId() {
        return anchorId;
    }
    public String getDistance() {
        return distance;
    }
    public void setAnchorId(String anchorId) {
        this.anchorId = anchorId;
    }
    public void setDistance(String distance) {
        this.distance = distance;
    }
}
src/Anchor/anchor_Dell.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package Anchor;
import java.util.Vector;
public class anchor_Dell {
     static Vector<Anchor> anchors=new Vector<>();
    static int id=1001;
    static int dis=1001;
     public anchor_Dell(){
         for (int i = 0; i < 50; i++) {
             id++;
             dis++;
             addAnchor(id+"",dis+"");
         }
     }
     public static Anchor findAnchor(String anchorId){
         for (Anchor anchor : anchors) {
             String anchorId1 = anchor.getAnchorId();
             if (anchorId1.equals(anchorId)){
                 return anchor;
             }
         }
         return null;
     }
     public static void addAnchor(String anchorId,String Distance){
         Anchor anchor = findAnchor(anchorId);
         if (anchor==null){
             Anchor anchor1=new Anchor();
             anchor1.setAnchorId(anchorId);
             anchor1.setDistance(Distance);
             anchors.add(anchor1);
         }else {
             anchor.setDistance(Distance);
         }
     }
    public static Vector<Anchor> getAnchors() {
        return anchors;
    }
}
src/META-INF/MANIFEST.MF
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: index.homeMain
src/baowen/Baowen.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package baowen;
public class Baowen {
String hex;
String ip;
String addtime;
int port;
String dataFrom;//数据来源    0:原始数据,1:拆包数据,-1:未知
    public String getDataFrom() {
        return dataFrom;
    }
    public void setDataFrom(String dataFrom) {
        this.dataFrom = dataFrom;
    }
    public int getPort() {
    return port;
}
public void setPort(int port) {
    this.port = port;
}
int  timestamp;
public String getHex() {
    return hex;
}
public String getIp() {
    return ip;
}
public String getAddtime() {
    return addtime;
}
public int getTimestamp() {
    return timestamp;
}
public void setHex(String hex) {
    this.hex = hex;
}
public void setIp(String ip) {
    this.ip = ip;
}
public void setAddtime(String addtime) {
    this.addtime = addtime;
}
public void setTimestamp(int timestamp) {
    this.timestamp = timestamp;
}
}
src/baowen/Dell_55AA03.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package baowen;
import index.JPanelMoudle.versionUpgradeComp;
import tools.Tools;
public class Dell_55AA03 {
    private static String[] hex = null;
    public static void dell(String ip, String message, int port) {
        String infom[] = message.split("55AA");
        int size = infom.length;
        for (int i = 0; i < size; i++) {
            String mes = "55AA" + infom[i];
            String[] hex = Tools.hex(message);
            if (hex.length < 30) {
                return;
            }
            String type = Tools.decodeHEX(hex[20] + hex[19]) + "";
            if (type.equals("3")) {
                dell05(ip, message, port);
            }
        }
    }
    public static void dell05(String ip, String message, int port) {
        String[] infoArray = message.split("55AA");
        int size = infoArray.length;
        for (int i = 0; i < size; i++) {
            String hexMessage = "55AA" + infoArray[i];
            if (isValidMessage(hexMessage)) {
                ok_55AA05(ip, hexMessage, port);
            }
        }
    }
    private static boolean isValidMessage(String hexMessage) {
        return hexMessage.startsWith("55AA0355") && hexMessage.length() == 178;
    }
    public static void ok_55AA05(String ip, String hexMessage, int port) {
        hexMessage = hexMessage.substring(14, hexMessage.length());
        hex = Tools.hex(hexMessage);
        String firmwareVersion = "V" + Integer.parseInt(hex[1], 16) + "." + Integer.parseInt(hex[0], 16);
        versionUpgradeComp.getReadVersion_jf().setText(firmwareVersion);
    }
}
src/baowen/Dell_55AA34.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package baowen;
import index.JPanelMoudle.readParamsComp;
import index.JPanelMoudle.versionUpgradeComp;
import tools.ShowMessage;
import tools.Tools;
import java.math.BigInteger;
//标签心跳包
public class Dell_55AA34 {
    static String[] hex;//字节数组
    static String ip;
    static int port;
//55AA3403240000
    public static void dellrgs( String ip1,String infom, int port1) {
        String jinDu="";//升级进度
        ip = ip1;
        port = port1;
        hex = Tools.hex(infom);
        if (hex.length>3) {
            int datalenth1 = Tools.decodeHEX(hex[3]);//数据长度
            datalenth1 = datalenth1 * 2 + 8;
            int lenth = infom.length();
            if (lenth == datalenth1) {
                int i = decodeHEX(hex[4]);
                String tagid="-----";
                if (hex[3].equals("05")){
                    tagid = hex[6] + hex[5];
                }
                String anchorID = readParamsComp.getAnchorId_jf().getText();
                if (tagid.equals(anchorID)||tagid.equals("-----")){
                    versionUpgradeComp.getUpdateAnchor_jf().setValue(i);
                }
                if (i==100||i==99){//设备升级进度达到100或者99时
                    ShowMessage.zidingyi("信标升级完成");
                    versionUpgradeComp.exitUpgradeXinBiao();
                }
            }
        }
    }
    /**16进制转为10进制*/
    public static int decodeHEX(String hexs){
        BigInteger bigint=new BigInteger(hexs, 16);
        int numb=bigint.intValue();
        return numb;
    }
}
src/baowen/Dell_55AA39.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package baowen;
import index.JPanelMoudle.readParamsComp;
import tools.GetNowTime;
import tools.ShowMessage;
import tools.Tools;
/**
 * åŸºç«™çš„配置信息
 */
public class Dell_55AA39 {
    public static boolean readpeizhi_succ = false;
    static String[] hex = null;
    static String[] hex1 = null;
    /**
     * 55 AA 39 55 03 01 50 00 01 01 90 E8 03 0A 00 05 00 E1 FF 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 71 04 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 43 00 02 00 78 00 01 00 00 00 01 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 A9 FA
     */
    public static void dell(String ip, String message, int port) {
        hex = Tools.hex(message);//原始数据
        int length = message.length();
        int size = Tools.decodeHEX(hex[3]);
        int length2 = (size * 2) + 8;
        if (length2 == length) {
            ok_55AA39(ip, message, port, hex);
        } else {
            Dell_uanshi_byt.intsert(ip, message, GetNowTime.timestamp2(), GetNowTime.timestamp(), port);
        }
    }
    @SuppressWarnings("unused")
    public static void ok_55AA39(String ip, String message, int port, String[] hex) {
        String hex1 = hex[8];
        //读写标签
        if (hex1.equals("02")) {
            rwTag(ip, message, port,hex);
        } else if (hex1.equals("12") || hex1.equals("11")) {
            rwAnc(ip, message, port, hex1);
        }
    }
    //读写基站配置
    private static void rwAnc(String ip, String message, int port, String hexr0w) {
        String message1 = message.substring(22);
        hex1 = Tools.hex(message1);//原始数据
        String ancId = null;       //基站ID
        String version = null;     //基站版本
        String cejuNum = null;     //测距基站数量
        String sendTime = null;    //uwb信号发送时间
        String loraGongLv = null;  //lora发射功率
        String uwbGongLv = null;   //uwb功率
        String gatewayId = null;   //uwb功率
        if (hexr0w.equals("11")){
            System.out.println("修改基站成功");
        }else {
            try {
                gatewayId = hex[7] + hex[6];//网关ID
                version = "V" + Integer.parseInt(hex1[1], 16) + "." + Integer.parseInt(hex1[0], 16);//版本号
                ancId = diZhi(2);//基站ID
                cejuNum = Tools.decodeHEX(diZhi(5)) + "";//组ID
                loraGongLv = getLoraGonglV(6);//lora功率
                sendTime = Tools.decodeHEX(diZhi(10)) + "";//发送时间
                uwbGongLv = Tools.decodeHEX(diZhi(27)) + "";//uwb功率
            } catch (NumberFormatException e) {
                ShowMessage.zidingyi_24("信标返回参数错误");
                return;
            }
        }
    }
    //读写标签回复
    private static void rwTag(String ip, String message, int port,String[] hex) {
        String message1 = message.substring(22);
        hex1 = Tools.hex(message1);//原始数据
        String tagid = null;//模块ID
        String version = null;//版本号
        String groupId = null;//小组ID
        String distance = null;//lora功率
        String uwbGongLv = null;//uw功率
        try {
            version = "V" + Integer.parseInt(hex1[1], 16) + "." + Integer.parseInt(hex1[0], 16);//版本号
            tagid = diZhi(2);//标签ID
            groupId = Tools.decodeHEX(diZhi(5)) + "";//小组ID
            distance = Tools.decodeHEX(diZhi(6))+"";//校准距离
            uwbGongLv = Tools.decodeHEX(diZhi(27)) + "";//UWB功率
            readParamsComp.getAnchorId_jf().setText(tagid);
            readParamsComp.getAnchorVersion_jf().setText(version);
            readParamsComp.getGroupId_jf().setText(groupId);
            readParamsComp.getAnchorPower_jf().setText(uwbGongLv);
            readParamsComp.getJiaoZhunDis_jf().setText(distance);
        } catch (NumberFormatException e) {
            ShowMessage.zidingyi_24("信标参数错误...");
            return;
        }
    }
    private static String getLoraGonglV(int addr) {
        String loraGongl="-1";
        int loraPower = Tools.decodeHEX(diZhi(addr));
        byte loraPower1 = (byte) loraPower;
        loraGongl = loraPower1 + "";
        return loraGongl;
    }
    public static String diZhi(int addr) {
        String s = hex1[(addr * 2) - 1] + hex1[(addr * 2) - 2];
        return s;
    }
}
src/baowen/Dell_55AA40.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package baowen;
import Anchor.anchor_Dell;
import tools.GetNowTime;
import tools.Tools;
public class Dell_55AA40 {
    static String[] hex;//字节数组
    static int[] distance;//获取距离的集合
    static String[] anchorid;//获取基站的集合
    public static void dellrgs(String ip,String message,  int port) {
        message = message.replaceAll("\r\n|\r|\n", "");//取出所有換行和回车
        int lenth = message.length();
        hex = Tools.hex(message);//原始数据
        //int datalenth1 = Tools.decodeHEX(hex[3]);//数据长度
      /*  datalenth1 = datalenth1 * 2 + 8;
        if (lenth == datalenth1) {*/
            String baoTou = diZhi(2);//包头
            int anchorNum = Tools.decodeHEXToInt8(hex[3]);
            get_anchorids(anchorNum);
            get_distance_int(anchorNum);
            addAnchor(anchorNum);
      /*  }else {
            Dell_uanshi_byt.intsert(ip, message, GetNowTime.timestamp2(), GetNowTime.timestamp(), port);
        }*/
    }
    //添加基站对象
    private static void addAnchor(int anchorNum) {
        for (int i = 0; i < anchorNum; i++) {
            String anchorID = anchorid[i];
            int dis = distance[i];
            anchor_Dell.addAnchor(anchorID,dis+"");
        }
    }
    //获取基站的ID集合
    public static void get_anchorids(int anchornum) {
        anchorid = new String[anchornum];
        for (int i = 0; i < anchornum; i++) {
            anchorid[i] = hex[5 + i * 2] + hex[4 + i * 2];
        }
    }
    //获取测距距离
    public static void get_distance_int(int anchornum) {
        int dis1 = anchornum * 2 +4 ;
        int dis2 = dis1 + 1;
        distance = new int[anchornum];
        for (int j = 0; j < anchornum; j++) {
            distance[j] = Tools.decodeHEXToInt8( hex[dis2 + j * 2] + hex[dis1 + j * 2]);
        }
    }
    public static String diZhi(int addr) {
        String s = hex[(addr * 2) - 1] + hex[(addr * 2) - 2];
        return s;
    }
}
src/baowen/Dell_Baowen.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package baowen;
import tools.GetNowTime;
import java.util.Vector;
public class Dell_Baowen implements Runnable {
    static Thread t;
    static Vector<Baowen> baowenvec = new Vector<Baowen>();
    static int sleeptime = 1;
    public void startThread() {
        t = new Thread(this);
        t.start();
    }
    public static void intsert(String ip, String hex, String time, int port) {
        Baowen baowen = new Baowen();
        baowen.setHex(hex);
        baowen.setIp(ip);
        baowen.setAddtime(time);
        baowen.setTimestamp(GetNowTime.timestamp());
        baowen.setPort(port);
        baowenvec.add(baowen);
    }
    public void run() {
        while (true) {
            try {
                dellhex();
                Thread.sleep(sleeptime);//休眠时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void dellhex() {
        int size = baowenvec.size();
        if (size == 0) {
            sleeptime = 10;
            return;
        }
        if (size > 100000) {//如果数据大于10万条没有处理则清空
            baowenvec.removeAllElements();
        } else {
            sleeptime = 0;
            Baowen baowen0 = baowenvec.get(0);
            String ip = baowen0.getIp();
            int port = baowen0.getPort();
            String hex = baowen0.getHex();
            String time = baowen0.getAddtime();
            int timestamp = baowen0.getTimestamp();
            int lenth = hex.length();
            try {
                dellhex2(ip, port, hex, time, timestamp, lenth);//处理原始数据
            } catch (Exception e) {
                e.printStackTrace();
            }
            baowenvec.remove(baowen0);//删除处理过的报文
        }
    }
    public static void dellhex2(String ip, int port, String hex, String time, int timestamp, int lenth) {
        if (hex.startsWith("55AA39")) {
            Dell_55AA39.dell(ip, hex,port);
        }else if (hex.startsWith("55AA40")){
            Dell_55AA40.dellrgs(ip, hex,port);
        }else if (hex.startsWith("55AA03")){
            Dell_55AA03.dell(ip, hex,port);
        }else if (hex.startsWith("55AA34")){
            Dell_55AA34.dellrgs(ip, hex,port);
        }else {
            Dell_uanshi_byt.intsert(ip, hex, time, timestamp, port);
        }
    }
}
src/baowen/Dell_uanshi_byt.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,187 @@
package baowen;
import tools.Jiaoyan;
import tools.Judge.JugeNumber;
import tools.ShowMessage;
import java.math.BigInteger;
import java.util.Vector;
/**
 * å¤„理原始数据
 */
public class Dell_uanshi_byt {
    static Vector<YuanshiByt> yuanshivec = new Vector<>();
    /**
     * æ’入原始测距数据,每个ip一个集合每个IP上来的数据装入各自IP之中
     */
    public static void intsert(String ip, String hex, String time, int timestamp, int port) {
        if (get_ys(ip) != null) {
            int lenth = hex.length() / 2;
            for (int i = 0; i < lenth; i++) {
                String hex1 = hex.substring(2 * i, (i + 1) * 2);
                get_ys(ip).getData().add(hex1);
                hex1 = null;
            }
            get_ys(ip).setTime(time);
            get_ys(ip).setTimestamp(timestamp);
            dell_ysbyt(get_ys(ip), ip, port);
        } else {
            YuanshiByt ysbyt = new YuanshiByt();
            Vector<String> data1 = new Vector<>();
            StringBuffer okhex = new StringBuffer();
            ysbyt.setIp(ip);
            ysbyt.setPort(port);
            ysbyt.setData(data1);
            ysbyt.setTimestamp(timestamp);
            ysbyt.setTime(time);
            ysbyt.setUsart_state(0);
            ysbyt.setPack(okhex);
            ysbyt.setDatalen(0);
            ysbyt.setType("");
            int lenth = hex.length() / 2;
            for (int i = 0; i < lenth; i++) {
                String hex1 = hex.substring(2 * i, (i + 1) * 2);
                data1.add(hex1);
                hex1 = null;
            }
            yuanshivec.add(ysbyt);
            dell_ysbyt(ysbyt, ip, port);
        }
    }
    /**
     * é€šè¿‡IP找到该IP的数据集合
     */
    public static YuanshiByt get_ys(String ip) {
        YuanshiByt ysbyt = null;
        int size = yuanshivec.size();
        for (int i = 0; i < size; i++) {
            YuanshiByt ysbyt1 = yuanshivec.get(i);
            String ip1 = ysbyt1.getIp();
            if (ip1.equals(ip)) {
                ysbyt = ysbyt1;
                break;
            }
        }
        return ysbyt;
    }
    /**
     * å¤„理原始集合中的数据
     */
    public static void dell_ysbyt(YuanshiByt ysbyt, String ip, int port) {
        String time = ysbyt.getTime();
        int timestamp = ysbyt.getTimestamp();
        while (ysbyt.getData().size() > 0) {
            String hex = null;
            try {
                hex = ysbyt.getData().get(0);
            } catch (ArrayIndexOutOfBoundsException e) {
                return;
            }
            int usart_state = ysbyt.getUsart_state();
            //将原始数据集合中的第一条数据取出放入swich循环
            switch (usart_state) {
                case 0:
                    //如果数据是55则执行
                    if (hex.equals("55")) {
                        //将数据处理的状态修改为1
                        ysbyt.setUsart_state(1);
                        //同时插入数据在字符串中
                        ysbyt.getPack().append(hex);
                    }
                    break;
                case 1:
                    //如果数据是AA则执行
                    if (hex.equals("AA")) {//状态1情况下,等待接收到AA包头2,然后变成状态2
                        ysbyt.setUsart_state(2);
                        ysbyt.getPack().append(hex);
                    }
                    break;
                case 2:
                    //数据类型给TYPE
                    ysbyt.setType(hex);
                    ysbyt.setUsart_state(3);
                    ysbyt.getPack().append(hex);
                    break;
                case 3:
                    //报文数据段数据长度
                    boolean a1 = JugeNumber.isLetterDigit(hex);
                    int d = 0;
                    if (a1) {
                        BigInteger bigint = new BigInteger(hex, 16);
                        d = bigint.intValue();
                    } else {
                        ShowMessage.zidingyi("HEX to DEC error:" + hex);
                        ysbyt.getPack().setLength(0);
                        ysbyt.setType("");
                        ysbyt.setUsart_state(0);
                        break;
                    }
                    ysbyt.getPack().append(hex);
                    ysbyt.setUsart_state(4);
                    ysbyt.setDatalen(d);
                    break;
                case 4:
                    ysbyt.getPack().append(hex);
                    int lenth = ysbyt.getPack().toString().length();
                    int a = ysbyt.getDatalen() * 2 + 8;
                    if (lenth == a) {
                        //数据处理的状态
                        ysbyt.setUsart_state(0);
                        //校验
                        String check = Jiaoyan.check2(ysbyt.getPack().toString());
                        String panck_cmd = null;
                        try {
                            panck_cmd = ysbyt.getPack().toString().substring(lenth - 2, lenth) + ysbyt.getPack().substring(lenth - 4, lenth - 2);
                        } catch (Exception e) {
                            return;
                        }
                        //如果校验成功
                        if (check.equals(panck_cmd)) {
                            //如果是测距数据
                            String type = ysbyt.getType();
                            switch (type) {
                                case "39":
                                    Dell_55AA39.dell(ip, ysbyt.getPack().toString(), port);
                                    break;
                                case "40":
                                    Dell_55AA40.dellrgs(ip, ysbyt.getPack().toString(), port);
                                    break;
                            }
                        }
                        ysbyt.getPack().setLength(0);
                        ysbyt.setDatalen(0);
                        ysbyt.setType("");
                    } else if (lenth > a) {
                        ysbyt.getPack().setLength(0);
                        ysbyt.setDatalen(0);
                        ysbyt.setType("");
                    }
                    break;
            }
            //删除处理过的数据
            ysbyt.getData().removeElement(hex);
        }
    }
}
src/baowen/Dell_udpReceive.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
package baowen;
import tools.GetNowTime;
import tools.Tools;
import java.io.IOException;
import java.net.*;
public class Dell_udpReceive implements Runnable{
    int port=7000;
    static DatagramSocket socket;
    static int bytlenth=1024;
    static DatagramPacket packet;
    static boolean startFlag=false;
    private static Thread receiveThread;
    public Dell_udpReceive(int port1){
        try {
            startFlag=true;
            port=port1;
            socket = new DatagramSocket(port);
            byte[] data = new byte[bytlenth]; // åˆ›å»ºbyte数组
            packet= new DatagramPacket(data,bytlenth);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }
    /**启动线程的方法*/
    public void startThread() {
        receiveThread = new Thread(this);
        receiveThread.start();
    }
    @Override
    public void run() {
        while(startFlag) {
            getdata();
        }
    }
    public  void getdata() {
        if (socket != null) {
            try {
                socket.receive(packet); // æŽ¥æ”¶æ•°æ®åŒ…
                delludp_receive(packet);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public static void delludp_receive(DatagramPacket packet) {
        int lenth=packet.getLength();
        byte[] byt=subBytes(packet.getData(),0, lenth);
        String ip=packet.getAddress().getHostAddress();//获取发送端的IP地址对象
        int port=packet.getPort();
        String datas = Tools.Bytes2HexString(byt);//串口来的数据
        Dell_Baowen.intsert(ip, datas, GetNowTime.timestamp2(), port);
    }
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }
    /**将数据发给基站*/
    public static void sendData(byte[] data,String ip2,int port2) {
        if(socket==null) {
            return;
        }
        String datas1=Tools.Bytes2HexString(data);
        DatagramPacket packet=null;
        InetAddress address=null;
        //如果数据类型相同
        try {
            address=InetAddress.getByName(ip2);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        packet=new DatagramPacket(data, data.length, address, port2);
        try {
            socket.send(packet);
            String datas=Tools.Bytes2HexString(data).substring(0, packet.getLength()*2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /** åœæ­¢çº¿ç¨‹å¹¶é‡Šæ”¾èµ„源 */
    public static void stop() {
        if (receiveThread != null && receiveThread.isAlive()) {
            try {
                receiveThread.join();  // ç­‰å¾…线程结束
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    public static void stopThread() {
        startFlag = false;//停止数据接收
        if (socket != null && !socket.isClosed()) {
            socket.close();//关闭socket对象
        }
        stop();
    }
}
src/baowen/WriteReadAnchor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
package baowen;
import gnu.io.SerialPort;
import index.JPanelMoudle.showDataComp;
import tools.ChuanKou.SerialPortUtil;
import tools.Jiaoyan;
import tools.Tools;
public class WriteReadAnchor {
    //给扫描器发送指令
    public static void updateLora(String zhi,
                                  byte diZhi,
                                  byte duxie,
                                  String anchorID,
                                  SerialPort serialPort,
                                  byte lenth) {
        byte[] write = write_loraAnc(diZhi,lenth ,duxie, Integer.parseInt(zhi),anchorID);
        if (write == null) {
            return;
        }
        sendData(serialPort, write);
    }
    public static void sendData(SerialPort serialPort, byte[] write) {
        SerialPortUtil.sendData(serialPort,write);
        showDataComp.addSendAreaTextMes(write);
    }
    /**@param start èµ·å§‹åœ°å€
     * @param lenth数据长度
     * @param value[]具体的值*/
    private static byte[] write_loraAnc(byte start ,byte lenth,byte duXie,int value,String id) {
        byte[] buf =new byte[12+lenth];
        byte[] buf1 =new byte[8+lenth];
        //包头
        buf[0]=(byte) 0x55;
        //包头
        buf[1]=(byte) 0xAA;
        //指令类型
        buf1[0]=(byte) 0x30;
        //数据长度
        buf1[1]=(byte) ((byte) 8+lenth);
        //读模式
        buf1[2]=(byte) duXie;
        //起始地址
        buf1[3]=(byte) start;
        buf1[4]= Tools.toByteArray(id)[1];
        buf1[5]=Tools.toByteArray(id)[0];
        buf1[6]=Tools.toByteArray(id)[1];
        buf1[7]=Tools.toByteArray(id)[0];
        buf1[8]=Tools.intToRegisters(value)[3];
        buf1[9]=Tools.intToRegisters(value)[2];
        for(int i=0;i<buf1.length;i++) {
            buf[i+2]=buf1[i];
        }
        //校验码
        buf[buf.length-2]= Jiaoyan.check(buf1)[1];
        buf[buf.length-1]=Jiaoyan.check(buf1)[0];
        return buf;
    }
    //读取扫描器版本
    public static byte[] ReadData(byte ref, byte lenth) {
        byte[] buf = new byte[10];
        byte[] buf1 = new byte[6];
        //包头
        buf[0] = (byte) 0x55;
        //包头
        buf[1] = (byte) 0xAA;
        //指令类型(参数读写模式)
        buf1[0] = (byte) 0x03;
        //数据长度
        buf1[1] = (byte) 0x06;
        //读模式(读模式)
        buf1[2] = (byte) 0x01;
        //起始地址
        buf1[3] = ref;
        //数据长度
        buf1[4] = lenth;
        //固定值(读模式下为0x00)
        buf1[5] = (byte) 0x00;
        for (int i = 0; i < buf1.length; i++) {
            buf[i + 2] = buf1[i];
        }
        //校验码
        buf[8] = Jiaoyan.check(buf1)[1];
        buf[9] = Jiaoyan.check(buf1)[0];
        ;
        return buf;
    }
    /**@param start èµ·å§‹åœ°å€
     * @param lenth数据长度
     * @param value[]具体的值*/
    public static byte[] write_lora(byte start ,byte lenth,int value) {
        byte[] buf =new byte[9+lenth];
        byte[] buf1 =new byte[5+lenth];
        //包头
        buf[0]=(byte) 0x55;
        //包头
        buf[1]=(byte) 0xAA;
        //指令类型
        buf1[0]=(byte) 0x03;
        //数据长度
        buf1[1]=(byte) ((byte) 5+lenth);
        //读模式
        buf1[2]=(byte) 0x02;
        //起始地址
        buf1[3]=(byte) start;
        //读写长度
        buf1[4]=(byte) lenth;
        buf1[5]=Tools.intToRegisters(value)[3];
        buf1[6]=Tools.intToRegisters(value)[2];
        for(int i=0;i<buf1.length;i++) {
            buf[i+2]=buf1[i];
        }
        //校验码
        buf[buf.length-2]=Jiaoyan.check(buf1)[1];
        buf[buf.length-1]=Jiaoyan.check(buf1)[0];
        return buf;
    }
}
src/baowen/YuanshiByt.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package baowen;
import java.util.Vector;
/**原始数据*/
public class YuanshiByt {
    String time;
    int timestamp;
    int port;
    String ip;
    Vector<String> data;
    StringBuffer pack;
    int datalen;//数据的长度
    String type;//数据类型
    //处理数据到什么状态了
    int usart_state;
    public String getIp() {
        return ip;
    }
    public Vector<String> getData() {
        return data;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public void setData(Vector<String> data) {
        this.data = data;
    }
    public StringBuffer getPack() {
        return pack;
    }
    public void setPack(StringBuffer pack) {
        this.pack = pack;
    }
    public String getTime() {
        return time;
    }
    public int getTimestamp() {
        return timestamp;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public void setTimestamp(int timestamp) {
        this.timestamp = timestamp;
    }
    public int getUsart_state() {
        return usart_state;
    }
    public void setUsart_state(int usart_state) {
        this.usart_state = usart_state;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public int getDatalen() {
        return datalen;
    }
    public void setDatalen(int datalen) {
        this.datalen = datalen;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
}
src/index/GCUWBreadIndex.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
package index;
import index.JPanelMoudle.*;
import java.awt.*;
import javax.swing.*;
/**
 * @author zsh
 */
public class GCUWBreadIndex extends JFrame {
    static ImageIcon icon = new ImageIcon("image/scan.png"); // è¯·æ›¿æ¢ä¸ºä½ å›¾æ ‡çš„路径
    public GCUWBreadIndex() {
        // èŽ·å–å±å¹•çš„åˆ†è¾¨çŽ‡
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        Rectangle screenBounds = gd.getDefaultConfiguration().getBounds();
        int screenWidth = screenBounds.width;
        int screenHeight = screenBounds.height;
        // æ ¹æ®å±å¹•尺寸调整窗口大小
        setSize(screenWidth / 2, screenHeight / 2);  // è®¾ç½®çª—口为屏幕尺寸的一半
        setLocationRelativeTo(null);  // å±…中显示窗口
        // çª—口属性
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("GC UWB信标扫描软件V1.2");
        setIconImage(icon.getImage());
        initComponents();
    }
    private void initComponents() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Container contentPane = getPane();
        anchor_TableList(contentPane);
        readComList(contentPane);
        readWriteAnchorParams(contentPane);
        DataShow(contentPane);
        versionUpgrade(contentPane);
        pack();
        setLocationRelativeTo(getOwner());
    }
    //选择串口界面
    private void readComList(Container contentPane) {
        ComMoudleComp.getCom_jp().setLayout(new GridBagLayout());
        int[] columnWidths = {110, 110, 220};
        int[] rowHeights = {46, 46, 0, 46};
        double[] columnWeights = {1.0, 1.0, 1.0};
        double[] rowWeights = {1.0, 1.0, 1.0, 1.0};
        //设置布局器的参数
        setGridBagLayoutParams(ComMoudleComp.getCom_jp(), columnWidths, rowHeights, columnWeights, rowWeights);
        // æ·»åŠ ç»„ä»¶
        addLabelAndField(ComMoudleComp.getCom_jp(), ComMoudleComp.getChuanKou_jl(), ComMoudleComp.getChuanKou_jcom(), 0, 0,2);
        addLabelAndField(ComMoudleComp.getCom_jp(), ComMoudleComp.getBotelv_jl(), ComMoudleComp.getBoteLV_jcm(), 0, 1,2);
        // æ·»åŠ æŒ‰é’®
        addButton(ComMoudleComp.getCom_jp(), ComMoudleComp.getOpen(), 0, 3, 2, 1);
        addButton(ComMoudleComp.getCom_jp(), ComMoudleComp.getClose(), 2, 3, 1, 1);
        // æœ€åŽå°†å®¹å™¨æ·»åŠ åˆ° contentPane
        contentPane.add(ComMoudleComp.getCom_jp(),
                new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 5), 0, 0));
    }
    //信标列表模块
    private void anchor_TableList(Container contentPane) {
        anchorListComp.getAncList_jp().setLayout(new GridBagLayout());
        int[] columnWidths = {449, 0};
        int[] rowHeights = {480, 50, 0};
        double[] columnWeights = {1.0, 1.0E-4};
        double[] rowWeights = {1.0, 0.0, 1.0E-4};
        // è®¾ç½® GridBagLayout é…ç½®
        setGridBagLayoutParams(anchorListComp.getAncList_jp(), columnWidths, rowHeights, columnWeights, rowWeights);
        // æ·»åŠ ç»„ä»¶
        addScrollPane(anchorListComp.getAncList_jp(), anchorListComp.getScrollPane1(), anchorListComp.getAncTable(), 0, 0, 1, 1);
        addButton(anchorListComp.getAncList_jp(), anchorListComp.getSelect_anc(), 0, 1, 1, 1);
        // æœ€åŽå°†å®¹å™¨æ·»åŠ åˆ° contentPane
        contentPane.add(anchorListComp.getAncList_jp(),
                new GridBagConstraints(0, 1, 1, 2, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 0, 5), 0, 0));
    }
    //固件升级界面
    private void versionUpgrade(Container contentPane) {
        versionUpgradeComp.getVersionUpdate().setLayout(new GridBagLayout());
        int[] columnWidths = {143, 350, 0};
        int[] rowHeights = {38, 54, 50, 58, 54, 0};
        double[] columnWeights = {1.0, 1.0, 1.0};
        double[] rowWeights = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
        // è®¾ç½® GridBagLayout é…ç½®
        setGridBagLayoutParams(versionUpgradeComp.getVersionUpdate(), columnWidths, rowHeights, columnWeights, rowWeights);
        addLabelAndField(versionUpgradeComp.getVersionUpdate(), versionUpgradeComp.getLabel9(), versionUpgradeComp.getLabel9(), 0, 0,2);
        addLabelAndField(versionUpgradeComp.getVersionUpdate(), versionUpgradeComp.getReadVersion_jb(), versionUpgradeComp.getReadVersion_jf(), 0, 1,2);
        addLabelAndField(versionUpgradeComp.getVersionUpdate(), versionUpgradeComp.getChooseVersion(), versionUpgradeComp.getChooseVersion_jf(), 0, 2,2);
        addLabelAndField(versionUpgradeComp.getVersionUpdate(), versionUpgradeComp.getWrite_saoMiao(), versionUpgradeComp.getJindu_SaoMiaoQi(), 0, 3,2);
        addLabelAndField(versionUpgradeComp.getVersionUpdate(), versionUpgradeComp.getUpdateAnchor_jb(), versionUpgradeComp.getUpdateAnchor_jf(), 0, 4,2);
        // æ·»åŠ åˆ° contentPane
        contentPane.add(versionUpgradeComp.getVersionUpdate(), new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 0, 5), 0, 0));
    }
    //读写参数模块
    private void readWriteAnchorParams(Container contentPane) {
        readParamsComp.getReadAncParam_jp().setLayout(new GridBagLayout());
        int[] columnWidths = {139, 124*2,30, 160, 0};//每列的宽度
        int[] rowHeights = {50, 50, 50, 50, 50, 50, 50, 50, 50, 0};//每行的高度
        double[] columnWeights = {1.0, 1.0, 1.0,1.0, 0};
        double[] rowWeights = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0};
        // è®¾ç½® GridBagLayout é…ç½®
        setGridBagLayoutParams(readParamsComp.getReadAncParam_jp(), columnWidths, rowHeights, columnWeights, rowWeights);
        // æ·»åŠ ç»„ä»¶
        addLabelAndField(readParamsComp.getReadAncParam_jp(), readParamsComp.getAnchorId(), readParamsComp.getAnchorId_jf(), 0, 1,3);
        addLabelAndField(readParamsComp.getReadAncParam_jp(), readParamsComp.getAnchorVersion(), readParamsComp.getAnchorVersion_jf(), 0, 2,3);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getGroupId(), readParamsComp.getGroupId_jf(),  readParamsComp.getSaveParam_GroupID(),0, 3);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getAnchorPower(), readParamsComp.getAnchorPower_jf(), readParamsComp.getSaveParam_anchorPower(),0, 4);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getJiaoZhunDis(), readParamsComp.getJiaoZhunDis_jf(), readParamsComp.getSaveParam_jiaoZhunDis(),0, 5);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getLabel6(), readParamsComp.getTextField6(), readParamsComp.getSaveParam_label6(),0, 6);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getLabel7(), readParamsComp.getTextField7(),readParamsComp.getSaveParam_label7(), 0, 7);
        addLabelAndFieldAndButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getLabel8(), readParamsComp.getTextField8(), readParamsComp.getSaveParam_label8(),0, 8);
        // æ·»åŠ æŒ‰é’®
        addButton(readParamsComp.getReadAncParam_jp(), readParamsComp.getReadParam(), 0, 0, 4, 1);
        // æœ€åŽå°†å®¹å™¨æ·»åŠ åˆ° contentPane
        contentPane.add(readParamsComp.getReadAncParam_jp(),
                new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 5), 0, 0));
    }
    //数据接收解析模块
    private void DataShow(Container contentPane) {
        showDataComp.getDataShow().setViewportView(showDataComp.getTextArea1());
        contentPane.add(showDataComp.getDataShow(),
                new GridBagConstraints(2, 0, 1, 3, 0.0, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 0), 0, 0));
    }
    // ç®€åŒ–的标签和输入框添加方法
    private void addLabelAndField(Container panel, JComponent label, JComponent textField, int gridx, int gridy,int width) {
        panel.add(label, new GridBagConstraints(gridx, gridy, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 5), 0, 0));
        panel.add(textField, new GridBagConstraints(gridx + 1, gridy,  width,1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 0), 0, 0));
    }
    // ç®€åŒ–的标签和输入 æŒ‰é’®æ·»åŠ æ–¹æ³•
    private void addLabelAndFieldAndButton(Container panel, JComponent label, JComponent textField, JComponent button,int gridx, int gridy) {
        panel.add(label, new GridBagConstraints(gridx, gridy, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 5), 0, 0));
        panel.add(textField, new GridBagConstraints(gridx + 1, gridy, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 0), 0, 0));
        panel.add(button, new GridBagConstraints(gridx + 3, gridy, 1, 1, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 0), 0, 0));
    }
    // ç®€åŒ–的按钮添加方法
    private void addButton(Container panel, JButton button, int gridx, int gridy, int gridwidth, int gridheight) {
        panel.add(button, new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 0), 0, 0));
    }
    // æ·»åŠ  JScrollPane çš„æ–¹æ³•
    private void addScrollPane(Container panel, JScrollPane scrollPane, JTable table, int gridx, int gridy, int gridwidth, int gridheight) {
        scrollPane.setViewportView(table);
        panel.add(scrollPane, new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 0.0, 0.0,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 5, 0), 0, 0));
    }
    //全局页面
    private Container getPane() {
        Container contentPane = getContentPane();
        contentPane.setLayout(new GridBagLayout());
        // è®¾ç½®é€‚应窗口大小的布局
        ((GridBagLayout) contentPane.getLayout()).columnWidths = new int[]{0, 504, 374, 0}; // å¯ä»¥è°ƒæ•´å®½åº¦
        ((GridBagLayout) contentPane.getLayout()).rowHeights = new int[]{170, 268, 315, 0}; // å¯ä»¥è°ƒæ•´é«˜åº¦
        // è®¾ç½®ä¼¸ç¼©æƒé‡ï¼Œç¡®ä¿å†…容在窗口放大时自适应
        ((GridBagLayout) contentPane.getLayout()).columnWeights = new double[]{1.0, 1.0, 1.0, 1.0E-4};
        ((GridBagLayout) contentPane.getLayout()).rowWeights = new double[]{1.0, 1.0, 1.0, 1.0E-4};
        return contentPane;
    }
    private void setGridBagLayoutParams(JPanel jPanel, int[] columnWidths, int[] rowHeights, double[] columnWeights, double[] rowWeights) {
        GridBagLayout layout = (GridBagLayout) jPanel.getLayout();
        layout.columnWidths = columnWidths;
        layout.rowHeights = rowHeights;
        layout.columnWeights = columnWeights;
        layout.rowWeights = rowWeights;
    }
    public static void startFrame(){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GCUWBreadIndex().setVisible(true);
            }
        });
    }
}
src/index/JPanelMoudle/ComMoudleComp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,216 @@
package index.JPanelMoudle;
import Anchor.anchor_Dell;
import baowen.Dell_Baowen;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import tools.ChuanKou.SerialPortManager;
import tools.ChuanKou.SerialPortUtil;
import tools.GetNowTime;
import tools.ShowMessage;
import tools.Tools;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.TooManyListenersException;
public class ComMoudleComp {
    private static JPanel com_jp;//选择串口模板
    private static JLabel chuanKou_jl;//串口号标签
    private static JLabel botelv_jl;//波特率标签
    private static JComboBox chuanKou_jcom;//串口号下拉框
    private static JComboBox boteLV_jcm;//波特率下拉框
    private static JButton open;//打开串口按钮
    private static JButton close;//关闭串口按钮
    static String[] coms = null;
    static String com = null;//选中的串口
    static boolean chuankou = false;//串口是否被打开
    static SerialPort serialPort = null;//串口对象
    // èŽ·å–é€‰æ‹©ä¸²å£é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JPanel getCom_jp() {
        if (com_jp == null) {
            com_jp = new JPanel();  // åˆå§‹åŒ–该面板
            com_jp.setBorder(new TitledBorder("选择串口"));
        }
        return com_jp;
    }
    // èŽ·å– ä¸²å£å·æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getChuanKou_jl() {
        if (chuanKou_jl == null) {
            chuanKou_jl = new JLabel(" ä¸²å£å·ï¼š");  // åˆå§‹åŒ–该标签
        }
        return chuanKou_jl;
    }
    // èŽ·å–æ³¢ç‰¹çŽ‡æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getBotelv_jl() {
        if (botelv_jl == null) {
            botelv_jl = new JLabel(" æ³¢ç‰¹çŽ‡ï¼š");  // åˆå§‹åŒ–该标签
        }
        return botelv_jl;
    }
    // èŽ·å– ä¸²å£å·ä¸‹æ‹‰æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JComboBox getChuanKou_jcom() {
        if (chuanKou_jcom == null) {
            chuanKou_jcom = new JComboBox();  // åˆå§‹åŒ–该下拉框
            chuanKou_jcom.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent e) {
                    int comnum = SerialPortManager.get_all_port().size();
                    if (coms.length != comnum) {
                        coms = new String[SerialPortManager.get_all_port().size()];
                        for (int i = 0; i < SerialPortManager.get_all_port().size(); i++) {
                            coms[i] = SerialPortManager.get_all_port().get(i);
                        }
                        ComboBoxModel<String> coModel = new DefaultComboBoxModel<>(coms);//下拉列表模型
                        chuanKou_jcom.setModel(coModel);
                    }
                }
                @Override
                public void focusLost(FocusEvent e) {
                }
            });
            if (SerialPortManager.get_all_port().size() != 0) {
                coms = new String[SerialPortManager.get_all_port().size()];
                for (int i = 0; i < SerialPortManager.get_all_port().size(); i++) {
                    coms[i] = SerialPortManager.get_all_port().get(i);
                }
            } else {
                coms = new String[1];
                coms[0] = "未识别到com口";
            }
            ComboBoxModel<String> coModel = new DefaultComboBoxModel<>(coms);//下拉列表模型
            chuanKou_jcom.setModel(coModel);
        }
        return chuanKou_jcom;
    }
    // èŽ·å–æ³¢ç‰¹çŽ‡ä¸‹æ‹‰æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JComboBox getBoteLV_jcm() {
        if (boteLV_jcm == null) {
            String[] com = {"115200", "921600", "19200", "9600"};
            boteLV_jcm = new JComboBox(com);  // åˆå§‹åŒ–该下拉框
        }
        return boteLV_jcm;
    }
    // èŽ·å– æ‰“开串口 æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getOpen() {
        if (open == null) {
            open = new JButton("打开串口");  // åˆå§‹åŒ–该按钮
            open.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    com = (String) chuanKou_jcom.getSelectedItem();
                    if (com == null || com.equals("未识别到com口")) {
                        ShowMessage.zidingyi("未识别到com口,请插入配置线并重启软件");
                        comshuaxin();
                        return;
                    }
                    int bote = Integer.parseInt((String) boteLV_jcm.getSelectedItem());
                    if (!chuankou) {
                        serialPort = SerialPortManager.open_chuankou(com, bote);
                        if (serialPort == null) {
                            return;
                        }
                        chuankou = true;//串口被打开
                        open.setEnabled(false);
                        close.setEnabled(true);
                        try {
                            SerialPortUtil.setListenerToSerialPort(serialPort, event -> {
                                //数据通知
                                if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                                    if (!versionUpgradeComp.isWrite()) {
                                        byte[] bytes = SerialPortUtil.readData(serialPort);
                                        if (bytes == null) {
                                            return;
                                        }
                                        showDataComp.addAreaTextMes(bytes,"127.0.0.1",8888);
                                    }
                                }
                            });
                        } catch (TooManyListenersException e1) {
                            // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
                            e1.printStackTrace();
                        }
                    } else {
                        ShowMessage.zidingyi("请先关闭已打开的串口");
                    }
                }
            });
        }
        return open;
    }
    // èŽ·å– å…³é—­ä¸²å£ æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getClose() {
        if (close == null) {
            close = new JButton("关闭串口");  // åˆå§‹åŒ–该按钮
            close.setEnabled(false);
            close.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (chuankou) {
                            SerialPortUtil.closeSerialPort(serialPort);
                            open.setEnabled(true);
                            close.setEnabled(false);
                            chuankou = false;
                            anchor_Dell.getAnchors().removeAllElements();//清空信标基站的集合
                            anchorListComp.updateTable();//清空信标列表
                        } else {
                            ShowMessage.zidingyi("串口未打开");
                        }
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
            });
        }
        return close;
    }
    //重新刷新串口
    public static void comshuaxin() {
        int comnum = SerialPortManager.get_all_port().size();
        if (comnum != 0) {
            coms = new String[SerialPortManager.get_all_port().size()];
            for (int i = 0; i < SerialPortManager.get_all_port().size(); i++) {
                coms[i] = SerialPortManager.get_all_port().get(i);
            }
        } else {
            coms = new String[1];
            coms[0] = "未识别到com口";
        }
        ComboBoxModel<String> coModel = new DefaultComboBoxModel<>(coms);//下拉列表模型
        chuanKou_jcom.setModel(coModel);
        chuanKou_jcom.repaint();
    }
    public static SerialPort getSerialPort() {
        return serialPort;
    }
    public static boolean isChuankou() {
        return chuankou;
    }
}
src/index/JPanelMoudle/anchorListComp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,199 @@
package index.JPanelMoudle;
import Anchor.Anchor;
import Anchor.anchor_Dell;
import tools.ShowMessage;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
public class anchorListComp {
    private static JPanel ancList_jp;//基站列表面板
    private static JTable ancTable;//基站列表
    private static DefaultTableModel model;//表格模型
    private static JButton select_anc;//扫描信标按钮
    private static JScrollPane scrollPane1;//解析数据滚动面板
    private static Vector<Vector<String>> rowData = null;
    private static Set<Anchor> existingIds = new HashSet<>();
    ;
    // èŽ·å– ancList_jp é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JPanel getAncList_jp() {
        if (ancList_jp == null) {
            ancList_jp = new JPanel();  // åˆå§‹åŒ–该面板
            ancList_jp.setBorder(new TitledBorder("信标列表"));
        }
        return ancList_jp;
    }
    public static JTable getAncTable() {
        if (ancTable == null) {
            String[] columnNames = {"设备ID", "测距距离(cm)"}; // è¡¨æ ¼åˆ—名
            Vector<String> columnName = new Vector<>();
            for (int i = 0; i < columnNames.length; i++) {
                columnName.add(columnNames[i]);
            }
            // è¡¨æ ¼åˆå§‹åŒ–
            ancTable = new JTable(rowData, columnName) {
                private static final long serialVersionUID = 1L;
                // ç¦æ­¢ç¼–辑
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
                // é‡å†™ prepareRenderer å®žçŽ°éš”è¡Œå˜è‰²
                @Override
                public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                    Component c = super.prepareRenderer(renderer, row, column);
                    // è®¾ç½®éš”行变色:偶数行为白色,奇数行为灰色
                    if (!isRowSelected(row)) {
                        if (row % 2 == 0) {
                            c.setBackground(new Color(240, 240, 240));  // å¶æ•°è¡Œç°è‰²
                        } else {
                            c.setBackground(Color.white);  // å¥‡æ•°è¡Œç™½è‰²
                        }
                    }
                    return c;
                }
            };
            ancTable.setColumnSelectionAllowed(false);
            ancTable.getTableHeader().setReorderingAllowed(false);
            // è®¾ç½®è¡¨æ ¼æ ·å¼
            setShowStyle();
            // è®¾ç½®åˆ—头样式
            ancTable.getTableHeader().setPreferredSize(new Dimension(ancTable.getTableHeader().getPreferredSize().width, 40));
            DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
            headerRenderer.setHorizontalAlignment(SwingConstants.CENTER);  // åˆ—头文字居中
            for (int i = 0; i < ancTable.getColumnCount(); i++) {
                ancTable.getColumnModel().getColumn(i).setHeaderRenderer(headerRenderer);
            }
            // è®¾ç½®è¡Œé«˜
            ancTable.setRowHeight(35);  // è®¾ç½®æ¯è¡Œçš„高度为35像素
            // èŽ·å–è¡¨æ ¼æ¨¡åž‹å¹¶åŠ è½½æ•°æ®
            model = (DefaultTableModel) ancTable.getModel();
            getRowData(anchor_Dell.getAnchors());
            ancTable.revalidate();
            ancTable.repaint();
        }
        return ancTable;
    }
    public static void getRowData(Vector<Anchor> s2_vector) {
        // éåŽ†æ–°æ•°æ®
        for (Anchor s2 : s2_vector) {
            String anchorId = s2.getAnchorId().trim();
            String newDistance = s2.getDistance().trim();
            boolean found = false;
            // éåŽ†çŽ°æœ‰æ¨¡åž‹ï¼Œåˆ¤æ–­æ˜¯å¦å­˜åœ¨ç›¸åŒçš„ AnchorId
            for (int i = 0; i < model.getRowCount(); i++) {
                String existingId = ((String) model.getValueAt(i, 0)).trim();
                String existingDistance = ((String) model.getValueAt(i, 1)).trim();
                if (existingId.equals(anchorId)) {
                    found = true;
                    // å¦‚果距离不同,更新模型
                    if (!existingDistance.equals(newDistance)) {
                        model.setValueAt(newDistance, i, 1); // æ›´æ–°è·ç¦»
                    }
                    break;
                }
            }
            // å¦‚果没有找到,添加新行
            if (!found) {
                Vector<String> row = new Vector<>();
                row.add(anchorId);
                row.add(newDistance);
                model.addRow(row);
            }
        }
    }
    // èŽ·å– select_anc æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSelect_anc() {
        if (select_anc == null) {
            select_anc = new JButton("扫描信标");  // åˆå§‹åŒ–该按钮
            select_anc.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (ComMoudleComp.isChuankou()) {
                        updateTable();
                        ShowMessage.zidingyi("正在重新扫描信标");
                    } else {
                        ShowMessage.zidingyi("请先打开串口");
                    }
                }
            });
        }
        return select_anc;
    }
    // èŽ·å– è§£æžæ•°æ®æ»šåŠ¨é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JScrollPane getScrollPane1() {
        if (scrollPane1 == null) {
            scrollPane1 = new JScrollPane();  // åˆå§‹åŒ–该滚动面板
        }
        return scrollPane1;
    }
    //设置表格显示风格
    private static void setShowStyle() {
        // èŽ·å–è¡¨æ ¼çš„åˆ—æ•°
        int columnCount = ancTable.getColumnCount();
        // åˆ›å»ºä¸€ä¸ªé»˜è®¤çš„单元格渲染器,用于居中显示
        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setHorizontalAlignment(SwingConstants.CENTER);
        // ä¸ºæ¯ä¸€åˆ—设置该渲染器
        for (int i = 0; i < columnCount; i++) {
            ancTable.getColumnModel().getColumn(i).setCellRenderer(renderer);
        }
        // ä¸ºåˆ—头设置居中渲染器
        DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
        headerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
        for (int i = 0; i < columnCount; i++) {
            // è®¾ç½®åˆ—头的渲染器
            ancTable.getTableHeader().getColumnModel().getColumn(i).setHeaderRenderer(headerRenderer);
        }
    }
    //刷新表格的方法
    public static void updateTable() {
        if (model != null) {
            // æ¸…空所有行
            existingIds.clear();
            model.setRowCount(0);
            anchor_Dell.getAnchors().removeAllElements();//删除所有信标
            getRowData(anchor_Dell.getAnchors());
            scrollPane1.validate();
        }
    }
    public static String getChooseAnchorId() {
        String anchorID = null;
        int selectedRow = anchorListComp.getAncTable().getSelectedRow();
        if (selectedRow != -1) {
            anchorID = (String) anchorListComp.getAncTable().getValueAt(selectedRow, 0);
        }
        return anchorID;
    }
}
src/index/JPanelMoudle/readParamsComp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,361 @@
package index.JPanelMoudle;
import baowen.WriteReadAnchor;
import tools.Judge.JugeIn;
import tools.ShowMessage;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class readParamsComp {
    private static JPanel readAncParam_jp;//读取信标配置面板
    private static JButton readParam;//读取参数按钮
    private static JLabel anchorId;//基站ID
    private static JLabel anchorVersion;//信标版本号
    private static JLabel groupId;//通讯小组
    private static JLabel anchorPower;//信标功率
    private static JLabel jiaoZhunDis;//校准距离
    private static JLabel label6;//保留参数1
    private static JLabel label7;//保留参数2
    private static JLabel label8;//保留参数3
    private static JTextField anchorId_jf;
    private static JTextField anchorVersion_jf;
    private static JTextField groupId_jf;
    private static JTextField anchorPower_jf;
    private static JTextField jiaoZhunDis_jf;
    private static JTextField textField6;
    private static JTextField textField7;
    private static JTextField textField8;
    private static JButton saveParam_groupId;
    private static JButton saveParam_anchorPower;
    private static JButton saveParam_jiaoZhunDis;
    private static JButton saveParam_label6;
    private static JButton saveParam_label7;
    private static JButton saveParam_label8;
    // èŽ·å– readAncParam_jp é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JPanel getReadAncParam_jp() {
        if (readAncParam_jp == null) {
            readAncParam_jp = new JPanel();  // åˆå§‹åŒ–该面板
            readAncParam_jp.setBorder(new TitledBorder("读写信标参数"));
        }
        return readAncParam_jp;
    }
    // èŽ·å– readParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getReadParam() {
        if (readParam == null) {
            readParam = new JButton("读取参数");  // åˆå§‹åŒ–该按钮
            readParam.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    String chooseAnchorId = anchorListComp.getChooseAnchorId();
                    if (chooseAnchorId != null) {
                        WriteReadAnchor.updateLora("0", (byte) 0x00, (byte) 0x02, chooseAnchorId, ComMoudleComp.getSerialPort(),(byte) 0x02);
                        ShowMessage.zidingyi(chooseAnchorId + ":读取指令已发送");
                    } else {
                        ShowMessage.zidingyi("请在信标列表中选中需要读取的设备");
                    }
                }
            });
        }
        return readParam;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_GroupID() {
        if (saveParam_groupId == null) {
            saveParam_groupId = new JButton("保存通讯小组");  // åˆå§‹åŒ–该按钮
            saveParam_groupId.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                    String zuId = getGroupId_jf().getText();//通讯小组
                    boolean groudID = JugeIn.shuru("通讯小组", zuId);
                    if (groudID){
                        WriteReadAnchor.updateLora(zuId, (byte) 0x0A, (byte) 0x01, ancID, ComMoudleComp.getSerialPort(),(byte) 0x02);
                    }
                }
            });
        }
        return saveParam_groupId;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_anchorPower() {
        if (saveParam_anchorPower == null) {
            saveParam_anchorPower = new JButton("保存信标功率");  // åˆå§‹åŒ–该按钮
            saveParam_anchorPower.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                    String power = getAnchorPower_jf().getText();//信标功率
                    boolean poweraAnc = JugeIn.shuru("信标功率", power);
                    if (poweraAnc){
                        WriteReadAnchor.updateLora(power, (byte) 0x36, (byte) 0x01, ancID, ComMoudleComp.getSerialPort(),(byte) 0x02);
                    }
                }
            });
        }
        return saveParam_anchorPower;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_jiaoZhunDis() {
        if (saveParam_jiaoZhunDis == null) {
            saveParam_jiaoZhunDis = new JButton("保存校准距离");  // åˆå§‹åŒ–该按钮
            saveParam_jiaoZhunDis.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                    String dis = getJiaoZhunDis_jf().getText();//校准距离
                    boolean distance = JugeIn.shuru("校准距离", dis);
                    if (distance){
                        WriteReadAnchor.updateLora(dis, (byte) 0x0C, (byte) 0x01, ancID, ComMoudleComp.getSerialPort(),(byte) 0x02);
                    }
                }
            });
        }
        return saveParam_jiaoZhunDis;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_label6() {
        if (saveParam_label6 == null) {
            saveParam_label6 = new JButton("保存参数");  // åˆå§‹åŒ–该按钮
            saveParam_label6.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                }
            });
        }
        return saveParam_label6;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_label7() {
        if (saveParam_label7 == null) {
            saveParam_label7 = new JButton("保存参数");  // åˆå§‹åŒ–该按钮
            saveParam_label7.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                }
            });
        }
        return saveParam_label7;
    }
    // èŽ·å– saveParam æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getSaveParam_label8() {
        if (saveParam_label8 == null) {
            saveParam_label8 = new JButton("保存参数");  // åˆå§‹åŒ–该按钮
            saveParam_label8.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!ComMoudleComp.isChuankou()) {
                        ShowMessage.zidingyi("请先打开串口");
                        return;
                    }
                    if (getAnchorId_jf().getText().length()!=4){
                        ShowMessage.zidingyi("信标ID不正确");
                        return;
                    }
                    String ancID = getAnchorId_jf().getText();//基站ID
                }
            });
        }
        return saveParam_label8;
    }
    // èŽ·å– label1 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getAnchorId() {
        if (anchorId == null) {
            anchorId = new JLabel("    ä¿¡æ ‡ID");  // åˆå§‹åŒ–该标签
        }
        return anchorId;
    }
    // èŽ·å– label2 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getAnchorVersion() {
        if (anchorVersion == null) {
            anchorVersion = new JLabel("    ä¿¡æ ‡ç‰ˆæœ¬å·");  // åˆå§‹åŒ–该标签
        }
        return anchorVersion;
    }
    // èŽ·å– label3 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getGroupId() {
        if (groupId == null) {
            groupId = new JLabel("    é€šè®¯å°ç»„");  // åˆå§‹åŒ–该标签
        }
        return groupId;
    }
    // èŽ·å– label4 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getAnchorPower() {
        if (anchorPower == null) {
            anchorPower = new JLabel("    ä¿¡æ ‡åŠŸçŽ‡");  // åˆå§‹åŒ–该标签
        }
        return anchorPower;
    }
    // èŽ·å– label5 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getJiaoZhunDis() {
        if (jiaoZhunDis == null) {
            jiaoZhunDis = new JLabel("    æ ¡å‡†è·ç¦»");  // åˆå§‹åŒ–该标签
        }
        return jiaoZhunDis;
    }
    // èŽ·å– label6 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getLabel6() {
        if (label6 == null) {
            label6 = new JLabel("    ä¿ç•™å‚æ•°1");  // åˆå§‹åŒ–该标签
        }
        return label6;
    }
    // èŽ·å– label7 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getLabel7() {
        if (label7 == null) {
            label7 = new JLabel("    ä¿ç•™å‚æ•°2");  // åˆå§‹åŒ–该标签
        }
        return label7;
    }
    // èŽ·å– label8 æ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getLabel8() {
        if (label8 == null) {
            label8 = new JLabel("    ä¿ç•™å‚æ•°3");  // åˆå§‹åŒ–该标签
        }
        return label8;
    }
    // èŽ·å– textField1 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getAnchorId_jf() {
        if (anchorId_jf == null) {
            anchorId_jf = new JTextField();  // åˆå§‹åŒ–该文本框
            anchorId_jf.setEnabled(false);
        }
        return anchorId_jf;
    }
    // èŽ·å– textField2 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getAnchorVersion_jf() {
        if (anchorVersion_jf == null) {
            anchorVersion_jf = new JTextField();  // åˆå§‹åŒ–该文本框
            anchorVersion_jf.setEnabled(false);
        }
        return anchorVersion_jf;
    }
    // èŽ·å– textField3 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getGroupId_jf() {
        if (groupId_jf == null) {
            groupId_jf = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return groupId_jf;
    }
    // èŽ·å– textField4 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getAnchorPower_jf() {
        if (anchorPower_jf == null) {
            anchorPower_jf = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return anchorPower_jf;
    }
    // èŽ·å– textField5 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getJiaoZhunDis_jf() {
        if (jiaoZhunDis_jf == null) {
            jiaoZhunDis_jf = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return jiaoZhunDis_jf;
    }
    // èŽ·å– textField6 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getTextField6() {
        if (textField6 == null) {
            textField6 = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return textField6;
    }
    // èŽ·å– textField7 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getTextField7() {
        if (textField7 == null) {
            textField7 = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return textField7;
    }
    // èŽ·å– textField8 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getTextField8() {
        if (textField8 == null) {
            textField8 = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return textField8;
    }
}
src/index/JPanelMoudle/showDataComp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,158 @@
package index.JPanelMoudle;
import baowen.Dell_Baowen;
import tools.GetNowTime;
import tools.Tools;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.nio.charset.Charset;
public class showDataComp {
    private static JScrollPane dataShow;//解析数据滚动面板
    private static JTextArea textArea1;
    private static JPopupMenu popupMenu;//右键菜单列表
    static boolean time=true;//显示时间戳
    static boolean ascll=false;//ascll显示
    // èŽ·å– textArea1 æ–‡æœ¬åŒºï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextArea getTextArea1() {
        if (textArea1 == null) {
            textArea1 = new JTextArea();  // åˆå§‹åŒ–该文本区
            textArea1.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    maybeShowPopup(e);
                }
                @Override
                public void mouseReleased(MouseEvent e) {
                    maybeShowPopup(e);
                }
                // æ˜¾ç¤ºå³é”®èœå•
                private void maybeShowPopup(MouseEvent e) {
                    if (e.isPopupTrigger()) {  // åˆ¤æ–­æ˜¯å¦æ˜¯å³é”®ç‚¹å‡»
                        getPopupMenu().show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            });
        }
        return textArea1;
    }
    // èŽ·å– è§£æžæ•°æ®æ»šåŠ¨é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JScrollPane getDataShow() {
        if (dataShow == null) {
            dataShow = new JScrollPane();  // åˆå§‹åŒ–该滚动面板
            dataShow.setBorder(new TitledBorder("接收数据解析"));
        }
        return dataShow;
    }
    public static JPopupMenu getPopupMenu(){
        if (popupMenu == null) {
            popupMenu = new JPopupMenu();
            popupMenu.setBackground(new Color(245, 245, 245));  // è®¾ç½®èœå•背景色
            popupMenu.setFont(new Font("Segoe UI", Font.PLAIN, 14)); // è®¾ç½®å­—体
            // åŠ¨æ€è®¡ç®—èœå•é¡¹çš„æ–‡æœ¬
            String showAscll = ascll ? "HEX显示" : "ASCLL显示";
            String noShowtime = time ? "隐藏时间戳" : "显示时间戳";
            // åˆ›å»ºèœå•项
            JMenuItem clear = new JMenuItem("清空窗口");
            JMenuItem ascllShow = new JMenuItem(showAscll);
            JMenuItem timeNoShow = new JMenuItem(noShowtime);
            // æ·»åŠ åŠ¨ä½œç›‘å¬å™¨
            clear.addActionListener(e -> textArea1.setText(""));
            ascllShow.addActionListener(e -> setAscll());
            timeNoShow.addActionListener(e -> setTimeShow());
            // é¼ æ ‡æ‚¬åœæ—¶æ”¹å˜èƒŒæ™¯é¢œè‰²
            clear.addMouseListener(createMouseAdapter(clear));
            ascllShow.addMouseListener(createMouseAdapter(ascllShow));
            timeNoShow.addMouseListener(createMouseAdapter(timeNoShow));
            // æ·»åŠ èœå•é¡¹åˆ°èœå•
            popupMenu.add(clear);
            popupMenu.addSeparator();
            popupMenu.add(ascllShow);
            popupMenu.addSeparator();
            popupMenu.add(timeNoShow);
        } else {
            // å¦‚æžœpopupMenu已经创建,更新菜单项
            // åŠ¨æ€æ›´æ–°èœå•é¡¹æ–‡æœ¬
            ((JMenuItem) popupMenu.getComponent(2)).setText(ascll ? "HEX显示" : "ASCLL显示");
            ((JMenuItem) popupMenu.getComponent(4)).setText(time ? "隐藏时间戳" : "显示时间戳");
        }
        return popupMenu;
    }
    // é¼ æ ‡æ‚¬åœæ—¶æ”¹å˜èƒŒæ™¯é¢œè‰²çš„通用方法
    private static MouseAdapter createMouseAdapter(JMenuItem item) {
        return new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                item.setBackground(new Color(220, 220, 220)); // è®¾ç½®æ‚¬åœæ—¶çš„颜色
            }
            @Override
            public void mouseExited(MouseEvent e) {
                item.setBackground(new Color(240, 240, 240)); // æ¢å¤æ­£å¸¸é¢œè‰²
            }
        };
    }
    public static void addAreaTextMes(byte[] Datas,String ip,int port) {
        String message = ascll ? new String(Datas, Charset.forName("GBK")): Tools.Bytes2HexString(Datas);
        if (time) {
            getTextArea1().append(GetNowTime.timestamp2() + ":收←" + message + "\n");
        }else {
            getTextArea1().append( message + "\n");
        }
        if (port!=9999) {
            Dell_Baowen.intsert(ip, message, GetNowTime.timestamp2(), port);
        }
        // èŽ·å–æ–‡æœ¬åŒºåŸŸçš„é•¿åº¦ï¼ˆå³æœ€åŽä¸€è¡Œçš„ç»“æŸä½ç½®ï¼‰
        int length = textArea1.getDocument().getLength();
        // è®¾ç½®å…‰æ ‡ä½ç½®åˆ°æ–‡æœ¬çš„æœ«å°¾
        textArea1.setCaretPosition(length);
    }
    public static void addSendAreaTextMes(byte[] Datas){
        String message = ascll ? new String(Datas, Charset.forName("GBK")): Tools.Bytes2HexString(Datas);
        if (time) {
            getTextArea1().append(GetNowTime.timestamp2()+":发→"+message+"\n");
        }else {
            getTextArea1().append( message + "\n");
        }
        // èŽ·å–æ–‡æœ¬åŒºåŸŸçš„é•¿åº¦ï¼ˆå³æœ€åŽä¸€è¡Œçš„ç»“æŸä½ç½®ï¼‰
        int length = textArea1.getDocument().getLength();
        // è®¾ç½®å…‰æ ‡ä½ç½®åˆ°æ–‡æœ¬çš„æœ«å°¾
        textArea1.setCaretPosition(length);
    }
    public static void setTimeShow(){
        if (time){
            time=false;
        }else {
            time=true;
        }
    }
    public static void setAscll(){
        if (ascll){
            ascll=false;
        }else {
            ascll=true;
        }
    }
}
src/index/JPanelMoudle/versionUpgradeComp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,228 @@
package index.JPanelMoudle;
import baowen.WriteReadAnchor;
import gnu.io.SerialPort;
import tools.ChuanKou.SerialPortUtil;
import tools.CustomProgressBar;
import tools.ShowMessage;
import ymodem.getFilesDataBytes;
import ymodem.YModemUpgradeThread;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
public class versionUpgradeComp {
    private static JPanel  versionUpdate;//版本升级面板
    private static JLabel label9;//空标签,进行占位
    private static JTextField readVersion_jf;//读取扫描器版本文本框
    private static JTextField chooseVersion_jf;//选择固件文本框
    private static JButton chooseVersion;//选择固件按钮
    private static JButton write_saoMiao;//写入扫描器按钮
    public static boolean write=false;//写入扫描器按钮
    public static boolean xinBiaoUp=false;//升级信标版本按钮
    private static JButton readVersion_jb;//读取版本按钮
    private static JButton  updateAnchor_jb;//升级信标版本按钮
    private static CustomProgressBar jindu_SaoMiaoQi;//写入扫描器进度条
    private static CustomProgressBar updateAnchor_jf;//升级信标版本进度条
    private static YModemUpgradeThread upgradeThread; // ä¿å­˜çº¿ç¨‹å¼•用
    private static Color color = new Color(6, 176, 37);; // ä¿å­˜çº¿ç¨‹å¼•用
    // èŽ·å–ç‰ˆæœ¬å‡çº§é¢æ¿ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JPanel getVersionUpdate() {
        if (versionUpdate == null) {
            versionUpdate = new JPanel();  // åˆå§‹åŒ–该面板
            versionUpdate.setBorder(new TitledBorder("固件升级"));
        }
        return versionUpdate;
    }
    // èŽ·å–ç©ºæ ‡ç­¾ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JLabel getLabel9() {
        if (label9 == null) {
            label9 = new JLabel();  // åˆå§‹åŒ–该标签
        }
        return label9;
    }
    // èŽ·å– é€‰æ‹©å›ºä»¶ æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getChooseVersion() {
        if (chooseVersion == null) {
            chooseVersion = new JButton("选择固件");  // åˆå§‹åŒ–该按钮
            chooseVersion.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // æ‰“开文件选择对话框
                    String currentDirectory = System.getProperty("user.dir");
                    JFileChooser fileChooser = new JFileChooser();
                    // è®¾ç½®æ–‡ä»¶é€‰æ‹©å¯¹è¯æ¡†ä¸ºå¯é€‰æ‹©æ–‡ä»¶
                    fileChooser.setDialogTitle("选择固件");
                    fileChooser.setCurrentDirectory(new File(currentDirectory));
                    int result = fileChooser.showOpenDialog(readParamsComp.getReadAncParam_jp());
                    if (result == JFileChooser.APPROVE_OPTION) {
                        // å¦‚果用户选择了文件
                        File selectedFile = fileChooser.getSelectedFile();
                        // æ˜¾ç¤ºé€‰æ‹©çš„æ–‡ä»¶è·¯å¾„
                        getChooseVersion_jf().setText(selectedFile.getPath());//文件名称);
                    }
                }
            });
        }
        return chooseVersion;
    }
    // èŽ·å– å†™å…¥æ‰«æå™¨ æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getWrite_saoMiao() {
        if (write_saoMiao == null) {
            write_saoMiao = new JButton("写入扫描器");  // åˆå§‹åŒ–该按钮
            write_saoMiao.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(!write) {
                        String filePath = getChooseVersion_jf().getText();
                        if (!ComMoudleComp.isChuankou()) {
                            ShowMessage.zidingyi("串口未识别");
                            return;
                        }
                        if (filePath == null || filePath.length() < 10) {
                            ShowMessage.zidingyi("固件不正确");
                            return;
                        }
                        SerialPort serialPort = ComMoudleComp.getSerialPort();
                        write = true;
                        byte[] bytes = WriteReadAnchor.write_lora((byte) 0x10, (byte) 0x2, 1);
                        YModemUpgradeThread.shengji(serialPort,filePath,bytes);
                        write_saoMiao.setText("取消写入");
                        jindu_SaoMiaoQi.setStringPainted(true); // æ˜¾ç¤ºç™¾åˆ†æ¯”文字
                    }else {
                       YModemUpgradeThread.setSendDataFlag(true);
                        exitUpgrade();
                    }
                }
            });
        }
        return write_saoMiao;
    }
    // èŽ·å– è¯»å–扫描器版本 æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getReadVersion_jb() {
        if (readVersion_jb == null) {
            readVersion_jb = new JButton("读取扫描器版本");  // åˆå§‹åŒ–该按钮
            readVersion_jb.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                        if (!ComMoudleComp.isChuankou()) {
                            ShowMessage.zidingyi("串口未识别");
                            return;
                        }
                        ShowMessage.zidingyi("读取扫描器版本指令发送成功");
                        byte[] byt = WriteReadAnchor.ReadData((byte) 0x2, (byte) 0x50);
                        WriteReadAnchor.sendData(ComMoudleComp.getSerialPort(), byt);
                }
            });
        }
        return readVersion_jb;
    }
    // èŽ·å– å‡çº§ä¿¡æ ‡ç‰ˆæœ¬ æŒ‰é’®ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JButton getUpdateAnchor_jb() {
        if (updateAnchor_jb == null) {
            updateAnchor_jb = new JButton("升级信标版本");  // åˆå§‹åŒ–该按钮
            updateAnchor_jb.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!xinBiaoUp) {
                        if (!ComMoudleComp.isChuankou()) {
                            ShowMessage.zidingyi("串口未识别");
                            return;
                        }
                        String text = readParamsComp.getAnchorId_jf().getText();
                        if (text.length() != 4) {
                            ShowMessage.zidingyi("信标ID不正确,请先读取信标参数");
                            return;
                        }
                        SerialPort serialPort = ComMoudleComp.getSerialPort();
                        xinBiaoUp=true;
                        updateAnchor_jb.setText("退出信标升级");
                        WriteReadAnchor.updateLora("0", (byte) 0xAA,(byte)  0x06, text,serialPort,(byte) 0x02);
                    }else {
                        exitUpgradeXinBiao();
                    }
                }
            });
        }
        return updateAnchor_jb;
    }
    // èŽ·å– è¯»å–扫描器版本 æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getReadVersion_jf() {
        if (readVersion_jf == null) {
            readVersion_jf = new JTextField();  // åˆå§‹åŒ–该文本框
        }
        return readVersion_jf;
    }
    // èŽ·å– é€‰æ‹©å›ºä»¶ æ–‡æœ¬æ¡†ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static JTextField getChooseVersion_jf() {
        if (chooseVersion_jf == null) {
            chooseVersion_jf = new JTextField();  // åˆå§‹åŒ–该文本框
            chooseVersion_jf.setEnabled(false);
        }
        return chooseVersion_jf;
    }
    // èŽ·å– å†™å…¥æ‰«æå™¨ è¿›åº¦æ¡ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static CustomProgressBar  getJindu_SaoMiaoQi() {
        if (jindu_SaoMiaoQi == null) {
            jindu_SaoMiaoQi = new CustomProgressBar();  // åˆå§‹åŒ–该进度条
            jindu_SaoMiaoQi.setForeground(color); // è®¾ç½®è¿›åº¦æ¡å‰æ™¯è‰²ä¸ºç»¿è‰²
            // è‡ªå®šä¹‰UI来修改文本颜色
        }
        return jindu_SaoMiaoQi;
    }
    // èŽ·å– å‡çº§ä¿¡æ ‡ç‰ˆæœ¬ è¿›åº¦æ¡ï¼Œè‹¥ä¸ºç©ºåˆ™åˆ›å»º
    public static CustomProgressBar getUpdateAnchor_jf() {
        if (updateAnchor_jf == null) {
            updateAnchor_jf = new CustomProgressBar();  // åˆå§‹åŒ–该进度条
            updateAnchor_jf.setForeground(color); // è®¾ç½®è¿›åº¦æ¡å‰æ™¯è‰²ä¸ºç»¿è‰²
        }
        return updateAnchor_jf;
    }
    public static boolean isWrite() {
        return write;
    }
    public static void exitUpgrade() {
        write=false;
        write_saoMiao.setText("写入扫描器");
        jindu_SaoMiaoQi.setValue(0); // æ˜¾ç¤ºç™¾åˆ†æ¯”文字
    }
    public static void exitUpgradeXinBiao() {
        xinBiaoUp=false;
        updateAnchor_jb.setText("升级信标版本");
        updateAnchor_jf.setValue(0); // æ˜¾ç¤ºç™¾åˆ†æ¯”文字
    }
}
src/index/Timer100.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package index;
import Anchor.anchor_Dell;
import index.JPanelMoudle.ComMoudleComp;
import index.JPanelMoudle.anchorListComp;
import java.util.Timer;
import java.util.TimerTask;
public class Timer100 {
    Timer timer;
    int time=0;
    public  void ding_shi_qi() {
        Integer cacheTime = 100;//触发器时间100毫秒执行一次
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    time++;
                    if (time==10){
                        if (ComMoudleComp.isChuankou()) {
                            anchorListComp.getRowData(anchor_Dell.getAnchors());
                        }else {
                            anchorListComp.updateTable();//清空信标列表
                        }
                        time=0;
                    }
                } catch (Exception e) {
                    // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
                    e.printStackTrace();
                }
            }
        }, 100, cacheTime);
    }
}
src/index/homeMain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package index;
import Anchor.anchor_Dell;
import baowen.Dell_Baowen;
import javax.swing.*;
public class homeMain {
    public static void main(String[] args) {
        new Dell_Baowen().startThread();//启动报文解析线程
        System.setProperty("sun.java2d.dpi", "96"); // è®¾ç½®DPI值为96(标准DPI)
        GCUWBreadIndex.startFrame();//启动图形化界面
        new Timer100().ding_shi_qi();//100毫秒定时器
    }
}
src/tools/AutoCloseDialog.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package tools;
/**自动关闭的对话框*/
import javax.swing.*;
import java.util.Timer;
import java.util.TimerTask;
public class AutoCloseDialog {
    static ImageIcon icon = new ImageIcon("image/warn.png"); // è¯·æ›¿æ¢ä¸ºä½ å›¾æ ‡çš„路径
    /**3秒钟消失的对话框*/
    public static JOptionPane getDialog(String message) {
        JOptionPane op = new JOptionPane(message,
                JOptionPane.INFORMATION_MESSAGE);
        op.setIcon(icon);
        final JDialog dialog = op.createDialog("提示信息, 2秒后自动关闭!");
        // åˆ›å»ºä¸€ä¸ªæ–°è®¡æ—¶å™¨
        Timer timer = new Timer();
        // 3秒后执行该任务
        timer.schedule(new TimerTask() {
            public void run() {
                dialog.setVisible(false);
                dialog.dispose();
            }
        }, 2000);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setAlwaysOnTop(true);
        dialog.setModal(false);
        dialog.setVisible(true);
        dialog.setIconImage(icon.getImage());
        return op;
    }
    /**24h消失的对话框*/
    public static JOptionPane getDialogno(String message) {
        JOptionPane op = new JOptionPane(message,JOptionPane.INFORMATION_MESSAGE);
        op.setIcon(icon);
        final JDialog dialog = op.createDialog("提示信息!");
        // åˆ›å»ºä¸€ä¸ªæ–°è®¡æ—¶å™¨
        Timer timer = new Timer();
        // 24小时后后执行该任务
        timer.schedule(new TimerTask() {
            public void run() {
                dialog.setVisible(false);
                dialog.dispose();
            }
        }, 86400000);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setAlwaysOnTop(true);
        dialog.setModal(false);
        dialog.setVisible(true);
        dialog.setIconImage(icon.getImage());
        return op;
    }
}
src/tools/ChuanKou/CRC16.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package tools.ChuanKou;
/**
 * CRC16校验
 *
 * @author yangle
 */
public class CRC16 {
    private static final char crctable[] = { 0x0000, 0x1021, 0x2042, 0x3063,
            0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
            0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252,
            0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a,
            0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
            0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509,
            0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630,
            0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
            0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7,
            0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af,
            0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
            0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e,
            0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
            0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
            0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4,
            0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc,
            0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
            0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
            0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da,
            0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
            0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589,
            0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481,
            0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
            0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0,
            0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f,
            0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
            0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e,
            0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16,
            0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
            0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45,
            0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c,
            0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
            0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 };
    public static char calc(byte[] bytes) {
        char crc = 0x0000;
        for (byte b : bytes) {
            crc = (char) ((crc << 8) ^ crctable[((crc >> 8) ^ b) & 0x00ff]);
        }
        return (char) (crc);
    }
}
src/tools/ChuanKou/SerialPortManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package tools.ChuanKou;
import gnu.io.*;
import tools.ShowMessage;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class SerialPortManager {
    static Enumeration<CommPortIdentifier> portList;
    static CommPortIdentifier portId;
    /**
     * åˆ—出本地连接的所有串口名称集合
     * @param args
     */
    @SuppressWarnings("unchecked")//告诉编译器忽略 unchecked è­¦å‘Šä¿¡æ¯ï¼Œå¦‚使用List,ArrayList等未进行参数化产生的警告信息。
    public static List<String> get_all_port(){
        List<String> all_port=new ArrayList<String>();
        portList = CommPortIdentifier.getPortIdentifiers();
        while(portList.hasMoreElements()){
            portId = (CommPortIdentifier)portList.nextElement();
            if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
                all_port.add(portId.getName());
            }
        }
        return all_port;
    }
    /**打开串口
     * @param chuankou ä¸²å£å·
     * @param botelv æ³¢ç‰¹çއ*/
    public static SerialPort open_chuankou(String chuankou,int botelv) {
        SerialPort serialPort=null;
        try {
        serialPort =SerialPortUtil.openSerialPort(chuankou,botelv);
        } catch (NoSuchPortException e) {
            // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
            ShowMessage.zidingyi(chuankou+"不存在!");
        } catch (PortInUseException e) {
            // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
            ShowMessage.zidingyi(chuankou+"已被占用!");
        } catch (UnsupportedCommOperationException e) {
            // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
            ShowMessage.zidingyi(chuankou+"不支持操作!");
        }
        return serialPort;
    }
}
src/tools/ChuanKou/SerialPortParameter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
package tools.ChuanKou;
import gnu.io.SerialPort;
/**
 * @name: SerialPortParameter
 * @author: tuacy.
 * @date: 2019/6/26.
 * @version: 1.0
 * @Description: ä¸²å£å‚æ•°
 */
public final class SerialPortParameter {
    /**
     * ä¸²å£åç§°(COM0、COM1、COM2等等)
     */
    private String serialPortName;
    /**
     * æ³¢ç‰¹çއ
     * é»˜è®¤ï¼š115200
     */
    private int baudRate;
    /**
     * æ•°æ®ä½ é»˜è®¤8位
     * å¯ä»¥è®¾ç½®çš„值:SerialPort.DATABITS_5、SerialPort.DATABITS_6、SerialPort.DATABITS_7、SerialPort.DATABITS_8
     * é»˜è®¤ï¼šSerialPort.DATABITS_8
     */
    private int dataBits;
    /**
     * åœæ­¢ä½
     * å¯ä»¥è®¾ç½®çš„值:SerialPort.STOPBITS_1、SerialPort.STOPBITS_2、SerialPort.STOPBITS_1_5
     * é»˜è®¤ï¼šSerialPort.STOPBITS_1
     */
    private int stopBits;
    /**
     * æ ¡éªŒä½
     * å¯ä»¥è®¾ç½®çš„值:SerialPort.PARITY_NONE、SerialPort.PARITY_ODD、SerialPort.PARITY_EVEN、SerialPort.PARITY_MARK、SerialPort.PARITY_SPACE
     * é»˜è®¤ï¼šSerialPort.PARITY_NONE
     */
    private int parity;
    public SerialPortParameter(String serialPortName) {
        this.serialPortName = serialPortName;
        this.baudRate = 115200;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }
    public SerialPortParameter(String serialPortName, int baudRate) {
        this.serialPortName = serialPortName;
        this.baudRate = baudRate;
        this.dataBits = SerialPort.DATABITS_8;
        this.stopBits = SerialPort.STOPBITS_1;
        this.parity = SerialPort.PARITY_NONE;
    }
    public String getSerialPortName() {
        return serialPortName;
    }
    public void setSerialPortName(String serialPortName) {
        this.serialPortName = serialPortName;
    }
    public int getBaudRate() {
        return baudRate;
    }
    public void setBaudRate(int baudRate) {
        this.baudRate = baudRate;
    }
    public int getDataBits() {
        return dataBits;
    }
    public void setDataBits(int dataBits) {
        this.dataBits = dataBits;
    }
    public int getStopBits() {
        return stopBits;
    }
    public void setStopBits(int stopBits) {
        this.stopBits = stopBits;
    }
    public int getParity() {
        return parity;
    }
    public void setParity(int parity) {
        this.parity = parity;
    }
}
src/tools/ChuanKou/SerialPortUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,306 @@
package tools.ChuanKou;
import gnu.io.*;
import index.JPanelMoudle.ComMoudleComp;
import tools.ShowMessage;
import tools.Tools;
import javax.tools.Tool;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;
/**
 * @name: SerialPortUtil
 * @author: tuacy.
 * @date: 2019/6/26.
 * @version: 1.0
 * @Description: ä¸²å£å·¥å…·ç±»
 */
@SuppressWarnings("unused")
public class SerialPortUtil {
    /**
     * èŽ·å¾—ç³»ç»Ÿå¯ç”¨çš„ç«¯å£åç§°åˆ—è¡¨(COM0、COM1、COM2等等)
     *
     * @return List<String>可用端口名称列表
     */
       // è¾“入流
    private static InputStream inputStream;
    // è¾“出流
    private static OutputStream outputStream;
    private static String data;
    // ä¿å­˜ä¸²å£è¿”回信息十六进制
    private static String dataHex;
    @SuppressWarnings("unchecked")
    public static List<String> getSerialPortList() {
        List<String> systemPorts = new ArrayList<>();
        //获得系统可用的端口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();//获得端口的名字
            systemPorts.add(portName);
        }
        return systemPorts;
    }
    /**
     * æ‰“开串口
     *
     * @param serialPortName ä¸²å£åç§°
     * @return SerialPort ä¸²å£å¯¹è±¡
     * @throws NoSuchPortException               å¯¹åº”串口不存在
     * @throws PortInUseException                ä¸²å£åœ¨ä½¿ç”¨ä¸­
     * @throws UnsupportedCommOperationException ä¸æ”¯æŒæ“ä½œæ“ä½œ
     */
    public static SerialPort openSerialPort(String serialPortName)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialPortParameter parameter = new SerialPortParameter(serialPortName);
        return openSerialPort(parameter);
    }
    /**
     * æ‰“开串口
     *
     * @param serialPortName ä¸²å£åç§°
     * @param baudRate       æ³¢ç‰¹çއ
     * @return SerialPort ä¸²å£å¯¹è±¡
     * @throws NoSuchPortException               å¯¹åº”串口不存在
     * @throws PortInUseException                ä¸²å£åœ¨ä½¿ç”¨ä¸­
     * @throws UnsupportedCommOperationException ä¸æ”¯æŒæ“ä½œæ“ä½œ
     */
    public static SerialPort openSerialPort(String serialPortName, int baudRate)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialPortParameter parameter =new SerialPortParameter(serialPortName, baudRate);
        return openSerialPort(parameter);
    }
    /**
     * æ‰“开串口
     *
     * @param serialPortName ä¸²å£åç§°
     * @param baudRate       æ³¢ç‰¹çއ
     * @param timeout        ä¸²å£æ‰“开超时时间
     * @return SerialPort ä¸²å£å¯¹è±¡
     * @throws NoSuchPortException               å¯¹åº”串口不存在
     * @throws PortInUseException                ä¸²å£åœ¨ä½¿ç”¨ä¸­
     * @throws UnsupportedCommOperationException ä¸æ”¯æŒæ“ä½œæ“ä½œ
     */
    public static SerialPort openSerialPort(String serialPortName, int baudRate, int timeout)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        SerialPortParameter parameter = new SerialPortParameter(serialPortName, baudRate);
        return openSerialPort(parameter, timeout);
    }
    /**
     * æ‰“开串口
     *
     * @param parameter ä¸²å£å‚æ•°
     * @return SerialPort ä¸²å£å¯¹è±¡
     * @throws NoSuchPortException               å¯¹åº”串口不存在
     * @throws PortInUseException                ä¸²å£åœ¨ä½¿ç”¨ä¸­
     * @throws UnsupportedCommOperationException ä¸æ”¯æŒæ“ä½œæ“ä½œ
     */
    public static SerialPort openSerialPort(SerialPortParameter parameter)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        return openSerialPort(parameter, 2000);
    }
    /**
     * æ‰“开串口
     *
     * @param parameter ä¸²å£å‚æ•°
     * @param timeout   ä¸²å£æ‰“开超时时间
     * @return SerialPort串口对象
     * @throws NoSuchPortException               å¯¹åº”串口不存在
     * @throws PortInUseException                ä¸²å£åœ¨ä½¿ç”¨ä¸­
     * @throws UnsupportedCommOperationException ä¸æ”¯æŒæ“ä½œæ“ä½œ
     */
    public static SerialPort openSerialPort(SerialPortParameter parameter, int timeout)
            throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException {
        //通过端口名称得到端口
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(parameter.getSerialPortName());
        //打开端口,(自定义名字,打开超时时间)
        CommPort commPort = portIdentifier.open(parameter.getSerialPortName(), timeout);
        //判断是不是串口
        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            //设置串口参数(波特率,数据位8,停止位1,校验位无)
            serialPort.setSerialPortParams(parameter.getBaudRate(), parameter.getDataBits(), parameter.getStopBits(), parameter.getParity());
            ShowMessage.zidingyi(parameter.getSerialPortName()+"打开成功!");
            //System.out.println("开启串口成功,串口名称:" + parameter.getSerialPortName());
            return serialPort;
        } else {
            //是其他类型的端口
            throw new NoSuchPortException();
        }
    }
    /**
     * @throws Exception
     * å…³é—­ä¸²å£
     * @author LinWenLi
     * @date 2018å¹´7月21日下午3:45:43
     * @Description: å…³é—­ä¸²å£
     * @param:
     * @return: void
     * @throws
     */
    public static void closeSerialPort(SerialPort serialPort) throws Exception {
        if (serialPort != null) {
            serialPort.notifyOnDataAvailable(false);
            serialPort.removeEventListener();
            if (inputStream != null) {
                try {
                    inputStream.close();
                    inputStream = null;
                } catch (IOException e) {
                    ShowMessage.zidingyi("关闭输入流时发生IO异常");
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                    outputStream = null;
                } catch (IOException e) {
                    ShowMessage.zidingyi("关闭输入流时发生IO异常");
                }
            }
            serialPort.close();
            serialPort = null;
            ShowMessage.zidingyi("串口关闭成功");
        }
    }
    /**
     * å‘送信息到串口
     * @author LinWenLi
     * @date 2018å¹´7月21日下午3:45:22
     * @param: serialPort ä¸²å£å¯¹è±¡
     * @return: data å‘送的数据
     * @throws
     */
    public static  void sendData(SerialPort serialPort, byte[] data) {
        try {
            outputStream = serialPort.getOutputStream();
            outputStream.write(data);
            outputStream.flush();
        } catch (NullPointerException e) {
            try {
                throw new Exception("找不到串口");
            } catch (Exception e1) {
                // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
                e1.printStackTrace();
            }
        } catch (IOException e) {
            try {
                throw new Exception("发送信息到串口时发生IO异常");
            } catch (Exception e1) {
                // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
                e1.printStackTrace();
            }
        }finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * è¯»å–串口返回信息
     * @author LinWenLi
     * @date 2018å¹´7月21日下午3:43:04
     * @return: byte[]
     */
    public static byte[] readData(SerialPort serialPort) {
        byte[] bytes=null;
        try {
            Thread.sleep(10);
            inputStream = serialPort.getInputStream();
            // é€šè¿‡è¾“入流对象的available方法获取数组字节长度
           bytes = new byte[inputStream.available()];
            // ä»Žçº¿è·¯ä¸Šè¯»å–数据流
            int len = 0;
            while ((len = inputStream.read(bytes)) != -1) {// ç›´æŽ¥èŽ·å–åˆ°çš„æ•°æ®
                data = new String(bytes, 0, len).trim();// è½¬ä¸ºåå…­è¿›åˆ¶æ•°æ®
                dataHex = Tools.Bytes2HexString(bytes);
                inputStream.close();
                inputStream = null;
                break;
            }
        } catch (IOException e) {
            try {
                SerialPortUtil.closeSerialPort(serialPort);
                ShowMessage.zidingyi_24("串口通信异常已关闭!");
                SerialPortUtil.getSerialPortList().clear();
                System.exit(-1);
            } catch (Exception e1) {
                // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
                e1.printStackTrace();
            }
        } catch (InterruptedException e) {
            //throw new RuntimeException(e);
        }
        return bytes;
    }
    /**
     * ç»™ä¸²å£è®¾ç½®ç›‘听
     *
     * @param serialPort serialPort è¦è¯»å–的串口
     * @param listener   SerialPortEventListener监听对象
     * @throws TooManyListenersException ç›‘听对象太多
     */
    public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) throws TooManyListenersException {
        //给串口添加事件监听
        if(serialPort!=null) {
        serialPort.addEventListener(listener);
        //串口有数据监听
        serialPort.notifyOnDataAvailable(true);
        //中断事件监听
        serialPort.notifyOnBreakInterrupt(true);
        }
    }
}
src/tools/ChuanKou/Xmodem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,257 @@
package tools.ChuanKou;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
 * XModem协议
 *
 * @author
 */
@SuppressWarnings("all")
public class Xmodem {
    // å¼€å§‹
    private final byte SOH = 0x01;
    // ç»“束
    private final byte EOT = 0x04;
    // åº”ç­”
    private final byte ACK = 0x06;
    // é‡ä¼ 
    private final byte NAK = 0x15;
    // æ— æ¡ä»¶ç»“束
    private final byte CAN = 0x18;
    // ä»¥128字节块的形式传输数据
    private final int SECTOR_SIZE = 128;
    // æœ€å¤§é”™è¯¯ï¼ˆæ— åº”答)包数
    private final int MAX_ERRORS = 10;
    // è¾“入流,用于读取串口数据
    private InputStream inputStream;
    // è¾“出流,用于发送串口数据
    private OutputStream outputStream;
    public Xmodem(InputStream inputStream, OutputStream outputStream) {
        this.inputStream = inputStream;
        this.outputStream = outputStream;
    }
    /**
     * å‘送数据
     *
     * @param filePath
     *            æ–‡ä»¶è·¯å¾„
     */
    public void send(final String filePath) {
        new Thread() {
            public void run() {
                try {
                    // é”™è¯¯åŒ…æ•°
                    int errorCount;
                    // åŒ…序号
                    byte blockNumber = 0x01;
                    // æ ¡éªŒå’Œ
                    int checkSum;
                    // è¯»å–到缓冲区的字节数量
                    int nbytes;
                    // åˆå§‹åŒ–数据缓冲区
                    byte[] sector = new byte[SECTOR_SIZE];
                    // è¯»å–文件初始化
                    DataInputStream inputStream = new DataInputStream(
                            new FileInputStream(filePath));
                    while ((nbytes = inputStream.read(sector)) > 0) {
                        // å¦‚果最后一包数据小于128个字节,以0xff补齐
                        if (nbytes < SECTOR_SIZE) {
                            for (int i = nbytes; i < SECTOR_SIZE; i++) {
                                sector[i] = (byte) 0xff;
                            }
                        }
                        // åŒä¸€åŒ…数据最多发送10次
                        errorCount = 0;
                        while (errorCount < MAX_ERRORS) {
                            // ç»„包
                            // æŽ§åˆ¶å­—符 + åŒ…序号 + åŒ…序号的反码 + æ•°æ®åŒºæ®µ + æ ¡éªŒå’Œ
                            putData(SOH);
                            putData(blockNumber);
                            putData(~blockNumber);
                            checkSum = CRC16.calc(sector) & 0x00ffff;
                            putChar(sector, (short) checkSum);
                            outputStream.flush();
                            // èŽ·å–åº”ç­”æ•°æ®
                            byte data = getData();
                            // å¦‚果收到应答数据则跳出循环,发送下一包数据
                            // æœªæ”¶åˆ°åº”答,错误包数+1,继续重发
                            if (data == ACK) {
                                break;
                            } else {
                                ++errorCount;
                            }
                        }
                        // åŒ…序号自增
                        blockNumber = (byte) ((++blockNumber) % 256);
                    }
                    // æ‰€æœ‰æ•°æ®å‘送完成后,发送结束标识
                    boolean isAck = false;
                    while (!isAck) {
                        putData(EOT);
                        isAck = getData() == ACK;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }
    /**
     * æŽ¥æ”¶æ•°æ®
     *
     * @param filePath
     *            æ–‡ä»¶è·¯å¾„
     * @return æ˜¯å¦æŽ¥æ”¶å®Œæˆ
     * @throws IOException
     *             å¼‚常
     */
    public boolean receive(String filePath) throws Exception {
        // é”™è¯¯åŒ…æ•°
        int errorCount = 0;
        // åŒ…序号
        byte blocknumber = 0x01;
        // æ•°æ®
        byte data;
        // æ ¡éªŒå’Œ
        int checkSum;
        // åˆå§‹åŒ–数据缓冲区
        byte[] sector = new byte[SECTOR_SIZE];
        // å†™å…¥æ–‡ä»¶åˆå§‹åŒ–
        DataOutputStream outputStream = new DataOutputStream(
                new FileOutputStream(filePath));
        // å‘送字符C,CRC方式校验
        putData((byte) 0x43);
        while (true) {
            if (errorCount > MAX_ERRORS) {
                outputStream.close();
                return false;
            }
            // èŽ·å–åº”ç­”æ•°æ®
            data = getData();
            if (data != EOT) {
                try {
                    // åˆ¤æ–­æŽ¥æ”¶åˆ°çš„æ˜¯å¦æ˜¯å¼€å§‹æ ‡è¯†
                    if (data != SOH) {
                        errorCount++;
                        continue;
                    }
                    // èŽ·å–åŒ…åºå·
                    data = getData();
                    // åˆ¤æ–­åŒ…序号是否正确
                    if (data != blocknumber) {
                        errorCount++;
                        continue;
                    }
                    // èŽ·å–åŒ…åºå·çš„åç 
                    byte _blocknumber = (byte) ~getData();
                    // åˆ¤æ–­åŒ…序号的反码是否正确
                    if (data != _blocknumber) {
                        errorCount++;
                        continue;
                    }
                    // èŽ·å–æ•°æ®
                    for (int i = 0; i < SECTOR_SIZE; i++) {
                        sector[i] = getData();
                    }
                    // èŽ·å–æ ¡éªŒå’Œ
                    checkSum = (getData() & 0xff) << 8;
                    checkSum |= (getData() & 0xff);
                    // åˆ¤æ–­æ ¡éªŒå’Œæ˜¯å¦æ­£ç¡®
                    int crc = CRC16.calc(sector);
                    if (crc != checkSum) {
                        errorCount++;
                        continue;
                    }
                    // å‘送应答
                    putData(ACK);
                    // åŒ…序号自增
                    blocknumber++;
                    // å°†æ•°æ®å†™å…¥æœ¬åœ°
                    outputStream.write(sector);
                    // é”™è¯¯åŒ…æ•°å½’é›¶
                    errorCount = 0;
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // å¦‚果出错发送重传标识
                    if (errorCount != 0) {
                        putData(NAK);
                    }
                }
            } else {
                break;
            }
        }
        // å…³é—­è¾“出流
        outputStream.close();
        // å‘送应答
        putData(ACK);
        return true;
    }
    /**
     * èŽ·å–æ•°æ®
     *
     * @return æ•°æ®
     * @throws IOException
     *             å¼‚常
     */
    private byte getData() throws IOException {
        return (byte) inputStream.read();
    }
    /**
     * å‘送数据
     *
     * @param data
     *            æ•°æ®
     * @throws IOException
     *             å¼‚常
     */
    private void putData(int data) throws IOException {
        outputStream.write((byte) data);
    }
    /**
     * å‘送数据
     *
     * @param data
     *            æ•°æ®
     * @param checkSum
     *            æ ¡éªŒå’Œ
     * @throws IOException
     *             å¼‚常
     */
    private void putChar(byte[] data, short checkSum) throws IOException {
        ByteBuffer bb = ByteBuffer.allocate(data.length + 2).order(
                ByteOrder.BIG_ENDIAN);
        bb.put(data);
        bb.putShort(checkSum);
        outputStream.write(bb.array());
    }
}
src/tools/CustomProgressBar.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package tools;
import javax.swing.*;
import java.awt.*;
public class CustomProgressBar extends JProgressBar {
    private Color textColor = Color.BLACK; // é»˜è®¤æ–‡æœ¬é¢œè‰²
    public CustomProgressBar() {
        super();
        setStringPainted(true); // å…è®¸æ˜¾ç¤ºæ–‡æœ¬
    }
    public void setTextColor(Color textColor) {
        this.textColor = textColor;
    }
    @Override
    protected void paintComponent(Graphics g) {
        // å…ˆè°ƒç”¨çˆ¶ç±»çš„paintComponent,绘制进度条的背景和前景
        super.paintComponent(g);
        if (isStringPainted()) {
            // èŽ·å–è¿›åº¦ç™¾åˆ†æ¯”çš„æ–‡æœ¬
            String text = String.format("%d%%", (int)(getPercentComplete() * 100));
            Graphics2D g2d = (Graphics2D) g;
            // èŽ·å–æ–‡æœ¬åŒºåŸŸçš„çŸ©å½¢åŒºåŸŸ
            FontMetrics metrics = g2d.getFontMetrics();
            int x = (getWidth() - metrics.stringWidth(text)) / 2;
            int y = (getHeight() + metrics.getAscent()) / 2;
            // æ¸…除文本区域,避免重影
            g2d.setColor(getBackground()); // ä½¿ç”¨èƒŒæ™¯è‰²æ¥æ¸…除区域
            g2d.fillRect(x, y - metrics.getAscent(), metrics.stringWidth(text), metrics.getHeight());
            // è®¾ç½®æ–‡æœ¬é¢œè‰²å’Œå­—体
            g2d.setColor(textColor);
            g2d.setFont(getFont().deriveFont(Font.BOLD));
            // ç»˜åˆ¶æ–‡æœ¬
            g2d.drawString(text, x, y);
        }
    }
}
src/tools/GetNowTime.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package tools;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class GetNowTime {
    public static String now() {//获取时间方法
        String msg="";
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
        msg+="["+sdf.format(date)+"]";
        return msg;
    }
    /**获取年月日时分秒毫秒时间 2020-05-30 12:33:45.23*/
    public static String timestamp2() {
        String d=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
        d="["+d+"]";
        return d;
    }
    public static int timestamp() {
        int time=0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String inputString =sss();
        Date date = null;
        try {
            date = sdf.parse("1970-01-01 " + inputString);
        } catch (ParseException e) {
            // TODO è‡ªåŠ¨ç”Ÿæˆçš„ catch å—
            e.printStackTrace();
        }
        time=(int) date.getTime();
        return time;
    }
    /**获取毫秒时间戳21:49:27.519*/
    public static String sss() {//获取时间方法
        String msg="";
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
        msg+=sdf.format(date);
        return msg;
    }
}
src/tools/Jiaoyan.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package tools;
import java.math.BigInteger;
public class Jiaoyan {
    /**获取校验码除去包头相加取反*/
    public static byte[] check(byte[] byt) {
        //字节数组转为16进制字符串/2后的长度
        int size=BinaryToHexString2(byt).length()/2;
        String[] hex=hex(BinaryToHexString2(byt));
        //求和
        int sum=0;
        for(int i=0;i<size;i++) {
            sum+=decodeHEX(hex[i]);
        }
        //取反转为16进制字符串
        String hex16=Integer.toHexString(~sum);
        //字符串的长度
        int lenth=hex16.length();
        byte[] jiaoyan=hexStringToByteArray(hex16.substring(lenth-4, lenth));
        return jiaoyan;
    }
    /**获取校验码除去包头相加取反*/
    public static String check2(String byt) {
        //字节数组转为16进制字符串/2后的长度
        int size=byt.length()/2;
        String[] hex=hex(byt);
        //求和
        int sum=0;
        for(int i=2;i<size-2;i++) {
            sum+=decodeHEX(hex[i]);
        }
        //取反转为16进制字符串
        String hex16=Integer.toHexString(~sum);
        //字符串的长度
        int lenth=hex16.length();
        String jiaoyan=hex16.substring(lenth-4, lenth);
        return jiaoyan.toUpperCase();
    }
    /**16进制转为10进制*/
    public static int decodeHEX(String hexs){
        BigInteger bigint=new BigInteger(hexs, 16);
        int numb=bigint.intValue();
        return numb;
    }
    /**将16进制字符串转为hex字符串数组2个字符串一个*/
    public static String[] hex(String message) {
        int size=message.length()/2;
        String[] hex=new String[size];
        for(int i=0;i<size;i++) {
            hex[i]=message.substring(i*2, 2+i*2);
        }
        return hex;
    }
    /**将字节数组转换为16进制字符串无空格*/
    public static  String BinaryToHexString2(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        String result = "";
        String hex = "";
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result += hex + "";
        }
        return result;
    }
    /**
     * 16进制表示的字符串转换为字节数组
    *
    * @param hexString 16进制表示的字符串
    * @return byte[] å­—节数组
    */
   public static byte[] hexStringToByteArray(String hexString) {
       hexString = hexString.replaceAll(" ", "");
       int len = hexString.length();
       byte[] bytes = new byte[len / 2];
       for (int i = 0; i < len; i += 2) {
           // ä¸¤ä½ä¸€ç»„,表示一个字节,把这样表示的16进制字符串,还原成一个字节
           bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
                   .digit(hexString.charAt(i+1), 16));
       }
       return bytes;
   }
}
src/tools/Judge/JugeIn.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package tools.Judge;
import tools.ShowMessage;
public class JugeIn {
    /**判断输入是否合法,如输入为kong*/
    public static  boolean shuru(String name,String str) {
        boolean inru=true;
        if(str.length()<1) {
            ShowMessage.zidingyi(name+"不能为空...");
            inru=false;
        }else if(!JugeNumber.isDigit(str)) {
            ShowMessage.zidingyi(name+"输入内容只能为整数...");
            inru=false;
        }
        return inru;
    }
}
src/tools/Judge/JugeNumber.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,136 @@
package tools.Judge;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JugeNumber {
    // çº¯æ•°å­—
    private static String DIGIT_REGEX = "^-?\\d+$";
    // å«æœ‰æ•°å­—
    private static String CONTAIN_DIGIT_REGEX = ".*[0-9].*";
    // çº¯å­—母
    private static String LETTER_REGEX = "[a-zA-Z]+";
    // åŒ…含字母
    private static String CONTAIN_LETTER_REGEX = ".*[a-zA-z].*";
    // çº¯ä¸­æ–‡
    private static String CHINESE_REGEX = "[\u4e00-\u9fa5]";
    // ä»…仅包含字母和数字
    private static String LETTER_DIGIT_REGEX = "^[a-z0-9A-Z]+$";
    private static String CHINESE_LETTER_REGEX = "([\u4e00-\u9fa5]+|[a-zA-Z]+)";
    private static String CHINESE_LETTER_DIGIT_REGEX = "^[a-z0-9A-Z\u4e00-\u9fa5]+$";
    /*方法二:推荐,速度最快
     * åˆ¤æ–­æ˜¯å¦ä¸ºæ•´æ•°
     * @param str ä¼ å…¥çš„字符串
     * @return æ˜¯æ•´æ•°è¿”回true,否则返回false
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }
    /** åˆ¤æ–­å­—符串是否仅含有数字和字母*/
    public static boolean isLetterDigit(String str) {
        return str.matches(LETTER_DIGIT_REGEX);
    }
    /**
     * æ˜¯å¦ä¸ºæ±‰å­—,不包括标点符号
     *
     * @param con
     * @return true æ˜¯æ±‰å­—
     */
    public static boolean isChinese(String con) {
        Pattern pattern = Pattern.compile(CHINESE_REGEX);
        for (int i = 0; i < con.length(); i = i + 1) {
            if (!pattern.matcher(
                    String.valueOf(con.charAt(i))).find()) {
                return false;
            }
        }
        return true;
    }
    /**
     * ç”¨æ­£åˆ™è¡¨è¾¾å¼åˆ¤æ–­å­—符串中是否 ä»…包含英文字母、数字和汉字
     *
     * @param str
     * @return
     */
    public static boolean isLetterDigitOrChinese(String str) {
        return str.matches(CHINESE_LETTER_DIGIT_REGEX);
    }
    /**
     * å§“名中可包含汉字和字母,无其它字符
     *
     * @param passengerName
     * @return
     */
    public static boolean checkChineseLetter(String passengerName) {
        Pattern pattern = Pattern.compile(CHINESE_LETTER_REGEX);
        Matcher matcher = pattern.matcher(passengerName);
        if (matcher.matches()) {
            //不包含特殊字符
            return true;
        } else {
            //包含了特殊字符
            return false;
        }
    }
    /**
     * åˆ¤æ–­ä¸€ä¸ªå­—符串是否包含标点符号(中文或者英文标点符号),true åŒ…含。<br/>
     * åŽŸç†ï¼šå¯¹åŽŸå­—ç¬¦ä¸²åšä¸€æ¬¡æ¸…æ´—ï¼Œæ¸…æ´—æŽ‰æ‰€æœ‰æ ‡ç‚¹ç¬¦å·ã€‚<br/>
     * æ­¤æ—¶ï¼Œå¦‚果入参 ret åŒ…含标点符号,那么清洗前后字符串长度不同,返回true;否则,长度相等,返回false。<br/>
     *
     * @param ret
     * @return true åŒ…含中英文标点符号
     */
    public static boolean checkPunctuation(String ret) {
        boolean b = false;
        String tmp = ret;
        //        replaceAll里面的正则匹配可以清空字符串中的中英文标点符号,只保留数字、英文和中文。
        tmp = tmp.replaceAll("\\p{P}", "");
        if (ret.length() != tmp.length()) {
            b = true;
        }
        return b;
    }
    /**判断字符串是否为纯数字*/
    public static boolean isDigit(String ret) {
        return ret.matches(DIGIT_REGEX);
    }
    public static boolean isLetter(String ret) {
        return ret.matches(LETTER_REGEX);
    }
    public static boolean hasDigit(String ret) {
        return ret.matches(CONTAIN_DIGIT_REGEX);
    }
    /**判断是否包含字母*/
    public static boolean hasLetter(String ret) {
        return ret.matches(CONTAIN_LETTER_REGEX);
    }
}
src/tools/ShowMessage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package tools;
public class ShowMessage {
    /**自定义的内容提示*/
    public static void zidingyi(String zidingyi) {
        AutoCloseDialog.getDialog(zidingyi);
    }
    /**软件试用期结束*/
    public static void zhuce_off() {
        AutoCloseDialog.getDialogno("软件试用期已结束,如需继续使用请向北京华星智控公司购买注册码!");
    }
    /**24小时消失的对话框*/
    public static void zidingyi_24(String str) {
        AutoCloseDialog.getDialogno(str);
    }
}
src/tools/Tools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,223 @@
package tools;
import java.math.BigInteger;
@SuppressWarnings("unused")
public class Tools {
    /**
     * å°†åå…­è¿›åˆ¶çš„字符串转换成字节数组
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStrToBinaryStr(String hexString) {
        if (hexString==null) {
            return null;
        }
        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;
        byte[] bytes = new byte[len / 2];
        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index/2] = (byte)Integer.parseInt(sub,16);
            index += 2;
        }
        return bytes;
    }
    /**
     * å°†åå…­è¿›åˆ¶çš„字符串转换成字节数组不去除空格
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStrToBinaryStr2(String hexString) {
        if (hexString==null) {
            return null;
        }
        int len = hexString.length();
        int index = 0;
        byte[] bytes = new byte[len / 2];
        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index/2] = (byte)Integer.parseInt(sub,16);
            index += 2;
        }
        return bytes;
    }
     public static final int registersToInt(byte[] bytes) {
            return (
                ((bytes[0] & 0xff) << 24) |
                ((bytes[1] & 0xff) << 16) |
                ((bytes[2] & 0xff) << 8) |
                (bytes[3] & 0xff)
                );
          }//registersToInt
    // hexתASCII
    public static String hexToAscii(String hex) {
        StringBuilder ascii = new StringBuilder();
        // å޻除 HEX å­—符串中的空格
        hex = hex.replaceAll(" ", "");
        // æ¯ä¸¤ä¸ªå­—符为一组,转换为对应的字节并拼接成 ASCII å­—符
        for (int i = 0; i < hex.length(); i += 2) {
            // ç›´æŽ¥ä½¿ç”¨ charAt èŽ·å–æ¯ä¸¤ä¸ªå­—ç¬¦çš„åå…­è¿›åˆ¶æ•°å­—
            char hexChar1 = hex.charAt(i);
            char hexChar2 = hex.charAt(i + 1);
            // ç»„合十六进制字符为一个数字
            int decimalValue = (Character.digit(hexChar1, 16) << 4) + Character.digit(hexChar2, 16);
            // è½¬æ¢ä¸ºå¯¹åº”çš„ ASCII å­—符并添加到结果中
            ascii.append((char) decimalValue);
        }
        return ascii.toString();  // è¿”回拼接后的 ASCII å­—符串
    }
    public static String byteToAscii(byte[] bytes) {
        // å°†å­—节数组转换为 ASCII å­—符串
        String asciiString = new String(bytes, java.nio.charset.StandardCharsets.US_ASCII);
        return asciiString;
    }
    /**将字节数组转为16进制字符串*/
     public static String Bytes2HexString(byte[] b) {
           String ret = "";
           for (int i = 0; i < b.length; i++) {
                 String hex = Integer.toHexString(b[i] & 0xFF);
                 if (hex.length() == 1) {
                   hex = '0' + hex;
                     }
                 ret += hex.toUpperCase();
               }
        return ret;
       }
     public static final float registersToFloat(byte[] bytes) {
            return Float.intBitsToFloat((
                ((bytes[0] & 0xff) << 24) |
                ((bytes[1] & 0xff) << 16) |
                ((bytes[2] & 0xff) << 8) |
                (bytes[3] & 0xff)
                ));
          }//
     @SuppressWarnings("unused")
    private static String intToHex(int n) {
            StringBuffer s = new StringBuffer();
            String a;
            char []b = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
            while(n != 0){
                s = s.append(b[n%16]);
                n = n/16;
            }
            a = s.reverse().toString();
            return a;
        }
     //将返回的数据转化为10进制数据
     public static int ormntoint(byte[] bytes){
         int aa=0;
         aa=bytes[0]-48 +(bytes[1]-48)*10+(bytes[2]-48)*100+(bytes[3]-48)*1000;
         return aa;
     }
    /**
     * 16进制的字符串表示转成字节数组
     *
     * @param hexString 16进制格式的字符串
     * @return è½¬æ¢åŽçš„字节数组
     **/
    public static byte[] toByteArray(String hexString) {
        byte[] byteArray=null;
        if(hexString !=null || hexString !="") {
            hexString = hexString.replaceAll(" ", "");
            byteArray = new byte[hexString.length() / 2];
            int k = 0;
            for (int i = 0; i < byteArray.length; i++) {//因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
                byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
                byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
                byteArray[i] = (byte) (high << 4 | low);
                k += 2;
            }
        }
        return byteArray;
    }
    public static  byte[] intToRegisters(int v) {
        byte[] registers = new byte[4];
        registers[0] = (byte) (0xff & (v >> 24));
        registers[1] = (byte) (0xff & (v >> 16));
        registers[2] = (byte) (0xff & (v >> 8));
        registers[3] = (byte) (0xff & v);
        return registers;
    }
    //转成字节数组
    public static String[] hex(String message) {
        int size=message.length()/2;
        String[] hex=new String[size];
        for(int i=0;i<size;i++) {
            hex[i]=message.substring(i*2, 2+i*2);
        }
        return hex;
    }
    /**
     * 16进制转为10进制
     */
    public static int decodeHEX(String hexs) {
        BigInteger bigint = new BigInteger(hexs, 16);
        int numb = bigint.intValue();
        return numb;
    }
    public static byte decodeHEXToInt8(String hexStr) {
        BigInteger bigInt = new BigInteger(hexStr, 16);
        // å°†æ— ç¬¦å·æ•´æ•°è½¬æ¢ä¸ºæœ‰ç¬¦å·çš„8位整数
        byte result = bigInt.byteValue();
        return result;
    }
}
src/ymodem/CRC16.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package ymodem;
import java.util.Arrays;
/**
 * Uses table for irreducible polynomial:  1 + x^2 + x^15 + x^16
 */
public class CRC16 {
    private static int[] table = {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
    };
    public static int getCRCLength() {
        return 2;
    }
    public static long calcCRC(byte[] block) {
        int crc = 0x0000;
        for (byte b : block) {
            crc = ((crc << 8) ^ table[((crc >> 8) ^ (0xff & b))]) & 0xFFFF;
        }
        return crc;
    }
    public static byte[] getCRC16(byte[] block) {
        byte[] crcBytes = new byte[getCRCLength()];
        long crcValue = calcCRC(block);
        for (int i = 0; i < getCRCLength(); i++) {
            crcBytes[getCRCLength() - i - 1] = (byte) ((crcValue >> (8 * i)) & 0xFF);
        }
        return crcBytes;
    }
    public static byte[] getCRC16(byte[] block,int start) {
        byte[] crcBytes = new byte[getCRCLength()];
        long crcValue = calcCRC(Arrays.copyOfRange(block, start, block.length-2));
        for (int i = 0; i < getCRCLength(); i++) {
            crcBytes[getCRCLength() - i - 1] = (byte) ((crcValue >> (8 * i)) & 0xFF);
        }
        return crcBytes;
    }
}
src/ymodem/YModemUpgradeThread.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,145 @@
package ymodem;
import gnu.io.SerialPort;
import index.JPanelMoudle.showDataComp;
import index.JPanelMoudle.versionUpgradeComp;
import tools.ChuanKou.SerialPortUtil;
import tools.ShowMessage;
import tools.Tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class YModemUpgradeThread extends Thread {
    private static byte[][] dataBytes; // æ•°æ®å¸§
    private static byte[] startBytes; // èµ·å§‹å¸§
    private static byte[] endBytes ; // ç»“束帧
    private static final long TIMEOUT = 30000; // è¶…过30秒未回应则退出升级模式
    private static SerialPort serialPort;
    static int numSend = 0;
    static boolean SendDataFlag = false;
    public static void shengji(SerialPort serialPort1, String filePath1,byte[] byt){
        SendDataFlag=false;
        numSend=0;
        serialPort = serialPort1;
        SerialPortUtil.sendData(serialPort, byt);
        ComSendUpdateFile(filePath1);
        chushihua();
    }
    // æž„造函数,接收串口和文件路径
    public static void chushihua() {
        if (versionUpgradeComp.isWrite()) {
            if (serialPort == null) {
                return;
            } else {
                new YModemUpgradeThread().startThread();
            }
        }
    }
    public void startThread() {
        Thread t = new Thread(this);
        t.start();
    }
    public void run() {
        try {
            // è°ƒç”¨å‡çº§è¿‡ç¨‹
            upgtade();
        } catch (Exception e) {
            Thread.currentThread().interrupt(); // æ¢å¤ä¸­æ–­æ ‡å¿—
            System.out.println("线程被中断,正在退出升级过程...");
            e.printStackTrace();
        }
    }
    //升级固件
    private void upgtade(){
        long startTime = System.currentTimeMillis();
        long l = System.currentTimeMillis() - startTime;
        boolean b =  l< TIMEOUT;
        while (b&&!SendDataFlag) {
            b=System.currentTimeMillis()-startTime<TIMEOUT;
            // ç­‰å¾…回应
            byte[] response = SerialPortUtil.readData(serialPort);
            // å¦‚果设备没有回应(回应为空),则认为是超时
            if (response == null || response.length == 0) {
                continue;  // å¦‚果没有回应,继续等待
            }
            showDataComp.addAreaTextMes(response,"127.0.0.1",9999);
            if (response[0] == ymodem.ACK) {
                numSend++;
                sendData(numSend);
            } else if (response[0] == ymodem.NAK || response[0] == ymodem.C) {
                // æ”¶åˆ°NAK或CA,退出升级
                sendData(numSend);
            }else if (response[0]==ymodem.CA){
                break;
            }
        }
        if (!b){
            ShowMessage.zidingyi("数据接收超时,退出升级模式");
        }
        versionUpgradeComp.exitUpgrade();
    }
    //发送数据包
    public static void sendData(int shuJuZhen) {
        int length = dataBytes.length;
        if (shuJuZhen == 0) {
            SerialPortUtil.sendData(serialPort, startBytes);
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen <= length && shuJuZhen > 0) {
            SerialPortUtil.sendData(serialPort, dataBytes[shuJuZhen - 1]);
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen == length + 1||shuJuZhen == length + 2) {
            SerialPortUtil.sendData(serialPort,new byte[]{(byte) ymodem.EOT});
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen == length + 3) {
            SerialPortUtil.sendData(serialPort,endBytes);
            getProgress(shuJuZhen, length);
            ShowMessage.zidingyi("升级完成");
            SendDataFlag=true;
            numSend = 0;
        }
    }
    //计算当前包的进度
    private static void getProgress(double shuJuZhen, int length) {
        int i =(int) Math.round((shuJuZhen / (length +3)) * 100);
        versionUpgradeComp.getJindu_SaoMiaoQi().setValue(i);
    }
    //获取要发送的帧数据
    public static void ComSendUpdateFile(String filePath){
        try {
            File file = new File(filePath);
            if (!file.exists()) {                                //如果文件不存在
                ShowMessage.zidingyi("文件不存在" + filePath);        //抛出文件找不到异常
                return;
            }
            getFilesDataBytes.setNum(0);
            startBytes = getFilesDataBytes.getStartData(file);//获取起始帧数据包
            dataBytes = getFilesDataBytes.getData(file);//获取数据帧数据包
            endBytes = getFilesDataBytes.getEndData();//获取结束帧数据包
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static boolean isSendDataFlag() {
        return SendDataFlag;
    }
    public static void setSendDataFlag(boolean sendDataFlag) {
        SendDataFlag = sendDataFlag;
    }
}
src/ymodem/getFilesDataBytes.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package ymodem;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class getFilesDataBytes {
    public static final int SOH = 0x01; // 128字节数据包
    public static final int STX = 0x02; // 1024字节数据包
    private static int num = 0;  // å¸§åºå·
    // èŽ·å–æ–‡ä»¶çš„èµ·å§‹æ•°æ®åŒ…
    public static byte[] getStartData(File file) {
        int index = 0;
        byte[] dat = new byte[133];
        byte[] nameBytes = file.getName().getBytes();
        byte[] lengthBytes = String.valueOf(file.length()).getBytes();
        dat[index++] = SOH;
        dat[index++] = (byte) num++;
        dat[index++] = (byte) ~dat[1];
        // ç»„合文件名数据
        for (int i = 0; i < nameBytes.length; i++) {
            dat[i + index] = nameBytes[i];
        }
        index += nameBytes.length;
        dat[index++] = 0x00;
        // ç»„合文件长度数据
        for (int i = 0; i < lengthBytes.length; i++) {
            dat[i + index] = lengthBytes[i];
        }
        index += lengthBytes.length;
        dat[index++] = 0x00;
        byte[] crcDat = CRC16.getCRC16(dat, 3);
        dat[dat.length - 2] = crcDat[0];
        dat[dat.length - 1] = crcDat[1];
        return dat;
    }
    // èŽ·å–ç»“æŸå¸§æ•°æ®
    public static byte[] getEndData() {
        byte[] dat = new byte[133];
        dat[0] = SOH;
        dat[1] = (byte) 0x00;
        dat[2] = (byte) 0xFF;
        byte[] crcDat = CRC16.getCRC16(dat, 3);
        dat[dat.length - 2] = crcDat[0];
        dat[dat.length - 1] = crcDat[1];
        return dat;
    }
    /**
     * èŽ·å–æ•°æ®å¸§æ•°æ®
     *
     * @param file æ–‡ä»¶
     * @return æ•°æ®å¸§æ•°ç»„
     * @throws IOException
     */
    public static byte[][] getData(File file) throws IOException {
        long len = file.length();
        int size = (int) Math.ceil(len / 1024d);
        int size1 = (int) Math.ceil(len / 1024d);
        double v = len % 1024d;
        if (v==0){
            int i = size + 1;
            size1=i;
        }
        //获取数据帧个数
        byte[][] result = new byte[size][1029];
        FileInputStream fis = new FileInputStream(file);
        for (int i = 0; i < size1-1 ; i++) {            //生成数据帧
            result[i][0] = STX;                        //1024字节数据包头
            result[i][1] = (byte) (num++);            //自动填充帧序号
            if (num > 255) {                        //帧序号最大255
                num = 0;
            }
            result[i][2] = (byte) ~result[i][1];        //取反帧序号
            fis.read(result[i], 3, 1024);
            byte[] crc16 = CRC16.getCRC16(result[i], 3);    //获取crc16校验
            result[i][result[i].length - 2] = crc16[0];
            result[i][result[i].length - 1] = crc16[1];    //填充crc16校验
        }
        int endLen = (int) len % 1024;
        //如果最后一帧不是整1024个字节
        if (endLen > 0) {
            //如果最后一帧长度小于等于128
            if (endLen <= 128) {
                //最后一帧使用128字节传输
                result[size - 1] = new byte[133];
                result[size - 1][0] = SOH;                        //128字节数据包头
                int n = fis.read(result[size - 1], 3, 128);        //填充128个字节数据
                for (int i = n + 3; i < 131; i++) {                    //剩余位填充0x1A
                    result[size - 1][i] = 0x1A;
                }
            } else {
                //最后一帧使用1024字节传输
                result[size - 1][0] = STX;                        //1024字节数据包头
                int n = fis.read(result[size - 1], 3, 1024);        //填充1024个数据
                for (int i = n + 3; i < 1027; i++) {                    //剩余位填充0x1A
                    result[size - 1][i] = 0x1A;
                }
            }
            result[size - 1][1] = (byte) (num++);                //自动填充帧序号
            if (num > 255) {                                //帧序号最大255
                num = 0;
            }
            result[size - 1][2] = (byte) ~result[size - 1][1];    //取反帧序号
            byte[] crc16 = CRC16.getCRC16(result[size - 1], 3);    //获取crc16校验
            result[size - 1][result[size - 1].length - 2] = crc16[0];
            result[size - 1][result[size - 1].length - 1] = crc16[1];    //填充crc16校验
        }
        fis.close();
        return result;
    }
    public static int getNum() {
        return num;
    }
    public static void setNum(int num) {
        getFilesDataBytes.num = num;
    }
}
src/ymodem/netWorkUpgradeThread.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
package ymodem;
import baowen.Dell_udpReceive;
import gnu.io.SerialPort;
import index.JPanelMoudle.showDataComp;
import index.JPanelMoudle.versionUpgradeComp;
import tools.ChuanKou.SerialPortUtil;
import tools.ShowMessage;
import tools.Tools;
import java.io.File;
import java.io.IOException;
import java.net.*;
public class netWorkUpgradeThread extends Thread {
    private static byte[][] dataBytes; // æ•°æ®å¸§
    private static byte[] startBytes; // èµ·å§‹å¸§
    private static byte[] endBytes ; // ç»“束帧
    private static final long TIMEOUT = 600000; // è¶…过30秒未回应则退出升级模式
    static int numSend = 0;
    static boolean SendDataFlag = false;
    static String ip = "";//目标设备ip地址
    static int port;//目标设备端口
    static DatagramSocket socket;
    static int bytlenth=1024;
    static DatagramPacket packet;
    public static void shengji(String ip1,int port1, String filePath1,byte[] byt,int nowPort){
        SendDataFlag=false;
        numSend=0;
        ip = ip1;
        port = port1;
        Dell_udpReceive.sendData(byt,ip,port);
        ComSendUpdateFile(filePath1);
        Dell_udpReceive.stopThread();//暂停解析线程
        chushihua(nowPort);
        new Dell_udpReceive(nowPort);//重新开始解析线程
    }
    // æž„造函数,接收串口和文件路径
    public static void chushihua(int nowPort) {
        if (versionUpgradeComp.isWrite()) {
          if (socket==null){
              try {
                  socket = new DatagramSocket(nowPort);//创建socket
                  byte[] data = new byte[bytlenth]; // åˆ›å»ºbyte数组
                  packet= new DatagramPacket(data,bytlenth);
                  new netWorkUpgradeThread().startThread();
              } catch (SocketException e) {
                  throw new RuntimeException(e);
              }
          }else {
              new netWorkUpgradeThread().startThread();
          }
        }
    }
    public void startThread() {
        Thread t = new Thread(this);
        t.start();
    }
    public void run() {
        try {
            // è°ƒç”¨å‡çº§è¿‡ç¨‹
            upgtade();
            stopThread();
        } catch (Exception e) {
            Thread.currentThread().interrupt(); // æ¢å¤ä¸­æ–­æ ‡å¿—
            System.out.println("线程被中断,正在退出升级过程...");
            e.printStackTrace();
        }
    }
    //升级固件
    private void upgtade(){
        long startTime = System.currentTimeMillis();
        boolean b = System.currentTimeMillis() - startTime < TIMEOUT;
        while (b&&!SendDataFlag) {
            // ç­‰å¾…回应
            byte[] recDat = getRecDat();
            // å¦‚果设备没有回应(回应为空),则认为是超时
            if (recDat == null || recDat.length == 0) {
                continue;
            }
            showDataComp.addAreaTextMes(recDat,ip,port);
            if (recDat[0] == ymodem.ACK) {
                numSend++;
                sendData(numSend);
            } else if (recDat[0] == ymodem.NAK || recDat[0] == ymodem.C) {
                // æ”¶åˆ°NAK或CA,退出升级
                sendData(numSend);
            }else if (recDat[0]==ymodem.CA){
                break;
            }
        }
        versionUpgradeComp.exitUpgrade();
    }
    //发送数据包
    public static void sendData(int shuJuZhen) {
        int length = dataBytes.length;
        if (shuJuZhen == 0) {
            sendData(startBytes,ip,port);
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen <= length && shuJuZhen > 0) {
            sendData(dataBytes[shuJuZhen - 1],ip,port);
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen == length + 1||shuJuZhen == length + 2) {
            sendData(new byte[]{(byte) ymodem.EOT},ip,port);
            getProgress(shuJuZhen, length);
        } else if (shuJuZhen == length + 3) {
            sendData(endBytes,ip,port);
            getProgress(shuJuZhen, length);
            ShowMessage.zidingyi("升级完成");
            SendDataFlag=true;
            numSend = 0;
        }
    }
    //计算当前包的进度
    private static void getProgress(double shuJuZhen, int length) {
        int i =(int) Math.round((shuJuZhen / (length +3)) * 100);
        versionUpgradeComp.getJindu_SaoMiaoQi().setValue(i);
    }
    //获取要发送的帧数据
    public static void ComSendUpdateFile(String filePath){
        try {
            File file = new File(filePath);
            if (!file.exists()) {                                //如果文件不存在
                ShowMessage.zidingyi("文件不存在" + filePath);        //抛出文件找不到异常
                return;
            }
            getFilesDataBytes.setNum(0);
            startBytes = getFilesDataBytes.getStartData(file);//获取起始帧数据包
            dataBytes = getFilesDataBytes.getData(file);//获取数据帧数据包
            endBytes = getFilesDataBytes.getEndData();//获取结束帧数据包
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static byte[] getRecDat()  {
        byte[] dat = new byte[0];
        try {
            dat = null;
            packet = new DatagramPacket(dat,100);
            socket.receive(packet);
            String hostAddress = packet.getAddress().getHostAddress();
            if (hostAddress.equals(ip)){
                int lenth=packet.getLength();
                dat=subBytes(packet.getData(),0, lenth);
            }
            return dat;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
        /**将数据发给网关*/
    public static void sendData(byte[] data,String ipout,int portout) {
        DatagramPacket packet=null;
        InetAddress address=null;
        //如果数据类型相同
        try {
            address=InetAddress.getByName(ipout);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        packet=new DatagramPacket(data,data.length, address, portout);
        try {
            socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }
    public static void stopThread() {
        if (socket != null && !socket.isClosed()) {
            socket.close();//关闭socket对象
        }
    }
}
src/ymodem/ymodem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package ymodem;
public class ymodem {
    public static final int EOT = 0x04; // ç»“束传输
    public static final int ACK = 0x06; // å“åº”
    public static final int NAK = 0x15; // ä¸å“åº”
    public static final int CA = 0x18;  // ä¼ è¾“终止
    public static final int C = 0x43;   // è¯·æ±‚数据包
}