廢話
一直在用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包