826220679@qq.com
3 天以前 96f9630247478ee09dace5786ebfe46a54a6f2c0
优化了地块管理文字变成图标
已添加1个文件
已修改7个文件
266 ■■■■ 文件已修改
.classpath 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.project 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dikuai.properties 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
image/look.png 补丁 | 查看 | 原始文档 | blame | 历史
set.properties 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/dikuai/Dikuai.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/dikuai/Dikuaiguanli.java 136 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/zhangaiwu/AddDikuai.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.classpath
@@ -6,9 +6,9 @@
            <attribute name="module" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="lib" path="lib/jSerialComm-2.10.4.jar"/>
    <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jts-core-1.19.0.jar"/>
    <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-api-1.7.30.jar"/>
    <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-simple-1.7.30.jar"/>
    <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/jSerialComm-2.10.4.jar"/>
    <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/jts-core-1.19.0.jar"/>
    <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/slf4j-api-1.7.30.jar"/>
    <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/slf4j-simple-1.7.30.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>
.project
@@ -14,4 +14,15 @@
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
    <filteredResources>
        <filter>
            <id>1766205615208</id>
            <name></name>
            <type>30</type>
            <matcher>
                <id>org.eclipse.core.resources.regexFilterMatcher</id>
                <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
            </matcher>
        </filter>
    </filteredResources>
</projectDescription>
dikuai.properties
@@ -1,21 +1,36 @@
#Dikuai Properties
#Fri Dec 19 19:44:17 CST 2025
LAND1.angleThreshold=-1
#Sat Dec 20 12:24:28 GMT+08:00 2025
LAND2.boundaryCoordinates=5.38,-6.41;-11.15,-8.94;-12.75,-4.68;-12.23,-3.28;-11.12,-3.17;-9.29,-3.53;-7.46,-3.89;-5.62,-4.25;-3.79,-4.61;-1.96,-4.97;-0.12,-5.33;1.71,-5.69;3.54,-6.05;5.38,-6.41
LAND1.intelligentSceneAnalysis=-1
LAND1.mowingSafetyDistance=-1
LAND1.landArea=26.75
LAND1.returnPointCoordinates=-1
LAND1.landNumber=LAND1
LAND2.landName=1452
LAND2.mowingOverlapDistance=0.06
LAND2.landArea=55.11
LAND1.mowingPattern=平行线
LAND1.mowingOverlapDistance=0.06
LAND2.updateTime=2025-12-20 12\:24\:28
LAND2.createTime=2025-12-20 12\:24\:28
LAND1.mowingWidth=34
LAND2.mowingWidth=34
LAND1.plannedPath=-5.830841,-2.644443;-12.323966,-4.153883;-12.276978,-4.492026;-6.161845,-3.070456;-6.492848,-3.496470;-12.229991,-4.830169;-12.183003,-5.168312;-6.823852,-3.922484;-7.154855,-4.348497;-12.136016,-5.506455;-12.089028,-5.844598;-7.487144,-4.774810;-7.821079,-5.201505;-12.042040,-6.182741;-11.995053,-6.520885;-8.155014,-5.628200;-8.700347,-6.104039;-11.948065,-6.859028;-11.901077,-7.197171;-10.070186,-6.771548;-11.440025,-7.439057;-11.854090,-7.535314
LAND1.updateTime=2025-12-19 19\:44\:17
LAND2.mowingSafetyDistance=0.50
LAND2.plannedPath=-12.031,-3.808;-10.774,-3.615;-9.790,-3.809;-12.167,-4.172;-12.302,-4.537;-8.807,-4.002;-7.823,-4.196;-12.280,-4.878;-12.158,-5.203;-6.838,-4.389;-5.852,-4.582;-12.036,-5.528;-11.914,-5.854;-4.868,-4.775;-3.884,-4.969;-11.792,-6.179;-11.670,-6.504;-2.901,-5.162;-1.917,-5.355;-11.547,-6.829;-11.425,-7.155;-0.931,-5.548;0.055,-5.741;-11.303,-7.480;-11.181,-7.805;1.038,-5.935;2.022,-6.128;-11.059,-8.130;-10.937,-8.456;3.005,-6.322
LAND1.baseStationCoordinates=3949.89151752,N,11616.79267501,E
LAND1.boundaryCoordinates=-10.36,-8.92;-12.10,-7.80;-12.66,-3.77;-4.96,-1.98;-6.04,-3.37;-7.12,-4.76;-8.20,-6.14;-9.28,-7.53;-10.36,-8.92
LAND1.boundaryOriginalCoordinates=39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27;39.831498,116.279762,49.27;39.831500,116.279776,49.34;39.831502,116.279791,49.32;39.831504,116.279805,49.27;39.831507,116.279820,49.28
LAND2.boundaryOriginalCoordinates=39.831468,116.279941,49.29;39.831465,116.279925,49.33;39.831463,116.279908,49.34;39.831462,116.279891,49.35;39.831461,116.279874,49.33;39.831458,116.279859,49.34;39.831456,116.279843,49.32;39.831454,116.279827,49.32;39.831452,116.279813,49.42;39.831450,116.279798,49.41;39.831448,116.279783,49.36;39.831447,116.279769,49.26;39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27
LAND1.boundaryPointInterval=-1
LAND1.createTime=2025-12-19 18\:31\:53
LAND1.intelligentSceneAnalysis=-1
LAND1.landArea=26.75
LAND1.landName=21233
LAND1.landNumber=LAND1
LAND1.mowingBladeWidth=0.40
LAND1.mowingOverlapDistance=0.06
LAND1.mowingPattern=平行线
LAND1.mowingTrack=-1
LAND1.mowingWidth=34
LAND1.plannedPath=-5.830841,-2.644443;-12.323966,-4.153883;-12.276978,-4.492026;-6.161845,-3.070456;-6.492848,-3.496470;-12.229991,-4.830169;-12.183003,-5.168312;-6.823852,-3.922484;-7.154855,-4.348497;-12.136016,-5.506455;-12.089028,-5.844598;-7.487144,-4.774810;-7.821079,-5.201505;-12.042040,-6.182741;-11.995053,-6.520885;-8.155014,-5.628200;-8.700347,-6.104039;-11.948065,-6.859028;-11.901077,-7.197171;-10.070186,-6.771548;-11.440025,-7.439057;-11.854090,-7.535314
LAND1.returnPointCoordinates=-1
LAND1.updateTime=2025-12-19 19\:44\:17
LAND1.userId=-1
LAND1.angleThreshold=-1
LAND2.mowingBladeWidth=0.40
LAND1.landName=21233
LAND1.mowingTrack=-1
LAND2.baseStationCoordinates=3949.89151752,N,11616.79267501,E
LAND1.boundaryOriginalCoordinates=39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27;39.831498,116.279762,49.27;39.831500,116.279776,49.34;39.831502,116.279791,49.32;39.831504,116.279805,49.27;39.831507,116.279820,49.28
LAND1.boundaryCoordinates=-10.36,-8.92;-12.10,-7.80;-12.66,-3.77;-4.96,-1.98;-6.04,-3.37;-7.12,-4.76;-8.20,-6.14;-9.28,-7.53;-10.36,-8.92
LAND2.mowingPattern=平行线
LAND2.landNumber=LAND2
LAND1.mowingBladeWidth=0.40
image/look.png
set.properties
@@ -1,19 +1,19 @@
#Mower Configuration Properties - Updated
#Fri Dec 19 19:44:56 CST 2025
#Current work land selection updated
#Sat Dec 20 12:59:18 GMT+08:00 2025
appVersion=-1
boundaryLengthVisible=false
currentWorkLandNumber=LAND1
cuttingWidth=200
firmwareVersion=-1
handheldMarkerId=1872
idleTrailDurationSeconds=60
manualBoundaryDrawingMode=false
mapScale=41.56
measurementModeEnabled=false
mowerId=860
serialAutoConnect=true
serialBaudRate=115200
serialPortName=COM15
simCardNumber=-1
viewCenterX=8.76
viewCenterY=4.44
currentWorkLandNumber=LAND2
serialBaudRate=115200
boundaryLengthVisible=false
idleTrailDurationSeconds=60
handheldMarkerId=1872
viewCenterX=0.99
viewCenterY=6.06
manualBoundaryDrawingMode=false
mowerId=860
serialPortName=COM15
serialAutoConnect=true
mapScale=13.68
measurementModeEnabled=false
firmwareVersion=-1
cuttingWidth=200
src/dikuai/Dikuai.java
@@ -47,6 +47,8 @@
    private String mowingBladeWidth;
    // 割草重叠距离(米),默认0.06米
    private String mowingOverlapDistance;
    // 割草安全距离(米)
    private String mowingSafetyDistance;
    // 存储多个地块的映射表,键为地块编号
    private static Map<String, Dikuai> dikuaiMap = new HashMap<>();
@@ -110,6 +112,7 @@
                dikuai.mowingTrack = landProps.getProperty("mowingTrack", "-1");
                dikuai.mowingBladeWidth = landProps.getProperty("mowingBladeWidth", "0.40");
                dikuai.mowingOverlapDistance = landProps.getProperty("mowingOverlapDistance", "0.06");
                dikuai.mowingSafetyDistance = landProps.getProperty("mowingSafetyDistance", "-1");
                
                dikuaiMap.put(landNum, dikuai);
            }
@@ -237,6 +240,9 @@
            case "mowingOverlapDistance":
                this.mowingOverlapDistance = value;
                return true;
            case "mowingSafetyDistance":
                this.mowingSafetyDistance = value;
                return true;
            default:
                System.err.println("未知字段: " + fieldName);
                return false;
@@ -273,6 +279,7 @@
            if (dikuai.mowingTrack != null) properties.setProperty(landNumber + ".mowingTrack", dikuai.mowingTrack);
            if (dikuai.mowingBladeWidth != null) properties.setProperty(landNumber + ".mowingBladeWidth", dikuai.mowingBladeWidth);
            if (dikuai.mowingOverlapDistance != null) properties.setProperty(landNumber + ".mowingOverlapDistance", dikuai.mowingOverlapDistance);
            if (dikuai.mowingSafetyDistance != null) properties.setProperty(landNumber + ".mowingSafetyDistance", dikuai.mowingSafetyDistance);
        }
        
        try {
@@ -440,6 +447,14 @@
        this.mowingOverlapDistance = mowingOverlapDistance;
    }
    public String getMowingSafetyDistance() {
        return mowingSafetyDistance;
    }
    public void setMowingSafetyDistance(String mowingSafetyDistance) {
        this.mowingSafetyDistance = mowingSafetyDistance;
    }
    @Override
    public String toString() {
        return "Dikuai{" +
src/dikuai/Dikuaiguanli.java
@@ -297,20 +297,17 @@
        // 割草安全距离
        String displaySafetyDistance = "未设置";
        Device device = Device.getActiveDevice();
        if (device != null) {
            String safetyDistanceValue = device.getMowingSafetyDistance();
            if (safetyDistanceValue != null && !"-1".equals(safetyDistanceValue) && !safetyDistanceValue.trim().isEmpty()) {
                try {
                    double distanceMeters = Double.parseDouble(safetyDistanceValue.trim());
                    // 如果值大于100,认为是厘米,需要转换为米
                    if (distanceMeters > 100) {
                        distanceMeters = distanceMeters / 100.0;
                    }
                    displaySafetyDistance = String.format("%.2f米", distanceMeters);
                } catch (NumberFormatException e) {
                    displaySafetyDistance = "未设置";
        String safetyDistanceValue = dikuai.getMowingSafetyDistance();
        if (safetyDistanceValue != null && !"-1".equals(safetyDistanceValue) && !safetyDistanceValue.trim().isEmpty()) {
            try {
                double distanceMeters = Double.parseDouble(safetyDistanceValue.trim());
                // 如果值大于100,认为是厘米,需要转换为米
                if (distanceMeters > 100) {
                    distanceMeters = distanceMeters / 100.0;
                }
                displaySafetyDistance = String.format("%.2f米", distanceMeters);
            } catch (NumberFormatException e) {
                displaySafetyDistance = "未设置";
            }
        }
        JPanel mowingSafetyDistancePanel = createCardInfoItem("割草安全距离:", displaySafetyDistance);
@@ -345,24 +342,24 @@
    contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
        // 路径坐标(带查看按钮)
        JPanel pathPanel = createCardInfoItemWithButtonOnly("路径坐标:",
            "查看", e -> editPlannedPath(dikuai));
        JPanel pathPanel = createCardInfoItemWithIconButton("路径坐标:",
            createViewButton(e -> editPlannedPath(dikuai)));
        configureInteractiveLabel(getInfoItemTitleLabel(pathPanel),
            () -> editPlannedPath(dikuai),
            "点击查看/编辑路径坐标");
        contentPanel.add(pathPanel);
    contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
    JPanel baseStationPanel = createCardInfoItemWithButtonOnly("基站坐标:",
        "查看", e -> editBaseStationCoordinates(dikuai));
    JPanel baseStationPanel = createCardInfoItemWithIconButton("基站坐标:",
        createViewButton(e -> editBaseStationCoordinates(dikuai)));
    configureInteractiveLabel(getInfoItemTitleLabel(baseStationPanel),
        () -> editBaseStationCoordinates(dikuai),
        "点击查看/编辑基站坐标");
    contentPanel.add(baseStationPanel);
    contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
    JPanel boundaryOriginalPanel = createCardInfoItemWithButtonOnly("边界原始坐标:",
        "查看", e -> editBoundaryOriginalCoordinates(dikuai));
    JPanel boundaryOriginalPanel = createCardInfoItemWithIconButton("边界原始坐标:",
        createViewButton(e -> editBoundaryOriginalCoordinates(dikuai)));
    configureInteractiveLabel(getInfoItemTitleLabel(boundaryOriginalPanel),
        () -> editBoundaryOriginalCoordinates(dikuai),
        "点击查看/编辑边界原始坐标");
@@ -371,7 +368,7 @@
        JPanel completedTrackPanel = createCardInfoItemWithButton("已完成割草路径:",
            getTruncatedValue(dikuai.getMowingTrack(), 12, "未记录"),
            "查看", e -> showCompletedMowingTrackDialog(dikuai));
            createViewButton(e -> showCompletedMowingTrackDialog(dikuai)));
        setInfoItemTooltip(completedTrackPanel, dikuai.getMowingTrack());
        configureInteractiveLabel(getInfoItemTitleLabel(completedTrackPanel),
            () -> showCompletedMowingTrackDialog(dikuai),
@@ -456,6 +453,38 @@
        return itemPanel;
    }
    private JPanel createCardInfoItemWithButton(String label, String value, JButton button) {
        JPanel itemPanel = new JPanel(new BorderLayout());
        itemPanel.setBackground(CARD_BACKGROUND);
        // 增加高度以确保按钮完整显示(按钮高度约24-28像素,加上上下边距)
        itemPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
        itemPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30));
        itemPanel.setMinimumSize(new Dimension(0, 28));
        JLabel labelComp = new JLabel(label);
        labelComp.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        labelComp.setForeground(LIGHT_TEXT);
        JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        rightPanel.setBackground(CARD_BACKGROUND);
        // 添加垂直内边距以确保按钮不被裁剪
        rightPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
        JLabel valueComp = new JLabel(value);
        valueComp.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        valueComp.setForeground(TEXT_COLOR);
        rightPanel.add(valueComp);
        rightPanel.add(button);
        itemPanel.add(labelComp, BorderLayout.WEST);
        itemPanel.add(rightPanel, BorderLayout.CENTER);
        itemPanel.putClientProperty("valueLabel", valueComp);
        itemPanel.putClientProperty("titleLabel", labelComp);
        return itemPanel;
    }
    private JPanel createCardInfoItemWithButtonOnly(String label, String buttonText, ActionListener listener) {
        JPanel itemPanel = new JPanel(new BorderLayout());
        itemPanel.setBackground(CARD_BACKGROUND);
@@ -484,6 +513,32 @@
        return itemPanel;
    }
    private JPanel createCardInfoItemWithIconButton(String label, JButton button) {
        JPanel itemPanel = new JPanel(new BorderLayout());
        itemPanel.setBackground(CARD_BACKGROUND);
        // 增加高度以确保按钮完整显示(按钮高度约24-28像素,加上上下边距)
        itemPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
        itemPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30));
        itemPanel.setMinimumSize(new Dimension(0, 28));
        JLabel labelComp = new JLabel(label);
        labelComp.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        labelComp.setForeground(LIGHT_TEXT);
        JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        rightPanel.setBackground(CARD_BACKGROUND);
        // 添加垂直内边距以确保按钮不被裁剪
        rightPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
        rightPanel.add(button);
        itemPanel.add(labelComp, BorderLayout.WEST);
        itemPanel.add(rightPanel, BorderLayout.CENTER);
        itemPanel.putClientProperty("titleLabel", labelComp);
        return itemPanel;
    }
        private JPanel createBoundaryInfoItem(Dikuai dikuai) {
            JPanel itemPanel = new JPanel(new BorderLayout());
            itemPanel.setBackground(CARD_BACKGROUND);
@@ -1544,15 +1599,50 @@
    }
    private JButton createDeleteButton() {
        JButton button = createStyledButton("删除", RED_COLOR, false); // 轮廓风格
        ImageIcon deleteIcon = loadIcon("image/delete.png", 16, 16);
        JButton button = new JButton();
        ImageIcon deleteIcon = loadIcon("image/delete.png", 25, 25);
        if (deleteIcon != null) {
            button.setIcon(deleteIcon);
            button.setIconTextGap(6);
        } else {
            button.setText("删除");
        }
        button.setFont(new Font("微软雅黑", Font.PLAIN, 11));
        button.setForeground(RED_COLOR);
        button.setBorder(BorderFactory.createEmptyBorder());
        button.setContentAreaFilled(false);
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));
        button.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) { button.setOpaque(true); button.setBackground(new Color(255, 240, 240)); }
            public void mouseExited(MouseEvent e) { button.setOpaque(false); }
        });
        return button;
    }
    private JButton createViewButton(ActionListener listener) {
        JButton btn = new JButton();
        ImageIcon lookIcon = loadIcon("image/look.png", 25, 25);
        if (lookIcon != null) {
            btn.setIcon(lookIcon);
        } else {
            btn.setText("查看");
        }
        btn.setFont(new Font("微软雅黑", Font.PLAIN, 11));
        btn.setForeground(PRIMARY_COLOR);
        btn.setBorder(BorderFactory.createEmptyBorder());
        btn.setContentAreaFilled(false);
        btn.setFocusPainted(false);
        btn.setCursor(new Cursor(Cursor.HAND_CURSOR));
        btn.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) { btn.setOpaque(true); btn.setBackground(new Color(230, 250, 240)); }
            public void mouseExited(MouseEvent e) { btn.setOpaque(false); }
        });
        if (listener != null) {
            btn.addActionListener(listener);
        }
        return btn;
    }
    private JButton createPrimaryFooterButton(String text) {
        return createStyledButton(text, PRIMARY_COLOR, true); // 实心风格
    }
src/zhangaiwu/AddDikuai.java
@@ -2539,6 +2539,21 @@
        if (isMeaningfulValue(plannedPath)) {
            dikuai.setPlannedPath(plannedPath);
        }
        // 保存割草安全距离(优先从dikuaiData获取,否则从TextField获取)
        if (dikuaiData.containsKey("mowingSafetyDistance")) {
            dikuai.setMowingSafetyDistance(dikuaiData.get("mowingSafetyDistance"));
        } else if (mowingSafetyDistanceField != null) {
            String safetyDistanceText = mowingSafetyDistanceField.getText().trim();
            if (!safetyDistanceText.isEmpty()) {
                try {
                    double safetyDistanceMeters = Double.parseDouble(safetyDistanceText);
                    dikuai.setMowingSafetyDistance(String.format(Locale.US, "%.2f", safetyDistanceMeters));
                } catch (NumberFormatException e) {
                    dikuai.setMowingSafetyDistance(safetyDistanceText);
                }
            }
        }
        Dikuai.putDikuai(landNumber, dikuai);
        Dikuai.saveToProperties();