From 6700283f9103a45bc087838ebf3eeeeb9022dd98 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 19 十二月 2025 12:11:45 +0800
Subject: [PATCH] 新增了割草机长宽和割草安全距离属性

---
 src/gecaoji/Device.java                        |   51 ++++++
 device.properties                              |    8 
 src/set/Sets.java                              |  281 +++++++++++++++++++++++++++++++++++
 set.properties                                 |    4 
 src/gecaoji/MowerSafetyDistanceCalculator.java |   98 ++++++++++++
 5 files changed, 438 insertions(+), 4 deletions(-)

diff --git a/device.properties b/device.properties
index 260ace6..36d438d 100644
--- a/device.properties
+++ b/device.properties
@@ -1,5 +1,5 @@
-#Updated base station information
-#Thu Dec 18 16:15:01 CST 2025
+#Updated device properties
+#Fri Dec 19 12:08:39 CST 2025
 BupdateTime=-1
 GupdateTime=-1
 baseStationCardNumber=-1
@@ -11,12 +11,15 @@
 differentialAge=-1
 heading=-1
 mowerBladeHeight=-1
+mowerLength=3.00
 mowerLightStatus=-1
 mowerModel=-1
 mowerName=-1
 mowerNumber=-1
 mowerStartStatus=-1
+mowerWidth=2.00
 mowingHeight=-1
+mowingSafetyDistance=1.86
 mowingWidth=-1
 pitch=-1
 positioningStatus=-1
@@ -27,3 +30,4 @@
 realtimeX=-1
 realtimeY=-1
 satelliteCount=-1
+selfCheckStatus=-1
diff --git a/set.properties b/set.properties
index 3bd8130..13c296d 100644
--- a/set.properties
+++ b/set.properties
@@ -1,5 +1,5 @@
-#Mower Configuration Properties - Updated
-#Fri Dec 19 11:48:07 CST 2025
+#Current work land selection updated
+#Fri Dec 19 12:08:28 CST 2025
 appVersion=-1
 boundaryLengthVisible=false
 currentWorkLandNumber=LAND1
diff --git a/src/gecaoji/Device.java b/src/gecaoji/Device.java
index fd7cae4..d37e21f 100644
--- a/src/gecaoji/Device.java
+++ b/src/gecaoji/Device.java
@@ -83,6 +83,12 @@
     // 鍓茶崏鏈虹伅寮�鍏崇姸鎬侊細1寮�鍚紝0鍏抽棴锛�-1鏈煡
     private String mowerBladeHeight = "-1";
     // 鍓茶崏鏈哄垁鐩橀珮搴︼細-1鏈煡
+    private String mowerWidth;
+    // 鍓茶崏鏈哄搴︼紝鍗曚綅绫�
+    private String mowerLength;
+    // 鍓茶崏鏈洪暱搴︼紝鍗曚綅绫�
+    private String mowingSafetyDistance;
+    // 鍓茶崏瀹夊叏璺濈锛屽崟浣嶇背
 
     private static final double METERS_PER_DEGREE_LAT = 111320.0d;
     
@@ -155,6 +161,9 @@
         if (mowerStartStatus != null) properties.setProperty("mowerStartStatus", mowerStartStatus);
         if (mowerLightStatus != null) properties.setProperty("mowerLightStatus", mowerLightStatus);
         if (mowerBladeHeight != null) properties.setProperty("mowerBladeHeight", mowerBladeHeight);
+        if (mowerWidth != null) properties.setProperty("mowerWidth", mowerWidth);
+        if (mowerLength != null) properties.setProperty("mowerLength", mowerLength);
+        if (mowingSafetyDistance != null) properties.setProperty("mowingSafetyDistance", mowingSafetyDistance);
         
         // 淇濆瓨鍒版枃浠�
         try (FileOutputStream output = new FileOutputStream("device.properties");
@@ -198,6 +207,9 @@
         target.mowerStartStatus = properties.getProperty("mowerStartStatus", "-1");
         target.mowerLightStatus = properties.getProperty("mowerLightStatus", "-1");
         target.mowerBladeHeight = properties.getProperty("mowerBladeHeight", "-1");
+        target.mowerWidth = properties.getProperty("mowerWidth", "-1");
+        target.mowerLength = properties.getProperty("mowerLength", "-1");
+        target.mowingSafetyDistance = properties.getProperty("mowingSafetyDistance", "-1");
     }
 
     private void applyDefaults(Device target) {
@@ -233,6 +245,9 @@
         target.mowerStartStatus = "-1";
         target.mowerLightStatus = "-1";
         target.mowerBladeHeight = "-1";
+        target.mowerWidth = "-1";
+        target.mowerLength = "-1";
+        target.mowingSafetyDistance = "-1";
     }
 
     public static synchronized Device initializeActiveDevice(String mowerId) { // 鏍规嵁璁惧ID鍒濆鍖栨椿璺冭澶�
@@ -343,6 +358,15 @@
             case "mowerBladeHeight":
                 this.mowerBladeHeight = value;
                 return true;
+            case "mowerWidth":
+                this.mowerWidth = value;
+                return true;
+            case "mowerLength":
+                this.mowerLength = value;
+                return true;
+            case "mowingSafetyDistance":
+                this.mowingSafetyDistance = value;
+                return true;
             default:
                 System.err.println("鏈煡瀛楁: " + fieldName);
                 return false;
@@ -835,6 +859,30 @@
         this.mowerBladeHeight = mowerBladeHeight;
     }
 
+    public String getMowerWidth() { // 鑾峰彇鍓茶崏鏈哄搴�
+        return mowerWidth;
+    }
+
+    public void setMowerWidth(String mowerWidth) { // 璁剧疆鍓茶崏鏈哄搴�
+        this.mowerWidth = mowerWidth;
+    }
+
+    public String getMowerLength() { // 鑾峰彇鍓茶崏鏈洪暱搴�
+        return mowerLength;
+    }
+
+    public void setMowerLength(String mowerLength) { // 璁剧疆鍓茶崏鏈洪暱搴�
+        this.mowerLength = mowerLength;
+    }
+
+    public String getMowingSafetyDistance() { // 鑾峰彇鍓茶崏瀹夊叏璺濈
+        return mowingSafetyDistance;
+    }
+
+    public void setMowingSafetyDistance(String mowingSafetyDistance) { // 璁剧疆鍓茶崏瀹夊叏璺濈
+        this.mowingSafetyDistance = mowingSafetyDistance;
+    }
+
     @Override
     public String toString() { // 杈撳嚭瀵硅薄淇℃伅
         return "Device{" +
@@ -866,6 +914,9 @@
                 ", mowerStartStatus='" + mowerStartStatus + '\'' +
                 ", mowerLightStatus='" + mowerLightStatus + '\'' +
                 ", mowerBladeHeight='" + mowerBladeHeight + '\'' +
+                ", mowerWidth='" + mowerWidth + '\'' +
+                ", mowerLength='" + mowerLength + '\'' +
+                ", mowingSafetyDistance='" + mowingSafetyDistance + '\'' +
                 '}';
     }
 }
\ No newline at end of file
diff --git a/src/gecaoji/MowerSafetyDistanceCalculator.java b/src/gecaoji/MowerSafetyDistanceCalculator.java
new file mode 100644
index 0000000..8134855
--- /dev/null
+++ b/src/gecaoji/MowerSafetyDistanceCalculator.java
@@ -0,0 +1,98 @@
+package gecaoji;
+
+import java.text.DecimalFormat;
+
+/**
+ * 鍓茶崏鏈哄畨鍏ㄨ窛绂昏绠楀櫒
+ * 鏍规嵁鍓茶崏鏈哄昂瀵稿拰RTK瀹氫綅绮惧害璁$畻浣滀笟鏃剁殑瀹夊叏璺濈
+ */
+public class MowerSafetyDistanceCalculator {
+    
+    // RTK瀹氫綅绮惧害锛堝崟浣嶏細绫筹級
+    private static final double RTK_ACCURACY = 0.03;
+    
+    /**
+     * 璁$畻缁煎悎瀹夊叏璺濈
+     * @param length 鍓茶崏鏈洪暱搴︼紙绫筹級
+     * @param width 鍓茶崏鏈哄搴︼紙绫筹級
+     * @return 缁煎悎瀹夊叏璺濈锛堢背锛夛紝淇濈暀涓や綅灏忔暟
+     */
+    public static double calculateSafetyDistance(double length, double width) {
+        // 楠岃瘉杈撳叆鍙傛暟
+        if (length <= 0 || width <= 0) {
+            throw new IllegalArgumentException("鍓茶崏鏈洪暱搴﹀拰瀹藉害蹇呴』涓烘鏁�");
+        }
+        
+        // 璁$畻鐩寸嚎琛岄┒鏃剁殑渚у悜瀹夊叏璺濈锛堜笉鍚宸ˉ鍋匡級
+        double lateralSafety = width / 2;
+        
+        // 璁$畻鍘熷湴鎺夊ご鏃剁殑鏃嬭浆鍗婂緞
+        double diagonal = Math.sqrt(length * length + width * width);
+        double turnRadius = diagonal / 2;
+        
+        // 璁$畻缁煎悎瀹夊叏璺濈锛堝彇鏈�澶у�� + RTK璇樊琛ュ伩锛�
+        double safetyDistance = Math.max(lateralSafety, turnRadius) + 2 * RTK_ACCURACY;
+        
+        // 淇濈暀涓や綅灏忔暟
+        DecimalFormat df = new DecimalFormat("#.##");
+        return Double.parseDouble(df.format(safetyDistance));
+    }
+    
+    /**
+     * 璁$畻鐩寸嚎琛岄┒鏃剁殑鏈�灏忎晶鍚戝畨鍏ㄨ窛绂�
+     * @param width 鍓茶崏鏈哄搴︼紙绫筹級
+     * @return 渚у悜瀹夊叏璺濈锛堢背锛夛紝淇濈暀涓や綅灏忔暟
+     */
+    public static double calculateLateralSafetyDistance(double width) {
+        if (width <= 0) {
+            throw new IllegalArgumentException("鍓茶崏鏈哄搴﹀繀椤讳负姝f暟");
+        }
+        
+        double lateralSafety = width / 2 + 2 * RTK_ACCURACY;
+        
+        DecimalFormat df = new DecimalFormat("#.##");
+        return Double.parseDouble(df.format(lateralSafety));
+    }
+    
+    /**
+     * 璁$畻鍘熷湴鎺夊ご鎵�闇�鐨勫畨鍏ㄥ崐寰�
+     * @param length 鍓茶崏鏈洪暱搴︼紙绫筹級
+     * @param width 鍓茶崏鏈哄搴︼紙绫筹級
+     * @return 鎺夊ご瀹夊叏鍗婂緞锛堢背锛夛紝淇濈暀涓や綅灏忔暟
+     */
+    public static double calculateTurnSafetyRadius(double length, double width) {
+        if (length <= 0 || width <= 0) {
+            throw new IllegalArgumentException("鍓茶崏鏈洪暱搴﹀拰瀹藉害蹇呴』涓烘鏁�");
+        }
+        
+        double diagonal = Math.sqrt(length * length + width * width);
+        double turnRadius = diagonal / 2 + 2 * RTK_ACCURACY;
+        
+        DecimalFormat df = new DecimalFormat("#.##");
+        return Double.parseDouble(df.format(turnRadius));
+    }
+    
+    /**
+     * 璁$畻涓よ涔嬮棿鐨勬帹鑽愰棿璺濓紙鐢ㄤ簬骞宠绾胯矾寰勮鍒掞級
+     * @param cuttingWidth 鍓茶崏瀹藉害锛堢背锛�
+     * @return 琛岄棿璺濓紙绫筹級锛屼繚鐣欎袱浣嶅皬鏁�
+     */
+    public static double calculateRowSpacing(double cuttingWidth) {
+        if (cuttingWidth <= 0) {
+            throw new IllegalArgumentException("鍓茶崏瀹藉害蹇呴』涓烘鏁�");
+        }
+        
+        // 鑰冭檻鍙屽悜璇樊鍙犲姞
+        double rowSpacing = cuttingWidth - 2 * RTK_ACCURACY;
+        
+        // 纭繚琛岄棿璺濅负姝f暟
+        if (rowSpacing <= 0) {
+            System.out.println("璀﹀憡锛氬壊鑽夊搴﹁繃灏忥紝鏃犳硶淇濊瘉鍏ㄨ鐩�");
+            rowSpacing = cuttingWidth; // 杩斿洖鍘熷鍊�
+        }
+        
+        DecimalFormat df = new DecimalFormat("#.##");
+        return Double.parseDouble(df.format(rowSpacing));
+    }    
+    
+}
\ No newline at end of file
diff --git a/src/set/Sets.java b/src/set/Sets.java
index 9a4d8c2..5b2bafa 100644
--- a/src/set/Sets.java
+++ b/src/set/Sets.java
@@ -1,6 +1,8 @@
 package set;
 
 import baseStation.BaseStation;
+import gecaoji.Device;
+import gecaoji.MowerSafetyDistanceCalculator;
 
 import zhuye.MapRenderer;
 import zhuye.Shouye;
@@ -32,6 +34,8 @@
     
     // 璁剧疆椤圭粍浠�
     private JLabel mowerIdLabel;
+    private JLabel mowerSizeLabel;
+    private JLabel mowingSafetyDistanceLabel;
     private JLabel baseStationIdLabel;
     private JLabel handheldMarkerLabel;
     private JLabel simCardNumberLabel;
@@ -43,6 +47,8 @@
     private JLabel measurementModeEnabledLabel;
     
     private JButton mowerIdEditBtn;
+    private JButton mowerSizeEditBtn;
+    private JButton mowingSafetyDistanceEditBtn;
     private JButton baseStationIdEditBtn;
     private JButton handheldEditBtn;
     private JButton checkUpdateBtn;
@@ -123,6 +129,18 @@
         mowerIdLabel = (JLabel) mowerIdPanel.getClientProperty("valueLabel");
         mowerIdEditBtn = (JButton) mowerIdPanel.getClientProperty("editButton");
 
+        // 鍓茶崏鏈洪暱瀹�
+        JPanel mowerSizePanel = createSettingItemPanel("鍓茶崏鏈洪暱瀹�",
+            formatMowerSize(), true);
+        mowerSizeLabel = (JLabel) mowerSizePanel.getClientProperty("valueLabel");
+        mowerSizeEditBtn = (JButton) mowerSizePanel.getClientProperty("editButton");
+
+        // 鍓茶崏瀹夊叏璺濈
+        JPanel mowingSafetyDistancePanel = createSettingItemPanel("鍓茶崏瀹夊叏璺濈",
+            formatMowingSafetyDistance(), true);
+        mowingSafetyDistanceLabel = (JLabel) mowingSafetyDistancePanel.getClientProperty("valueLabel");
+        mowingSafetyDistanceEditBtn = (JButton) mowingSafetyDistancePanel.getClientProperty("editButton");
+
         JPanel baseStationIdPanel = createSettingItemPanel("宸垎鍩哄噯绔欑紪鍙�",
             resolveBaseStationId(), true);
         baseStationIdLabel = (JLabel) baseStationIdPanel.getClientProperty("valueLabel");
@@ -167,6 +185,8 @@
         
         // 娣诲姞璁剧疆椤癸紝浣跨敤鍒嗗壊绾垮垎闅�
         addSettingItem(panel, mowerIdPanel, true);
+        addSettingItem(panel, mowerSizePanel, true);
+        addSettingItem(panel, mowingSafetyDistancePanel, true);
         addSettingItem(panel, baseStationIdPanel, true);
         addSettingItem(panel, handheldPanel, true);
         addSettingItem(panel, simCardPanel, true);
@@ -205,6 +225,67 @@
         return seconds + "绉�";
     }
 
+    /**
+     * 灏嗗瓧绗︿覆鍊艰浆鎹负绫筹紙鍏煎鏃ф暟鎹紝濡傛灉鍊煎ぇ浜�100璁や负鏄帢绫筹紝闇�瑕侀櫎浠�100锛�
+     */
+    private double convertToMeters(String value) {
+        if (value == null || value.trim().isEmpty() || "-1".equals(value.trim())) {
+            return -1;
+        }
+        try {
+            double val = Double.parseDouble(value.trim());
+            // 濡傛灉鍊煎ぇ浜�100锛岃涓烘槸鍘樼背锛岄渶瑕佽浆鎹负绫�
+            if (val > 100) {
+                return val / 100.0;
+            }
+            return val;
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+    /**
+     * 鏍煎紡鍖栨暟鍊间负绫筹紝淇濈暀2浣嶅皬鏁�
+     */
+    private String formatMeters(double value) {
+        if (value < 0) {
+            return "鏈缃�";
+        }
+        return String.format("%.2f", value) + "m";
+    }
+
+    private String formatMowerSize() {
+        Device device = Device.getActiveDevice();
+        if (device == null) {
+            return "鏈缃�";
+        }
+        String width = device.getMowerWidth();
+        String length = device.getMowerLength();
+        double widthMeters = convertToMeters(width);
+        double lengthMeters = convertToMeters(length);
+        
+        if (widthMeters < 0 && lengthMeters < 0) {
+            return "鏈缃�";
+        }
+        
+        String widthStr = widthMeters >= 0 ? formatMeters(widthMeters) : "鏈缃�";
+        String lengthStr = lengthMeters >= 0 ? formatMeters(lengthMeters) : "鏈缃�";
+        return lengthStr + " 脳 " + widthStr;
+    }
+
+    private String formatMowingSafetyDistance() {
+        Device device = Device.getActiveDevice();
+        if (device == null) {
+            return "鏈缃�";
+        }
+        String distance = device.getMowingSafetyDistance();
+        double distanceMeters = convertToMeters(distance);
+        if (distanceMeters < 0) {
+            return "鏈缃�";
+        }
+        return formatMeters(distanceMeters);
+    }
+
     
     private JPanel createSettingItemPanel(String title, String value, boolean editable) {
         JPanel panel = new JPanel(new GridBagLayout());
@@ -620,6 +701,11 @@
         // 浠嶴etsys绫诲姞杞芥暟鎹�
         setData.initializeFromProperties();
         baseStation.load();
+        // 浠巇evice.properties鍔犺浇璁惧鏁版嵁
+        Device device = Device.getActiveDevice();
+        if (device != null) {
+            device.initFromProperties();
+        }
         updateDisplay();
         // 鍔犺浇骞跺簲鐢ㄤ笂娆′繚瀛樼殑瑙嗗浘涓績鍧愭爣
         loadViewCenterFromProperties();
@@ -671,6 +757,16 @@
             mowerIdLabel.setText(setData.getMowerId() != null ? setData.getMowerId() : "鏈缃�");
         }
 
+        // 鏇存柊鍓茶崏鏈洪暱瀹芥樉绀�
+        if (mowerSizeLabel != null) {
+            mowerSizeLabel.setText(formatMowerSize());
+        }
+
+        // 鏇存柊鍓茶崏瀹夊叏璺濈鏄剧ず
+        if (mowingSafetyDistanceLabel != null) {
+            mowingSafetyDistanceLabel.setText(formatMowingSafetyDistance());
+        }
+
         if (baseStationIdLabel != null) {
             baseStationIdLabel.setText(resolveBaseStationId());
         }
@@ -768,6 +864,16 @@
             mowerIdEditBtn.addActionListener(e -> editMowerId());
         }
 
+        // 鍓茶崏鏈洪暱瀹界紪杈戞寜閽簨浠�
+        if (mowerSizeEditBtn != null) {
+            mowerSizeEditBtn.addActionListener(e -> editMowerSize());
+        }
+
+        // 鍓茶崏瀹夊叏璺濈缂栬緫鎸夐挳浜嬩欢
+        if (mowingSafetyDistanceEditBtn != null) {
+            mowingSafetyDistanceEditBtn.addActionListener(e -> editMowingSafetyDistance());
+        }
+
         if (baseStationIdEditBtn != null) {
             baseStationIdEditBtn.addActionListener(e -> editBaseStationId());
         }
@@ -816,6 +922,181 @@
         }
     }
 
+    private void editMowerSize() {
+        Device device = Device.getActiveDevice();
+        if (device == null) {
+            JOptionPane.showMessageDialog(this, "璁惧鏈垵濮嬪寲", "閿欒", JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        // 鑾峰彇褰撳墠鍊煎苟杞崲涓虹背锛堝吋瀹规棫鏁版嵁锛�
+        double currentLengthMeters = convertToMeters(device.getMowerLength());
+        double currentWidthMeters = convertToMeters(device.getMowerWidth());
+        
+        String currentLengthStr = currentLengthMeters >= 0 ? String.format("%.2f", currentLengthMeters) : "";
+        String currentWidthStr = currentWidthMeters >= 0 ? String.format("%.2f", currentWidthMeters) : "";
+
+        // 鍒涘缓杈撳叆瀵硅瘽妗�
+        JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
+        inputPanel.add(new JLabel("闀垮害(m):"));
+        JTextField lengthField = new JTextField(currentLengthStr);
+        inputPanel.add(lengthField);
+        inputPanel.add(new JLabel("瀹藉害(m):"));
+        JTextField widthField = new JTextField(currentWidthStr);
+        inputPanel.add(widthField);
+
+        int result = JOptionPane.showConfirmDialog(this,
+            inputPanel,
+            "淇敼鍓茶崏鏈洪暱瀹�",
+            JOptionPane.OK_CANCEL_OPTION,
+            JOptionPane.QUESTION_MESSAGE);
+
+        if (result == JOptionPane.OK_OPTION) {
+            String newLength = lengthField.getText().trim();
+            String newWidth = widthField.getText().trim();
+
+            // 楠岃瘉杈撳叆
+            if (newLength.isEmpty() && newWidth.isEmpty()) {
+                JOptionPane.showMessageDialog(this, "闀垮害鍜屽搴︿笉鑳藉悓鏃朵负绌�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                return;
+            }
+
+            double lengthValue = -1;
+            double widthValue = -1;
+
+            if (!newLength.isEmpty()) {
+                try {
+                    lengthValue = Double.parseDouble(newLength);
+                    if (lengthValue < 0) {
+                        JOptionPane.showMessageDialog(this, "闀垮害蹇呴』澶т簬绛変簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                        return;
+                    }
+                } catch (NumberFormatException e) {
+                    JOptionPane.showMessageDialog(this, "闀垮害蹇呴』鏄湁鏁堢殑鏁板瓧", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                    return;
+                }
+            }
+
+            if (!newWidth.isEmpty()) {
+                try {
+                    widthValue = Double.parseDouble(newWidth);
+                    if (widthValue < 0) {
+                        JOptionPane.showMessageDialog(this, "瀹藉害蹇呴』澶т簬绛変簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                        return;
+                    }
+                } catch (NumberFormatException e) {
+                    JOptionPane.showMessageDialog(this, "瀹藉害蹇呴』鏄湁鏁堢殑鏁板瓧", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                    return;
+                }
+            }
+
+            // 鏇存柊璁惧灞炴�э紙淇濆瓨涓虹背锛屼繚鐣�2浣嶅皬鏁帮級
+            if (lengthValue >= 0) {
+                String lengthStr = String.format("%.2f", lengthValue);
+                device.setMowerLength(lengthStr);
+                device.updateField("mowerLength", lengthStr);
+            } else {
+                device.setMowerLength("-1");
+                device.updateField("mowerLength", "-1");
+            }
+
+            if (widthValue >= 0) {
+                String widthStr = String.format("%.2f", widthValue);
+                device.setMowerWidth(widthStr);
+                device.updateField("mowerWidth", widthStr);
+            } else {
+                device.setMowerWidth("-1");
+                device.updateField("mowerWidth", "-1");
+            }
+
+            // 濡傛灉闀垮害鍜屽搴﹂兘鏈夋晥锛岃嚜鍔ㄨ绠楀畨鍏ㄨ窛绂�
+            if (lengthValue > 0 && widthValue > 0) {
+                try {
+                    double safetyDistance = MowerSafetyDistanceCalculator.calculateSafetyDistance(lengthValue, widthValue);
+                    String safetyDistanceStr = String.format("%.2f", safetyDistance);
+                    device.setMowingSafetyDistance(safetyDistanceStr);
+                    device.updateField("mowingSafetyDistance", safetyDistanceStr);
+                    
+                    // 鏇存柊瀹夊叏璺濈鏄剧ず
+                    if (mowingSafetyDistanceLabel != null) {
+                        mowingSafetyDistanceLabel.setText(formatMowingSafetyDistance());
+                    }
+                } catch (IllegalArgumentException e) {
+                    // 濡傛灉璁$畻澶辫触锛屼笉鏇存柊瀹夊叏璺濈
+                    System.err.println("璁$畻瀹夊叏璺濈澶辫触: " + e.getMessage());
+                }
+            }
+
+            // 淇濆瓨鍒癲evice.properties
+            device.saveToProperties();
+
+            // 鏇存柊鏄剧ず
+            if (mowerSizeLabel != null) {
+                mowerSizeLabel.setText(formatMowerSize());
+            }
+            JOptionPane.showMessageDialog(this, "鍓茶崏鏈洪暱瀹芥洿鏂版垚鍔�" + 
+                (lengthValue > 0 && widthValue > 0 ? "锛屽畨鍏ㄨ窛绂诲凡鑷姩璁$畻" : ""), 
+                "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
+        }
+    }
+
+    private void editMowingSafetyDistance() {
+        Device device = Device.getActiveDevice();
+        if (device == null) {
+            JOptionPane.showMessageDialog(this, "璁惧鏈垵濮嬪寲", "閿欒", JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        // 鑾峰彇褰撳墠鍊煎苟杞崲涓虹背锛堝吋瀹规棫鏁版嵁锛�
+        double currentDistanceMeters = convertToMeters(device.getMowingSafetyDistance());
+        String currentValueStr = currentDistanceMeters >= 0 ? String.format("%.2f", currentDistanceMeters) : "";
+
+        String newValue = (String) JOptionPane.showInputDialog(this,
+            "璇疯緭鍏ュ壊鑽夊畨鍏ㄨ窛绂�(鍗曚綅:m):",
+            "淇敼鍓茶崏瀹夊叏璺濈",
+            JOptionPane.QUESTION_MESSAGE,
+            null,
+            null,
+            currentValueStr);
+
+        if (newValue == null) {
+            return; // 鐢ㄦ埛鍙栨秷
+        }
+
+        newValue = newValue.trim();
+        if (newValue.isEmpty()) {
+            JOptionPane.showMessageDialog(this, "鍓茶崏瀹夊叏璺濈涓嶈兘涓虹┖", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+
+        // 楠岃瘉杈撳叆
+        double distanceValue;
+        try {
+            distanceValue = Double.parseDouble(newValue);
+            if (distanceValue < 0) {
+                JOptionPane.showMessageDialog(this, "鍓茶崏瀹夊叏璺濈蹇呴』澶т簬绛変簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+                return;
+            }
+        } catch (NumberFormatException e) {
+            JOptionPane.showMessageDialog(this, "鍓茶崏瀹夊叏璺濈蹇呴』鏄湁鏁堢殑鏁板瓧", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+
+        // 鏇存柊璁惧灞炴�э紙淇濆瓨涓虹背锛屼繚鐣�2浣嶅皬鏁帮級
+        String distanceStr = String.format("%.2f", distanceValue);
+        device.setMowingSafetyDistance(distanceStr);
+        device.updateField("mowingSafetyDistance", distanceStr);
+
+        // 淇濆瓨鍒癲evice.properties
+        device.saveToProperties();
+
+        // 鏇存柊鏄剧ず
+        if (mowingSafetyDistanceLabel != null) {
+            mowingSafetyDistanceLabel.setText(formatMowingSafetyDistance());
+        }
+        JOptionPane.showMessageDialog(this, "鍓茶崏瀹夊叏璺濈鏇存柊鎴愬姛", "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
+    }
+
     private void editHandheldMarkerId() {
         String currentValue = setData.getHandheldMarkerId() != null ? setData.getHandheldMarkerId() : "";
         String newValue = (String) JOptionPane.showInputDialog(this,

--
Gitblit v1.10.0