用Java写一个PC端的WIFI-ADB管理软件

废话

    一直在用android studio做android开发,偶然一次机会接触到了wifi adb,试了好几个支持android studio的插件,各有优缺点,有一个本来用着好好的,突然就用不了,不懂啥情况,于是就萌生了自己写一个的想法。然后查了一下,感觉写android studio插件的话,会有点麻烦,写一个小型PC桌面程序,相对简单一些,但我也从来没写过,当然,有着多年的Java基础,也不怂,索性就,盘他。

    先上源码地址:https://gitee.com/imxiaoyu_admin/WIFI-ADB.git

    然后附上运行之后的效果图:

程序逻辑

参考了一下其他的插件,大概就是几个功能点:

1、用户手动输入ip和端口号,直接连接设备

2、用户先用usb连接手机,然后一键切换至wifi连接

3、连接过的手机可以保存起来(如果不保存的话,下次打开需要有限连接一次才能切换wifi连接,比较麻烦)

4、连接、断开等常规操作

5、手动设置adb程序的路径(懒得写自动检测的,索性就写个手动的,反正设置一次永久使用,问题不大)

开发环境

    操作系统是win10,其他一些Jdk等必要的东西,就不列举了

1、开发工具Intellij Idea

2、adb.exe

开始编码

1、新建一个java程序

2、简单分一下包

3、引用gson工具包

    网上下载一个gson.jar,然后复制到lib文件夹

    点击 File->Project Structure->Libraries,然后点加号并找到gson.jar,导入完成之后如下图所示:

4、相关工具类

    缓存逻辑:

    因为程序比较简单,这里就不搞数据库这种花里胡哨的东西了,数据存储的方式,就采用txt文件+json的形式,即在本机的某个固定路径(这里写死D://wifi-adb-settings.txt)生成一个txt文件,用于存放相关数据的json字符串。

    需要保存的,仅有adb路径和历史设备数据两项,设备详细信息我也不新建对象了,直接用Map<String,Objec>来处理了,一切从简。

    跟adb的交互,则是通过命令行的方式交互,通过执行命令行并解析结果,来完成相关的交互工作。

    下面放工具类,具体逻辑不多说了,都有注释,仔细看即可。

(1)CmdUtils

package com.imxiaoyu.wifi.adb.utils;

import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class CmdUtils {

    /**
     * 执行adb命令
     *
     * @param cmd 要执行的命令  参数
     * @return 返回执行结果,区分换行
     */
    public static List<String> runCmd(String cmd) {
        System.out.print("\n执行命令:" + cmd);
        List<String> list = new ArrayList<>();
        Process proc = null;
        BufferedReader reader;
        String line = null;
        Runtime runtime = Runtime.getRuntime();
        try {
            proc = runtime.exec(cmd);

            if (proc != null) {
                reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                while ((line = reader.readLine()) != null) {
                    if (line.length() > 1) {
                        list.add(line);
                    }
                }
            }

        } catch (Exception e) {
            System.out.print("执行命令:" + cmd + "出错啦!");
            return null;
        }

        System.out.print("执行结果:" + new Gson().toJson(list));
        return list;
    }
}

(2)ConnectUtils

package com.imxiaoyu.wifi.adb.utils;

import com.google.gson.Gson;

import javax.swing.*;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class ConnectUtils {


    /**
     * 链接设备
     * @param name
     * @return
     */
    public static boolean connect(String name) {
        String cmd = SettingsUtils.getSettings().getWifiAdbPath() + "/adb.exe " + "connect " + name;
        List<String> list = CmdUtils.runCmd(cmd);
        String str = new Gson().toJson(list);
        if (str.indexOf("connected to") > -1) {
            //链接成功
            return true;
        }

        JOptionPane.showMessageDialog(null, "目标设备拒接,无法链接。", "链接失败", JOptionPane.ERROR_MESSAGE);
        return false;
    }

    /**
     * 断开设备
     * @param name
     * @return
     */
    public static boolean disconnect(String name) {
        String cmd = SettingsUtils.getSettings().getWifiAdbPath() + "/adb.exe " + "disconnect " + name;
        List<String> list = CmdUtils.runCmd(cmd);
        String str = new Gson().toJson(list);
        if (str.indexOf("disconnected") > -1) {
            //断开成功
            return true;
        }

        JOptionPane.showMessageDialog(null, "设备不存在。", "断开链接失败", JOptionPane.ERROR_MESSAGE);
        return false;
    }

    /**
     * 解析一个usb设备的ip地址,不带端口号
     *
     * @return
     */
    public static String getDeviceIp(String name) {
        String cmd = SettingsUtils.getSettings().getWifiAdbPath() + "/adb.exe" + " -s " + name + " shell ifconfig wlan0 ";
        List<String> list = CmdUtils.runCmd(cmd);
        if (list.size() < 2) {
            return null;
        }
        String str = list.get(1);//ip地址在第二行,实例参数:  inet addr:192.168.22.11  Bcast:192.168.22.255  Mask:255.255.255.0

        Pattern p = Pattern.compile("\\s+");
        Matcher m = p.matcher(str);
        str = m.replaceAll(" ");//将多个连续的空格只保留一个

        str = str.replace(":", " ");
        String[] strList = str.split(" ");
        System.out.print("\n读取到的ip地址:" + strList[3]);
        return strList[3];
    }

    /**
     * 给一个设备设置一个默认端口,默认5555,设置好了之后就可以直接通过ip+端口链接
     *
     * @param name
     * @param port
     * @return
     */
    public static void setDevicePort(String name, String port) {
        String cmd = SettingsUtils.getSettings().getWifiAdbPath() + "/adb.exe" + " -s " + name + " tcpip " + port;
        CmdUtils.runCmd(cmd);
    }

    /**
     * 判定一个设备是否是usb链接
     *
     * @param name
     * @return true-usb链接  false-wifi链接
     */
    public static boolean isUsb(String name) {
        if (name.indexOf(":") == -1) {
            //如果设备的名称带有冒号的,证明是带有端口的,也就不是usb的方式链接的了
            return true;
        }
        return false;
    }


    /**
     * 判定一个usb设备是否已经链接了wifi
     *
     * @param deviceList
     * @param name
     * @return true-usb链接  false-wifi链接
     */
    public static boolean isUsbConnectWifi(List<Map<String, Object>> deviceList, String name) {
        //判定逻辑:先获取这个有线设备的ip地址,如果现有的设备列表已经存在了这个ip地址,证明这个有线设备已经通过wifi链接了
        String ip = getDeviceIp(name);
        for (int i = 0; i < deviceList.size(); i++) {
            String deviceName = deviceList.get(i).get("name") + "";
            if (deviceName.startsWith(ip)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判定一个wifi设备是否已经链接了
     *
     * @param deviceList
     * @param name
     * @return true-usb链接  false-wifi链接
     */
    public static boolean isWifiConnect(List<Map<String, Object>> deviceList, String name) {
        //逻辑:如果这个wifi设备已经在当前的设备列表里,那就是已连接了
        for (int i = 0; i < deviceList.size(); i++) {
            String deviceName = deviceList.get(i).get("name") + "";
            if (deviceName.startsWith(name)) {
                return true;
            }
        }
        return false;
    }
}

(3)SettingsEntity

package com.imxiaoyu.wifi.adb.utils;

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

public class SettingsEntity {
    private String wifiAdbPath = "";
    private List<Map<String, Object>> phoneList=new ArrayList<>();

    public String getWifiAdbPath() {
        return wifiAdbPath;
    }

    public void setWifiAdbPath(String wifiAdbPath) {
        this.wifiAdbPath = wifiAdbPath;
    }

    public List<Map<String, Object>> getPhoneList() {
        return phoneList;
    }

    public void setPhoneList(List<Map<String, Object>> phoneList) {
        this.phoneList = phoneList;
    }
}

(4)SettingsUtils

package com.imxiaoyu.wifi.adb.utils;

import com.google.gson.Gson;

import javax.swing.*;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SettingsUtils {
    private static Gson gson = new Gson();
    private static final String SETTINGS_PATH = "D://wifi-adb-settings.txt";//用于保存数据的txt文件的目录


    /**
     * 获取当前链接的设备的设备列表
     *
     * @return
     */
    public static List<Map<String, Object>> getAllDevice() {
        List<Map<String, Object>> deviceList = new ArrayList<>();
        SettingsEntity entity = getSettings();
        String cmd = entity.getWifiAdbPath() + "/adb.exe " + "devices -l";//获取列表的命令
        List<String> cmdList = CmdUtils.runCmd(cmd);

        //运行adb.exe devices -l 这个命令之后,从返回的结果中解析出设备的相关信息

        for (int i = 1; i < cmdList.size(); i++) {
            //跳过第一行
            Pattern p = Pattern.compile("\\s+");
            Matcher m = p.matcher(cmdList.get(i));
            String str = m.replaceAll(" ");//将多个连续的空格只保留一个
            str = str.replace(":", " ");//将冒号抓换成空格,方便解析
            if (str.indexOf(".") > -1) {
                //如果包含有小数点,证明名字是带端口的,这时候需要把第一个空格还原为冒号
                str = str.replaceFirst(" ", ":");
            }
            System.out.print("\n解析前:" + str);

            Map<String, Object> map = new HashMap<>();
            String[] list = str.split(" ");
            map.put("name", list[0]);
            map.put("device_product", list[3]);
            map.put("model", list[5]);
            map.put("device", list[7]);
            map.put("transport_id", list[9]);
            deviceList.add(map);
        }

        return deviceList;
    }

    /**
     * 将一个已连接的设备保存起来
     *
     * @param map
     */
    public static void saveDevice(Map<String, Object> map) {

        if (isHaveDevice(map)) {
            JOptionPane.showMessageDialog(null, "设备已存在", "保存失败", JOptionPane.ERROR_MESSAGE);
            return;
        }

        SettingsEntity entity = getSettings();
        map.put("id", UUID.randomUUID().toString());//保存的时候给加一个唯一id,方便删除
        entity.getPhoneList().add(map);
        setSettings(entity);
        //保存成功
    }

    /**
     * 根据id,删除一个已保存的设备
     *
     * @param id
     */
    public static void removeDevice(String id) {
        SettingsEntity entity = getSettings();
        List<Map<String, Object>> list = getSettings().getPhoneList();

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).get("id").equals(id)) {
                list.remove(i);
            }
            entity.setPhoneList(list);
            setSettings(entity);
            return;
        }
        //删除成功
    }


    /**
     * 判定一个设备是否已经存在
     *
     * @param map
     * @return
     */
    public static boolean isHaveDevice(Map<String, Object> map) {

        List<Map<String, Object>> deviceList = getSettings().getPhoneList();
        if (deviceList == null) {
            deviceList = new ArrayList<>();
        }
        boolean isHave = false;//是否存在
        for (int i = 0; i < deviceList.size(); i++) {
            if (deviceList.get(i).get("name").equals(map.get("name")) && deviceList.get(i).get("model").equals(map.get("model"))) {
                isHave = true;//这个设备已存在
            }
        }
        return isHave;
    }


    /**
     * 获取保存的数据
     *
     * @return
     */
    public static SettingsEntity getSettings() {
        SettingsEntity settingsEntity;
        String str = readString();
        settingsEntity = gson.fromJson(str, SettingsEntity.class);
        if (settingsEntity == null) {
            settingsEntity = new SettingsEntity();
        }
        return settingsEntity;
    }

    /**
     * 写入保存数据
     *
     * @param entity
     */
    public static void setSettings(SettingsEntity entity) {
        writeString(gson.toJson(entity));
    }

    /**
     * 从文件中读取保存数据的json字符串
     *
     * @return
     */
    private static String readString() {

        File file = new File(SETTINGS_PATH);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        try (FileReader reader = new FileReader(SETTINGS_PATH);
             BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
        ) {
            String allStr = "";
            String line;
            //网友推荐更加简洁的写法
            while ((line = br.readLine()) != null) {
                // 一次读入一行数据
//                System.out.println(line);
                allStr += line;
            }
            return allStr;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json字符串写入到txt文件中
     *
     * @param settingsStr
     */
    private static void writeString(String settingsStr) {
        try {
            File writeName = new File(SETTINGS_PATH); // 相对路径,如果没有则要建立一个新的output.txt文件
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            try (FileWriter writer = new FileWriter(writeName);
                 BufferedWriter out = new BufferedWriter(writer)
            ) {
                out.write(settingsStr); // \r\n即为换行
                out.flush(); // 把缓存区内容压入文件
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5、写页面交互

    其实写页面是我耗时最久的地方,可能是写习惯android了,切换到这边,写列表的时候,习惯性使用jlist这个控件,后来试了挺多次了,效果不太满意,后来查了一下,才转过来用jtabel,对是用对了,但是这个坑也挺坑的,反正就是遇到各种问题,耗费了不少时间。

    编写过程也不多少了,直接看代码吧,都有注释,先上一张截图,然后是源码。

    页面相关的操作逻辑,我都放到了IndexView这个页面里,可能会显得稍乱一些。

package com.imxiaoyu.wifi.adb.view;

import com.imxiaoyu.wifi.adb.utils.ConnectUtils;
import com.imxiaoyu.wifi.adb.utils.SettingsEntity;
import com.imxiaoyu.wifi.adb.utils.SettingsUtils;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class IndexView {


    private JPanel jPanel;

    private JTextField tf_adb_path;
    private JButton btn_adb_path;
    private JButton btn_refresh;
    private JTable tb_now;
    private JTable tb_history;
    private JButton btn_test_connect;
    private JTextField tf_ip_port;

    private List<Map<String, Object>> nowDeviceList = new ArrayList<>();
    private List<Map<String, Object>> historyDeviceList = new ArrayList<>();

    public void startView() {
        JFrame frame = new JFrame("Wifi Adb");
        frame.setContentPane(jPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setSize(new Dimension(880, 500));

        btn_adb_path.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //设置一下adb.exe的路径
                JFileChooser fileChooser = new JFileChooser("D:\\");
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int returnVal = fileChooser.showOpenDialog(fileChooser);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    String filePath = fileChooser.getSelectedFile().getAbsolutePath();//这个就是你选择的文件夹的路径
                    tf_adb_path.setText(filePath);
                    System.out.print("\n选中的路径:" + filePath);
                    SettingsEntity entity = SettingsUtils.getSettings();
                    entity.setWifiAdbPath(filePath);
                    SettingsUtils.setSettings(entity);
                }
            }
        });

        btn_test_connect.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //通过手动输入ip和端口的形式,直接连接设备
                String deviceName=tf_ip_port.getText();
                ConnectUtils.connect(deviceName);
                initList();
            }
        });

        btn_refresh.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //刷新列表
                initList();
            }
        });

        //初始化adv.exe的路径信息
        SettingsEntity entity = SettingsUtils.getSettings();
        tf_adb_path.setText(entity.getWifiAdbPath());

        initList();
    }


    private void initList() {

        nowDeviceList = SettingsUtils.getAllDevice();
        NowListModel listModel = new NowListModel();

        tb_now.setModel(listModel);//设置需要显示的数据
        tb_now.setRowHeight(36);

        //这个setCellEditor和setCellRenderer必须分别new,不然的话点击按钮的时候会有点小问题
        tb_now.getColumnModel().getColumn(3).setCellEditor(new NowListEditor());//加入点击监听
        tb_now.getColumnModel().getColumn(3).setCellRenderer(new NowListEditor());//加入操作按钮

        tb_now.setRowSelectionAllowed(false);


        historyDeviceList = SettingsUtils.getSettings().getPhoneList();

        HistoryListModel historyListModel = new HistoryListModel();

        tb_history.setModel(historyListModel);
        tb_history.setRowHeight(36);

        tb_history.getColumnModel().getColumn(3).setCellEditor(new HistoryListEditor());
        tb_history.getColumnModel().getColumn(3).setCellRenderer(new HistoryListEditor());

        tb_history.setRowSelectionAllowed(false);

    }


    public class NowListModel extends AbstractTableModel {


        /**
         * 得到表格行数
         */
        @Override
        public int getRowCount() {
            if (nowDeviceList.size() == 0) {
                //列表空的话,标题也不显示
                return 0;
            }
            return nowDeviceList.size() + 1;
        }

        /**
         * 重写方法,得到表格列数
         */
        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            if (rowIndex == 0) {
                if (columnIndex == 0) {
                    return "型号";
                }
                if (columnIndex == 1) {
                    return "设备名称";
                }
                if (columnIndex == 2) {
                    return "transport_id";
                }
                if (columnIndex == 3) {
                    return "操作";
                }
            }

            if (columnIndex == 0) {
                return nowDeviceList.get(rowIndex - 1).get("model");
            }
            if (columnIndex == 1) {
                return nowDeviceList.get(rowIndex - 1).get("name");
            }
            if (columnIndex == 2) {
                return nowDeviceList.get(rowIndex - 1).get("transport_id");
            }
            return "";
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            // 带有按钮列的功能这里必须要返回true不然按钮点击时不会触发编辑效果,也就不会触发事件。
            if (column == 3) {
                return true;
            } else {
                return false;
            }
        }

    }

    public class HistoryListModel extends AbstractTableModel {


        /**
         * 得到表格行数
         */
        @Override
        public int getRowCount() {
            if (historyDeviceList.size() == 0) {
                return 0;
            }
            return historyDeviceList.size() + 1;
        }

        /**
         * 重写方法,得到表格列数
         */
        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            if (rowIndex == 0) {
                if (columnIndex == 0) {
                    return "型号";
                }
                if (columnIndex == 1) {
                    return "设备名称";
                }
                if (columnIndex == 3) {
                    return "操作";
                }
                if (columnIndex == 2) {
                    return "transport_id";
                }
            }

            if (columnIndex == 1) {
                return historyDeviceList.get(rowIndex - 1).get("name");
            }
            if (columnIndex == 0) {
                return historyDeviceList.get(rowIndex - 1).get("model");
            }
            if (columnIndex == 2) {
                return historyDeviceList.get(rowIndex - 1).get("transport_id");
            }
            return "";
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            // 带有按钮列的功能这里必须要返回true不然按钮点击时不会触发编辑效果,也就不会触发事件。
            if (column == 3) {
                return true;
            } else {
                return false;
            }
        }

    }

    public class NowListEditor extends AbstractCellEditor implements TableCellRenderer,
            TableCellEditor {

        private JPanel panel;
        private JButton btnSave = null;
        private JButton btnDis = null;
        private JButton btnConnect = null;
        private int clickRow;

        public NowListEditor() {
            initButton();

            initPanel();

            panel.add(btnConnect);
            panel.add(btnDis);
            panel.add(btnSave);
        }

        private void initButton() {
            /**
             * 初始化按钮
             */
            btnConnect = new JButton("链接");
            btnDis = new JButton("断开");
            btnSave = new JButton("保存");

            /**
             * 设置按钮监听
             */
            btnConnect.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n链接");
                    System.out.print(";clickRow:" + clickRow);

                    String deviceName = nowDeviceList.get(clickRow - 1).get("name") + "";
                    String ip = ConnectUtils.getDeviceIp(deviceName);
                    String port = "5555";
                    ConnectUtils.setDevicePort(deviceName, port);
                    ConnectUtils.connect(ip + ":" + port);
                    initList();
                }
            });
            btnDis.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n断开");
                    System.out.print(";clickRow:" + clickRow);
                    ConnectUtils.disconnect(nowDeviceList.get(clickRow - 1).get("name") + "");
                    initList();
                }
            });
            btnSave.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n保存");
                    System.out.print(";clickRow:" + clickRow);
                    SettingsUtils.saveDevice(nowDeviceList.get(clickRow - 1));
                    initList();
                }
            });
        }

        /**
         * 初始化画板
         */
        private void initPanel() {
            panel = new JPanel();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            /**
             * 这里是处理显示
             */
            panel.setBackground(new Color(255, 255, 255));
            if (row != 0) {
                panel.removeAll();

                String deviceName = nowDeviceList.get(row - 1).get("name") + "";

                if (ConnectUtils.isUsb(deviceName)) {
                    //这是一个有线设备
                    if (!ConnectUtils.isUsbConnectWifi(nowDeviceList, deviceName)) {
                        //这个有限设备还没链接wifi
                        panel.add(btnConnect);
                    }
                } else {
                    //这是一个wifi设备
                    panel.add(btnDis);

                    if (!SettingsUtils.isHaveDevice(nowDeviceList.get(row - 1))) {
                        //这个wifi设备还没有保存
                        panel.add(btnSave);
                    }
                }
                return panel;
            }
            return null;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                                                     boolean isSelected, int row, int column) {
            /**
             * 这里是处理点击
             */
            clickRow = row;
            panel.setBackground(new Color(255, 255, 255));
            if (row != 0) {
                panel.removeAll();

                String deviceName = nowDeviceList.get(row - 1).get("name") + "";
                if (ConnectUtils.isUsb(deviceName)) {
                    System.out.print("\n有线设备:"+deviceName);
                    //这是一个有线设备
                    if (!ConnectUtils.isUsbConnectWifi(nowDeviceList, deviceName)) {
                        //这个有限设备还没链接wifi
                        panel.add(btnConnect);//显示连接按钮
                    }
                    //如果有线设备已经链接了,就不再显示连接按钮
                } else {
                    //这是一个wifi设备
                    panel.add(btnDis);//如果列表里面有wifi设备,证明肯定是链接状态了的,所以只需要显示断开按钮

                    if (!SettingsUtils.isHaveDevice(nowDeviceList.get(row - 1))) {
                        //这个wifi设备还没有保存
                        panel.add(btnSave);//没保存就显示保存按钮,已保存则不显示
                    }
                }

                return panel;
            }
            return null;
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }
    }

    public class HistoryListEditor extends AbstractCellEditor implements TableCellRenderer,
            TableCellEditor {

        private JPanel panel;
        private JButton btnSave = null;
        private JButton btnDis = null;
        private JButton btnConnect = null;
        private int clickRow;

        public HistoryListEditor() {
            initButton();

            initPanel();

            panel.add(btnConnect);
            panel.add(btnDis);
            panel.add(btnSave);
        }

        private void initButton() {
            /**
             * 初始化按钮
             */
            btnConnect = new JButton("链接");
            btnDis = new JButton("断开");
            btnSave = new JButton("删除");

            /**
             * 监听点击
             */
            btnConnect.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n链接");
                    ConnectUtils.connect(historyDeviceList.get(clickRow - 1).get("name") + "");
                    System.out.print(";clickRow:" + clickRow);
                    initList();
                }
            });
            btnDis.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n断开");
                    ConnectUtils.disconnect(historyDeviceList.get(clickRow - 1).get("name") + "");
                    System.out.print(";clickRow:" + clickRow);
                    initList();
                }
            });
            btnSave.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.print("\n删除");
                    System.out.print(";clickRow:" + clickRow);
                    SettingsUtils.removeDevice(historyDeviceList.get(clickRow - 1).get("id") + "");
                    initList();
                }
            });

        }

        /**
         * 初始化画板
         */
        private void initPanel() {
            panel = new JPanel();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            panel.setBackground(new Color(255, 255, 255));
            if (row != 0) {
                panel.removeAll();

                String deviceName=historyDeviceList.get(row-1).get("name")+"";
                if(ConnectUtils.isWifiConnect(nowDeviceList,deviceName)){
                    System.out.print("wifi已连接");
                    //这个wifi设备已经链接
                    panel.add(btnDis);//已连接,显示断开按钮
                }else{
                    //还没链接
                    panel.add(btnConnect);//未连接,显示连接按钮
                }
                panel.add(btnSave);//显示删除按钮
                return panel;
            }
            return null;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                                                     boolean isSelected, int row, int column) {
            clickRow = row;
            panel.setBackground(new Color(255, 255, 255));
            if (row != 0) {
                panel.removeAll();

                String deviceName=historyDeviceList.get(row-1).get("name")+"";
                if(ConnectUtils.isWifiConnect(nowDeviceList,deviceName)){
                    //这个wifi设备已经链接
                    panel.add(btnDis);//已连接,显示断开按钮
                }else{
                    //还没链接
                    panel.add(btnConnect);//未连接,显示连接按钮
                }
                panel.add(btnSave);//显示删除按钮
                return panel;
            }
            return null;
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }
    }

}

6、导出可运行的jar程序

    点击Build->Build Artifacts->All Artifacts->Build

   

    Idea会自动在out目录中生成jar包

    

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章