From 5ae9bbe3583384afab8eb95a134ccb74aee6487a Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期四, 25 十二月 2025 13:46:38 +0800
Subject: [PATCH] 曾加修改密码功能
---
src/lujing/AoxinglujingNoObstacle.java | 78 ++++++
src/set/Sets.java | 57 ++++
set.properties | 4
src/set/xiugaimima.java | 276 +++++++++++++++++++++
src/Mqttmessage/Client.java | 308 ++++++++++++++++++++++-
5 files changed, 700 insertions(+), 23 deletions(-)
diff --git a/set.properties b/set.properties
index ed82d7f..4d5600c 100644
--- a/set.properties
+++ b/set.properties
@@ -1,5 +1,5 @@
#Mower Configuration Properties - Updated
-#Thu Dec 25 12:21:15 CST 2025
+#Thu Dec 25 13:40:36 CST 2025
appVersion=-1
boundaryLengthVisible=false
currentWorkLandNumber=LAND1
@@ -8,7 +8,7 @@
handheldMarkerId=1872
idleTrailDurationSeconds=60
manualBoundaryDrawingMode=false
-mapScale=0.78
+mapScale=0.93
measurementModeEnabled=false
mowerId=6258
serialAutoConnect=true
diff --git a/src/Mqttmessage/Client.java b/src/Mqttmessage/Client.java
index 60be1c3..de7d4a8 100644
--- a/src/Mqttmessage/Client.java
+++ b/src/Mqttmessage/Client.java
@@ -3,6 +3,7 @@
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import set.Setsys;
import user.Usrdell;
@@ -19,6 +20,10 @@
private MqttClient client;
private MqttConnectOptions options;
+ // 闈欐�佸彉閲忕敤浜庡瓨鍌ㄥ鎴风瀹炰緥
+ private static Client gpsClient;
+ private static Client responseClient;
+
/**
* 鏋勯�犲嚱鏁�
* @param host MQTT鏈嶅姟鍣ㄥ湴鍧�锛屾牸寮忥細tcp://ip:port
@@ -26,12 +31,19 @@
* @param clientId 瀹㈡埛绔疘D锛屼笉鑳介噸澶�
*/
public Client(String host, String topic, String clientId) {
-
this.host = host;
this.topic = topic;
this.clientId = clientId;
this.options = new MqttConnectOptions();
this.options.setCleanSession(true);
+ // 璁剧疆杩炴帴瓒呮椂鏃堕棿锛堢锛�
+ this.options.setConnectionTimeout(30);
+ // 璁剧疆KeepAlive闂撮殧锛堢锛夛紝鐢ㄤ簬淇濇寔杩炴帴娲昏穬
+ this.options.setKeepAliveInterval(60);
+ // 璁剧疆鑷姩閲嶈繛
+ this.options.setAutomaticReconnect(true);
+ // 璁剧疆MQTT鐗堟湰锛屼娇鐢�3.1.1
+ this.options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
}
/**
@@ -40,11 +52,28 @@
*/
public void connect() throws MqttException {
if (client != null && client.isConnected()) {
+ System.out.println("MQTT瀹㈡埛绔凡杩炴帴锛孋lientId: " + clientId);
return;
}
- client = new MqttClient(host, clientId);
- client.connect(options);
+
+ // 濡傛灉瀹㈡埛绔凡瀛樺湪浣嗘湭杩炴帴锛屽厛鍏抽棴
+ if (client != null) {
+ try {
+ client.close();
+ } catch (Exception e) {
+ // 蹇界暐鍏抽棴鏃剁殑寮傚父
+ }
+ client = null;
+ }
+
+ // 浣跨敤鍐呭瓨鎸佷箙鍖栵紝閬垮厤鏂囦欢閿佸畾闂
+ client = new MqttClient(host, clientId, new MemoryPersistence());
+ // 鍏堣缃洖璋冿紝鍐嶈繛鎺�
client.setCallback(new PushCallback());
+
+ // 鎵ц杩炴帴
+ client.connect(options);
+ System.out.println("MQTT杩炴帴鎴愬姛锛丆lientId: " + clientId + ", 鏈嶅姟鍣�: " + host + ", 涓婚: " + topic);
}
/**
@@ -78,6 +107,23 @@
}
/**
+ * 鍏抽棴瀹㈡埛绔苟閲婃斁璧勬簮
+ */
+ public void close() {
+ try {
+ if (client != null) {
+ if (client.isConnected()) {
+ client.disconnect();
+ }
+ client.close();
+ client = null;
+ }
+ } catch (Exception e) {
+ // 蹇界暐鍏抽棴鏃剁殑寮傚父
+ }
+ }
+
+ /**
* 妫�鏌ユ槸鍚﹀凡杩炴帴
* @return true琛ㄧず宸茶繛鎺ワ紝false琛ㄧず鏈繛鎺�
*/
@@ -94,29 +140,249 @@
}
/**
- * 绀轰緥鐢ㄦ硶
+ * 杩炴帴MQTT鏈嶅姟鍣ㄧ殑宸ュ叿鏂规硶
+ * 渚涘叾浠栫被鐩存帴璋冪敤锛岃繛鎺PS涓婚鍜屽搷搴斾富棰�
+ * @return true琛ㄧず杩炴帴鎴愬姛锛宖alse琛ㄧず杩炴帴澶辫触
*/
-
- public static void lianjiemqqt() {
+ public static boolean connectMQTT() {
+ // 鍏堟柇寮�涔嬪墠鐨勮繛鎺�
+ disconnectAll();
+
+ boolean gpsSuccess = false;
+ boolean responseSuccess = false;
+
try {
String host = "tcp://39.99.43.227:1883";
- String deiveID=Setsys.getMowerIdValue();
- String clientId =Usrdell.getUserEmail()+"mower";
- String clientId2 =Usrdell.getUserEmail()+"response";
- String topic = "mower/"+deiveID+"/gps";
- String topic2 = "mower/"+deiveID+"/response";
- Client mqttClient = new Client(host, topic, clientId);
- Client mqttClient1 = new Client(host, topic2, clientId2);
- mqttClient.connect();
- mqttClient.subscribe();
+ String deiveID = Setsys.getMowerIdValue();
+ // 娣诲姞鏃堕棿鎴崇‘淇濆鎴风ID鍞竴
+ long timestamp = System.currentTimeMillis();
+ String clientId = Usrdell.getUserEmail() + "mower" + "_" + timestamp;
+ String clientId2 = Usrdell.getUserEmail() + "response" + "_" + timestamp;
+ String topic = "mower/" + deiveID + "/gps";
+ String topic2 = "mower/" + deiveID + "/response";
+
+ // 杩炴帴GPS涓婚
+ try {
+ gpsClient = new Client(host, topic, clientId);
+ gpsClient.connect();
+ // 绋嶄綔寤惰繜锛岀‘淇濊繛鎺ョǔ瀹�
+ Thread.sleep(100);
+ gpsClient.subscribe();
+ gpsSuccess = true;
+ System.out.println("GPS涓婚MQTT杩炴帴骞惰闃呮垚鍔�");
+ } catch (MqttException e) {
+ System.err.println("GPS涓婚MQTT杩炴帴澶辫触: " + e.getMessage());
+ if (e.getCause() != null) {
+ System.err.println("澶辫触鍘熷洜: " + e.getCause().getMessage());
+ }
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.err.println("杩炴帴杩囩▼琚腑鏂�");
+ }
- mqttClient1.connect();
- mqttClient1.subscribe();
+ // 杩炴帴鍝嶅簲涓婚
+ try {
+ responseClient = new Client(host, topic2, clientId2);
+ responseClient.connect();
+ // 绋嶄綔寤惰繜锛岀‘淇濊繛鎺ョǔ瀹�
+ Thread.sleep(100);
+ responseClient.subscribe();
+ responseSuccess = true;
+ System.out.println("鍝嶅簲涓婚MQTT杩炴帴骞惰闃呮垚鍔�");
+ } catch (MqttException e) {
+ System.err.println("鍝嶅簲涓婚MQTT杩炴帴澶辫触: " + e.getMessage());
+ if (e.getCause() != null) {
+ System.err.println("澶辫触鍘熷洜: " + e.getCause().getMessage());
+ }
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.err.println("杩炴帴杩囩▼琚腑鏂�");
+ }
- // 淇濇寔绋嬪簭杩愯
-// Thread.sleep(Long.MAX_VALUE);
- } catch (MqttException e) {
- throw new RuntimeException(e);
+ if (gpsSuccess && responseSuccess) {
+ System.out.println("鎵�鏈塎QTT涓婚杩炴帴骞惰闃呮垚鍔燂紒");
+ return true;
+ } else if (gpsSuccess || responseSuccess) {
+ System.out.println("閮ㄥ垎MQTT涓婚杩炴帴鎴愬姛");
+ return true;
+ } else {
+ System.err.println("鎵�鏈塎QTT涓婚杩炴帴澶辫触");
+ return false;
+ }
+ } catch (Exception e) {
+ System.err.println("MQTT杩炴帴杩囩▼鍙戠敓寮傚父: " + e.getMessage());
+ e.printStackTrace();
+ return false;
}
}
+
+ /**
+ * 杩炴帴MQTT鏈嶅姟鍣ㄧ殑宸ュ叿鏂规硶锛堝甫鍙傛暟鐗堟湰锛�
+ * @param host MQTT鏈嶅姟鍣ㄥ湴鍧�锛屾牸寮忥細tcp://ip:port
+ * @param deviceId 璁惧ID
+ * @param userEmail 鐢ㄦ埛閭
+ * @return true琛ㄧず杩炴帴鎴愬姛锛宖alse琛ㄧず杩炴帴澶辫触
+ */
+ public static boolean connectMQTT(String host, String deviceId, String userEmail) {
+ // 鍏堟柇寮�涔嬪墠鐨勮繛鎺�
+ disconnectAll();
+
+ boolean gpsSuccess = false;
+ boolean responseSuccess = false;
+
+ try {
+ // 娣诲姞鏃堕棿鎴崇‘淇濆鎴风ID鍞竴
+ long timestamp = System.currentTimeMillis();
+ String clientId = userEmail + "mower" + "_" + timestamp;
+ String clientId2 = userEmail + "response" + "_" + timestamp;
+ String topic = "mower/" + deviceId + "/gps";
+ String topic2 = "mower/" + deviceId + "/response";
+
+ // 杩炴帴GPS涓婚
+ try {
+ gpsClient = new Client(host, topic, clientId);
+ gpsClient.connect();
+ // 绋嶄綔寤惰繜锛岀‘淇濊繛鎺ョǔ瀹�
+ Thread.sleep(100);
+ gpsClient.subscribe();
+ gpsSuccess = true;
+ System.out.println("GPS涓婚MQTT杩炴帴骞惰闃呮垚鍔�");
+ } catch (MqttException e) {
+ System.err.println("GPS涓婚MQTT杩炴帴澶辫触: " + e.getMessage());
+ if (e.getCause() != null) {
+ System.err.println("澶辫触鍘熷洜: " + e.getCause().getMessage());
+ }
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.err.println("杩炴帴杩囩▼琚腑鏂�");
+ }
+
+ // 杩炴帴鍝嶅簲涓婚
+ try {
+ responseClient = new Client(host, topic2, clientId2);
+ responseClient.connect();
+ // 绋嶄綔寤惰繜锛岀‘淇濊繛鎺ョǔ瀹�
+ Thread.sleep(100);
+ responseClient.subscribe();
+ responseSuccess = true;
+ System.out.println("鍝嶅簲涓婚MQTT杩炴帴骞惰闃呮垚鍔�");
+ } catch (MqttException e) {
+ System.err.println("鍝嶅簲涓婚MQTT杩炴帴澶辫触: " + e.getMessage());
+ if (e.getCause() != null) {
+ System.err.println("澶辫触鍘熷洜: " + e.getCause().getMessage());
+ }
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.err.println("杩炴帴杩囩▼琚腑鏂�");
+ }
+
+ if (gpsSuccess && responseSuccess) {
+ System.out.println("鎵�鏈塎QTT涓婚杩炴帴骞惰闃呮垚鍔燂紒");
+ return true;
+ } else if (gpsSuccess || responseSuccess) {
+ System.out.println("閮ㄥ垎MQTT涓婚杩炴帴鎴愬姛");
+ return true;
+ } else {
+ System.err.println("鎵�鏈塎QTT涓婚杩炴帴澶辫触");
+ return false;
+ }
+ } catch (Exception e) {
+ System.err.println("MQTT杩炴帴杩囩▼鍙戠敓寮傚父: " + e.getMessage());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 鍒涘缓骞惰繛鎺QTT瀹㈡埛绔殑宸ュ叿鏂规硶
+ * @param host MQTT鏈嶅姟鍣ㄥ湴鍧�
+ * @param topic 璁㈤槄涓婚
+ * @param clientId 瀹㈡埛绔疘D
+ * @param qos 鏈嶅姟璐ㄩ噺绛夌骇锛岄粯璁�2
+ * @return Client瀹炰緥锛岃繛鎺ュけ璐ヨ繑鍥瀗ull
+ */
+ public static Client createAndConnect(String host, String topic, String clientId, int qos) {
+ try {
+ Client mqttClient = new Client(host, topic, clientId);
+ mqttClient.connect();
+ mqttClient.subscribe(qos);
+ System.out.println("MQTT瀹㈡埛绔垱寤哄苟璁㈤槄鎴愬姛锛屼富棰�: " + topic + ", ClientId: " + clientId);
+ return mqttClient;
+ } catch (MqttException e) {
+ System.err.println("MQTT瀹㈡埛绔垱寤哄け璐�: " + e.getMessage() + ", 涓婚: " + topic);
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * 鍒涘缓骞惰繛鎺QTT瀹㈡埛绔殑宸ュ叿鏂规硶锛堥粯璁oS涓�2锛�
+ * @param host MQTT鏈嶅姟鍣ㄥ湴鍧�
+ * @param topic 璁㈤槄涓婚
+ * @param clientId 瀹㈡埛绔疘D
+ * @return Client瀹炰緥锛岃繛鎺ュけ璐ヨ繑鍥瀗ull
+ */
+ public static Client createAndConnect(String host, String topic, String clientId) {
+ return createAndConnect(host, topic, clientId, 2);
+ }
+
+ /**
+ * 鏂紑鎵�鏈塎QTT杩炴帴
+ */
+ public static void disconnectAll() {
+ try {
+ if (gpsClient != null) {
+ gpsClient.close();
+ System.out.println("GPS涓婚MQTT杩炴帴宸叉柇寮�");
+ gpsClient = null;
+ }
+ if (responseClient != null) {
+ responseClient.close();
+ System.out.println("鍝嶅簲涓婚MQTT杩炴帴宸叉柇寮�");
+ responseClient = null;
+ }
+ } catch (Exception e) {
+ System.err.println("鏂紑MQTT杩炴帴澶辫触: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 鑾峰彇GPS瀹㈡埛绔疄渚�
+ * @return GPS瀹㈡埛绔疄渚�
+ */
+ public static Client getGpsClient() {
+ return gpsClient;
+ }
+
+ /**
+ * 鑾峰彇鍝嶅簲瀹㈡埛绔疄渚�
+ * @return 鍝嶅簲瀹㈡埛绔疄渚�
+ */
+ public static Client getResponseClient() {
+ return responseClient;
+ }
+
+ /**
+ * 妫�鏌QTT杩炴帴鐘舵�侊紙闈欐�佹柟娉曪級
+ * @return true琛ㄧず宸茶繛鎺ワ紝false琛ㄧず鏈繛鎺�
+ */
+ public static boolean areClientsConnected() {
+ boolean gpsConnected = gpsClient != null && gpsClient.isConnected();
+ boolean responseConnected = responseClient != null && responseClient.isConnected();
+ return gpsConnected || responseConnected;
+ }
+
+ /**
+ * 绀轰緥鐢ㄦ硶锛堜繚鐣欏悜鍚庡吋瀹癸級
+ * @deprecated 璇蜂娇鐢� connectMQTT() 鏂规硶鏇夸唬
+ */
+ @Deprecated
+ public static void lianjiemqqt() {
+ connectMQTT();
+ }
}
\ No newline at end of file
diff --git a/src/lujing/AoxinglujingNoObstacle.java b/src/lujing/AoxinglujingNoObstacle.java
index fe884f9..4bdf628 100644
--- a/src/lujing/AoxinglujingNoObstacle.java
+++ b/src/lujing/AoxinglujingNoObstacle.java
@@ -38,6 +38,14 @@
return planPathCore(originalPolygon, width, margin);
}
+ /**
+ * 鏍稿績璺緞瑙勫垝閫昏緫
+ *
+ * @param originalPolygon 鍘熷澶氳竟褰㈤《鐐瑰垪琛�
+ * @param width 鍓茶崏瀹藉害
+ * @param margin 瀹夊叏杈硅窛
+ * @return 瑙勫垝濂界殑璺緞娈靛垪琛�
+ */
private static List<PathSegment> planPathCore(List<Point> originalPolygon, double width, double margin) {
if (originalPolygon.size() < 3) return new ArrayList<>();
@@ -74,6 +82,11 @@
/**
* 瀵绘壘寮撳瓧褰㈢殑绗竴鏉$嚎鐨勮捣鐐�
+ *
+ * @param polygon 澶氳竟褰㈤《鐐瑰垪琛�
+ * @param angle 鎵弿瑙掑害
+ * @param width 鍓茶崏瀹藉害
+ * @return 鎵弿璧风偣鐨勫潗鏍�
*/
private static Point getFirstScanStartPoint(List<Point> polygon, double angle, double width) {
List<Point> rotated = rotatePolygon(polygon, -angle);
@@ -90,6 +103,10 @@
/**
* 閲嶇粍澶氳竟褰㈤《鐐癸紝浣垮緱绱㈠紩0鐨勭偣鏈�闈犺繎濉厖璧风偣
+ *
+ * @param polygon 澶氳竟褰㈤《鐐瑰垪琛�
+ * @param target 鐩爣鐐癸紙濉厖璧风偣锛�
+ * @return 閲嶇粍鍚庣殑澶氳竟褰㈤《鐐瑰垪琛�
*/
private static List<Point> alignBoundaryToStart(List<Point> polygon, Point target) {
int bestIdx = 0;
@@ -108,6 +125,15 @@
return aligned;
}
+ /**
+ * 鐢熸垚寮撳瓧褰㈡壂鎻忚矾寰�
+ *
+ * @param polygon 澶氳竟褰㈤《鐐瑰垪琛�
+ * @param angle 鎵弿瑙掑害
+ * @param width 鍓茶崏瀹藉害
+ * @param startPoint 璧峰鐐�
+ * @return 寮撳瓧褰㈣矾寰勬鍒楄〃
+ */
private static List<PathSegment> generateZigZagPath(List<Point> polygon, double angle, double width, Point startPoint) {
List<PathSegment> result = new ArrayList<>();
List<Point> rotated = rotatePolygon(polygon, -angle);
@@ -143,6 +169,13 @@
return result;
}
+ /**
+ * 鑾峰彇鎵弿绾夸笌澶氳竟褰㈢殑浜ょ偣X鍧愭爣鍒楄〃
+ *
+ * @param rotatedPoly 鏃嬭浆鍚庣殑澶氳竟褰�
+ * @param y 鎵弿绾跨殑Y鍧愭爣
+ * @return 浜ょ偣X鍧愭爣鍒楄〃
+ */
private static List<Double> getXIntersections(List<Point> rotatedPoly, double y) {
List<Double> xIntersections = new ArrayList<>();
int n = rotatedPoly.size();
@@ -159,6 +192,13 @@
// --- 鍑犱綍鍩虹宸ュ叿 ---
+ /**
+ * 澶氳竟褰㈠唴缂╋紙璁$畻瀹夊叏宸ヤ綔鍖哄煙锛�
+ *
+ * @param polygon 鍘熷澶氳竟褰�
+ * @param margin 鍐呯缉璺濈
+ * @return 鍐呯缉鍚庣殑澶氳竟褰�
+ */
private static List<Point> shrinkPolygon(List<Point> polygon, double margin) {
List<Point> result = new ArrayList<>();
int n = polygon.size();
@@ -187,6 +227,12 @@
return result;
}
+ /**
+ * 瀵绘壘鏈�浼樻壂鎻忚搴︼紙浣挎壂鎻忕嚎鏁伴噺鏈�灏戯級
+ *
+ * @param polygon 澶氳竟褰�
+ * @return 鏈�浼樿搴︼紙寮у害锛�
+ */
private static double findOptimalScanAngle(List<Point> polygon) {
double minH = Double.MAX_VALUE;
double bestA = 0;
@@ -199,6 +245,13 @@
return bestA;
}
+ /**
+ * 璁$畻澶氳竟褰㈠湪鐗瑰畾瑙掑害涓嬬殑楂樺害锛堟姇褰遍暱搴︼級
+ *
+ * @param poly 澶氳竟褰�
+ * @param angle 瑙掑害
+ * @return 楂樺害
+ */
private static double calculatePolygonHeightAtAngle(List<Point> poly, double angle) {
double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
double sin = Math.sin(-angle), cos = Math.cos(-angle);
@@ -209,17 +262,36 @@
return maxY - minY;
}
+ /**
+ * 鏃嬭浆鐐�
+ *
+ * @param p 鐐�
+ * @param angle 鏃嬭浆瑙掑害
+ * @return 鏃嬭浆鍚庣殑鐐�
+ */
private static Point rotatePoint(Point p, double angle) {
double c = Math.cos(angle), s = Math.sin(angle);
return new Point(p.x * c - p.y * s, p.x * s + p.y * c);
}
+ /**
+ * 鏃嬭浆澶氳竟褰�
+ *
+ * @param poly 澶氳竟褰�
+ * @param angle 鏃嬭浆瑙掑害
+ * @return 鏃嬭浆鍚庣殑澶氳竟褰�
+ */
private static List<Point> rotatePolygon(List<Point> poly, double angle) {
List<Point> res = new ArrayList<>();
for (Point p : poly) res.add(rotatePoint(p, angle));
return res;
}
+ /**
+ * 纭繚澶氳竟褰㈤《鐐逛负閫嗘椂閽堥『搴�
+ *
+ * @param poly 澶氳竟褰�
+ */
private static void ensureCCW(List<Point> poly) {
double s = 0;
for (int i = 0; i < poly.size(); i++) {
@@ -229,6 +301,12 @@
if (s > 0) Collections.reverse(poly);
}
+ /**
+ * 瑙f瀽鍧愭爣瀛楃涓�
+ *
+ * @param s 鍧愭爣瀛楃涓� (鏍煎紡: "x1,y1;x2,y2;...")
+ * @return 鐐瑰垪琛�
+ */
private static List<Point> parseCoords(String s) {
List<Point> list = new ArrayList<>();
for (String p : s.split(";")) {
diff --git a/src/set/Sets.java b/src/set/Sets.java
index 2379b27..bbc0160 100644
--- a/src/set/Sets.java
+++ b/src/set/Sets.java
@@ -193,6 +193,9 @@
JPanel manualBoundaryDrawingPanel = createManualBoundaryDrawingPanel();
manualBoundaryDrawingModeLabel = (JLabel) manualBoundaryDrawingPanel.getClientProperty("valueLabel");
+ // 淇敼瀵嗙爜璁剧疆椤�
+ JPanel changePasswordPanel = createChangePasswordPanel();
+
JPanel feedbackPanel = createFeedbackPanel();
// APP鐗堟湰
@@ -214,6 +217,7 @@
addSettingItem(panel, boundaryLengthPanel, true);
addSettingItem(panel, measurementModePanel, true);
addSettingItem(panel, manualBoundaryDrawingPanel, true);
+ addSettingItem(panel, changePasswordPanel, true);
addSettingItem(panel, feedbackPanel, true);
addSettingItem(panel, appVersionPanel, true);
addSettingItem(panel, logoutPanel, false); // 鏈�鍚庝竴椤逛笉鍔犲垎鍓茬嚎
@@ -1860,4 +1864,57 @@
return panel;
}
+
+ /**
+ * 鍒涘缓淇敼瀵嗙爜璁剧疆闈㈡澘
+ */
+ private JPanel createChangePasswordPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
+ panel.setOpaque(false);
+ panel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT));
+ panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT));
+ panel.setMinimumSize(new Dimension(0, ROW_HEIGHT));
+ panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING));
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ JLabel titleLabel = new JLabel("淇敼瀵嗙爜");
+ titleLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 14));
+ titleLabel.setForeground(Color.BLACK);
+ titleLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.weightx = 0;
+ gbc.anchor = GridBagConstraints.EAST;
+ gbc.insets = new Insets(0, 0, 0, 12);
+ panel.add(titleLabel, gbc);
+
+ JLabel valueLabel = new JLabel("******");
+ valueLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
+ valueLabel.setForeground(Color.DARK_GRAY);
+ gbc = new GridBagConstraints();
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ gbc.weightx = 1.0;
+ gbc.anchor = GridBagConstraints.EAST;
+ panel.add(valueLabel, gbc);
+
+ JButton editBtn = createEditButton();
+ editBtn.addActionListener(e -> {
+ SwingUtilities.invokeLater(() -> {
+ xiugaimima dialog = new xiugaimima((Frame) SwingUtilities.getWindowAncestor(this));
+ dialog.setVisible(true);
+ });
+ });
+
+ gbc = new GridBagConstraints();
+ gbc.gridx = 2;
+ gbc.gridy = 0;
+ gbc.weightx = 0;
+ gbc.anchor = GridBagConstraints.EAST;
+ panel.add(editBtn, gbc);
+
+ return panel;
+ }
}
\ No newline at end of file
diff --git a/src/set/xiugaimima.java b/src/set/xiugaimima.java
new file mode 100644
index 0000000..c7ff19a
--- /dev/null
+++ b/src/set/xiugaimima.java
@@ -0,0 +1,276 @@
+package set;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import user.Usrdell;
+
+public class xiugaimima extends JDialog {
+ private static final long serialVersionUID = 1L;
+ private JPasswordField oldPasswordField;
+ private JPasswordField newPasswordField;
+ private JPasswordField confirmPasswordField;
+ private JButton saveButton;
+ private JButton cancelButton;
+ private JLabel errorLabel;
+ private final Color THEME_COLOR = new Color(46, 139, 87);
+
+ public xiugaimima(Frame owner) {
+ super(owner, "淇敼瀵嗙爜", true);
+ initializeUI();
+ }
+
+ private void initializeUI() {
+ setLayout(new BorderLayout());
+ setSize(400, 350);
+ setLocationRelativeTo(getOwner());
+ setResizable(false);
+
+ JPanel mainPanel = new JPanel(new GridBagLayout());
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ mainPanel.setBackground(Color.WHITE);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.insets = new Insets(10, 10, 10, 10);
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+
+ // 鍘熷瘑鐮�
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.weightx = 0;
+ mainPanel.add(new JLabel("鍘熷瘑鐮�:"), gbc);
+
+ oldPasswordField = createStyledPasswordField();
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ gbc.weightx = 1.0;
+ mainPanel.add(oldPasswordField, gbc);
+
+ // 鏂板瘑鐮�
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.weightx = 0;
+ mainPanel.add(new JLabel("鏂板瘑鐮�:"), gbc);
+
+ JPanel newPasswordPanel = createPasswordPanelWithEye(newPasswordField = createStyledPasswordField());
+ gbc.gridx = 1;
+ gbc.gridy = 1;
+ gbc.weightx = 1.0;
+ mainPanel.add(newPasswordPanel, gbc);
+
+ // 纭瀵嗙爜
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ gbc.weightx = 0;
+ mainPanel.add(new JLabel("纭瀵嗙爜:"), gbc);
+
+ JPanel confirmPasswordPanel = createPasswordPanelWithEye(confirmPasswordField = createStyledPasswordField());
+ gbc.gridx = 1;
+ gbc.gridy = 2;
+ gbc.weightx = 1.0;
+ mainPanel.add(confirmPasswordPanel, gbc);
+
+ // 閿欒鎻愮ず淇℃伅
+ errorLabel = new JLabel("瀵嗙爜闀垮害涓嶈兘灏忎簬6涓瓧绗�");
+ errorLabel.setForeground(Color.GRAY);
+ errorLabel.setFont(new Font("PingFang SC", Font.PLAIN, 12));
+ gbc.gridx = 1;
+ gbc.gridy = 3;
+ gbc.gridwidth = 2;
+ gbc.insets = new Insets(0, 10, 10, 10);
+ mainPanel.add(errorLabel, gbc);
+
+ // 娣诲姞瀵嗙爜杈撳叆鐩戝惉
+ DocumentListener passwordListener = new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) { checkPasswords(); }
+ @Override
+ public void removeUpdate(DocumentEvent e) { checkPasswords(); }
+ @Override
+ public void changedUpdate(DocumentEvent e) { checkPasswords(); }
+ };
+ newPasswordField.getDocument().addDocumentListener(passwordListener);
+ confirmPasswordField.getDocument().addDocumentListener(passwordListener);
+
+ add(mainPanel, BorderLayout.CENTER);
+
+ // 鎸夐挳闈㈡澘
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
+ buttonPanel.setBackground(Color.WHITE);
+
+ saveButton = new JButton("淇濆瓨");
+ saveButton.setBackground(THEME_COLOR);
+ saveButton.setForeground(Color.WHITE);
+ saveButton.setFocusPainted(false);
+ saveButton.setPreferredSize(new Dimension(100, 35));
+ saveButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ handleSave();
+ }
+ });
+
+ cancelButton = new JButton("鍙栨秷");
+ cancelButton.setBackground(new Color(240, 240, 240));
+ cancelButton.setForeground(Color.BLACK);
+ cancelButton.setFocusPainted(false);
+ cancelButton.setPreferredSize(new Dimension(100, 35));
+ cancelButton.addActionListener(e -> dispose());
+
+ buttonPanel.add(saveButton);
+ buttonPanel.add(cancelButton);
+
+ add(buttonPanel, BorderLayout.SOUTH);
+ }
+
+ private JPasswordField createStyledPasswordField() {
+ JPasswordField field = new JPasswordField(15);
+ field.setPreferredSize(new Dimension(200, 38)); // 璁剧疆楂樺害涓�38锛屼笌鐧诲綍椤甸潰涓�鑷�
+ field.setFont(new Font("PingFang SC", Font.PLAIN, 14));
+ field.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(200, 200, 200)),
+ BorderFactory.createEmptyBorder(8, 10, 8, 10)
+ ));
+ field.setForeground(new Color(60, 60, 60));
+ return field;
+ }
+
+ private JPanel createPasswordPanelWithEye(JPasswordField passwordField) {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setBackground(Color.WHITE);
+ // 灏嗚竟妗嗙Щ鍔ㄥ埌 Panel 涓婏紝妯℃嫙鏂囨湰妗嗗瑙�
+ panel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(200, 200, 200)),
+ BorderFactory.createEmptyBorder(0, 0, 0, 5)
+ ));
+ panel.setPreferredSize(new Dimension(200, 38));
+
+ // 绉婚櫎 Field 鐨勮竟妗嗭紝浣垮叾铻嶅叆 Panel
+ passwordField.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 0));
+ passwordField.setPreferredSize(null); // 璁� BorderLayout 绠$悊澶у皬
+
+ panel.add(passwordField, BorderLayout.CENTER);
+
+ JLabel eyeLabel = new JLabel();
+ eyeLabel.setPreferredSize(new Dimension(30, 38));
+ eyeLabel.setHorizontalAlignment(SwingConstants.CENTER);
+ eyeLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
+
+ // 榛樿闂溂鍥炬爣
+ eyeLabel.setText("馃憗");
+ eyeLabel.setForeground(Color.GRAY);
+
+ eyeLabel.addMouseListener(new MouseAdapter() {
+ private boolean isVisible = false;
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ isVisible = !isVisible;
+ if (isVisible) {
+ passwordField.setEchoChar((char) 0);
+ eyeLabel.setForeground(THEME_COLOR);
+ } else {
+ passwordField.setEchoChar('鈥�');
+ eyeLabel.setForeground(Color.GRAY);
+ }
+ }
+ });
+
+ panel.add(eyeLabel, BorderLayout.EAST);
+ return panel;
+ }
+
+ private void checkPasswords() {
+ String newPass = new String(newPasswordField.getPassword());
+ String confirmPass = new String(confirmPasswordField.getPassword());
+
+ // 榛樿鎻愮ず
+ if (newPass.isEmpty() && confirmPass.isEmpty()) {
+ errorLabel.setText("瀵嗙爜闀垮害涓嶈兘灏忎簬6涓瓧绗�");
+ errorLabel.setForeground(Color.GRAY);
+ return;
+ }
+
+ // 闀垮害妫�鏌�
+ if (newPass.length() > 0 && newPass.length() < 6) {
+ errorLabel.setText("瀵嗙爜闀垮害涓嶈兘灏忎簬6涓瓧绗�");
+ errorLabel.setForeground(Color.RED);
+ return;
+ }
+
+ // 涓�鑷存�ф鏌�
+ if (confirmPass.length() > 0) {
+ if (confirmPass.length() == newPass.length()) {
+ if (!newPass.equals(confirmPass)) {
+ errorLabel.setText("涓ゆ杈撳叆鐨勬柊瀵嗙爜涓嶄竴鑷�");
+ errorLabel.setForeground(Color.RED);
+ } else {
+ errorLabel.setText(" "); // 瀵嗙爜涓�鑷翠笖闀垮害绗﹀悎瑕佹眰
+ }
+ } else if (confirmPass.length() < newPass.length()) {
+ // 姝e湪杈撳叆涓紝濡傛灉涔嬪墠鏈夐敊璇彁绀猴紝鍙互娓呴櫎鎴栨仮澶嶉粯璁�
+ if (newPass.length() >= 6) {
+ errorLabel.setText(" ");
+ }
+ } else {
+ // 纭瀵嗙爜姣旀柊瀵嗙爜闀匡紝鑲畾涓嶄竴鑷�
+ errorLabel.setText("涓ゆ杈撳叆鐨勬柊瀵嗙爜涓嶄竴鑷�");
+ errorLabel.setForeground(Color.RED);
+ }
+ } else {
+ // 纭瀵嗙爜涓虹┖锛屽鏋滄柊瀵嗙爜绗﹀悎闀垮害锛屾竻闄ら敊璇紙鎴栬�呮樉绀洪粯璁ゆ彁绀猴級
+ if (newPass.length() >= 6) {
+ errorLabel.setText(" ");
+ }
+ }
+ }
+
+ private void handleSave() {
+ // 娓呴櫎涔嬪墠鐨勯敊璇俊鎭�
+ // errorLabel.setText(" "); // 涓嶅啀寮哄埗娓呴櫎锛屼緷璧� checkPasswords 鐨勭姸鎬侊紝鎴栬�呴噸鏂版鏌�
+
+ String oldPass = new String(oldPasswordField.getPassword());
+ String newPass = new String(newPasswordField.getPassword());
+ String confirmPass = new String(confirmPasswordField.getPassword());
+
+ if (oldPass.isEmpty() || newPass.isEmpty() || confirmPass.isEmpty()) {
+ errorLabel.setText("璇峰~鍐欐墍鏈夊瓧娈�");
+ errorLabel.setForeground(Color.RED);
+ return;
+ }
+
+ if (newPass.length() < 6) {
+ errorLabel.setText("鏂板瘑鐮侀暱搴︿笉鑳藉皬浜�6涓瓧绗�");
+ errorLabel.setForeground(Color.RED);
+ return;
+ }
+
+ String currentStoredPassword = Usrdell.getProperty("password");
+ if (currentStoredPassword == null) {
+ currentStoredPassword = "";
+ }
+
+ if (!oldPass.equals(currentStoredPassword)) {
+ errorLabel.setText("鍘熷瘑鐮侀敊璇�");
+ errorLabel.setForeground(Color.RED);
+ return;
+ }
+
+ if (!newPass.equals(confirmPass)) {
+ errorLabel.setText("涓ゆ杈撳叆鐨勬柊瀵嗙爜涓嶄竴鑷�");
+ errorLabel.setForeground(Color.RED);
+ return;
+ }
+
+ // 鏇存柊瀵嗙爜
+ Usrdell.updateProperty("password", newPass);
+ JOptionPane.showMessageDialog(this, "瀵嗙爜淇敼鎴愬姛", "鎻愮ず", JOptionPane.INFORMATION_MESSAGE);
+ dispose();
+ }
+}
+
--
Gitblit v1.10.0