张世豪
4 天以前 a3b05960fe629e9006b45d61618b01f724e757fd
src/dikuai/Dikuaiguanli.java
@@ -30,6 +30,7 @@
import zhuye.MapRenderer;
import zhuye.Shouye;
import zhuye.Coordinate;
import gecaoji.Device;
/**
 * 地块管理面板 - 卡片式布局设计
@@ -71,7 +72,7 @@
   private ImageIcon workUnselectedIcon;
   private ImageIcon boundaryVisibleIcon;
   private ImageIcon boundaryHiddenIcon;
   private static final int BOUNDARY_TOGGLE_ICON_SIZE = 48;
   private static final int BOUNDARY_TOGGLE_ICON_SIZE = 24;
   private Map<String, ObstacleSummary> obstacleSummaryCache = Collections.emptyMap();
   public Dikuaiguanli(String landNumber) {
@@ -165,7 +166,7 @@
         for (Dikuai dikuai : allDikuai.values()) {
            JPanel card = createDikuaiCard(dikuai);
            cardsPanel.add(card);
            cardsPanel.add(Box.createRigidArea(new Dimension(0, 15)));
            cardsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
         }
      }
      
@@ -245,11 +246,11 @@
      
      // 地块编号
      contentPanel.add(createCardInfoItem("地块编号:", getDisplayValue(dikuai.getLandNumber(), "未知")));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 添加时间
      contentPanel.add(createCardInfoItem("添加时间:", getDisplayValue(dikuai.getCreateTime(), "未知")));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 地块面积
      String landArea = dikuai.getLandArea();
@@ -259,59 +260,7 @@
         landArea = "未知";
      }
      contentPanel.add(createCardInfoItem("地块面积:", landArea));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      // 返回点坐标(带修改按钮)
      contentPanel.add(createCardInfoItemWithButton("返回点坐标:",
         getDisplayValue(dikuai.getReturnPointCoordinates(), "未设置"),
         "修改", e -> editReturnPoint(dikuai)));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      // 地块边界坐标(带显示顶点按钮)
      JPanel boundaryPanel = createBoundaryInfoItem(dikuai);
      configureInteractiveLabel(getInfoItemTitleLabel(boundaryPanel),
         () -> editBoundaryCoordinates(dikuai),
         "点击查看/编辑地块边界坐标");
      contentPanel.add(boundaryPanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      ObstacleSummary obstacleSummary = getObstacleSummaryFromCache(dikuai.getLandNumber());
      JPanel obstaclePanel = createCardInfoItemWithButton("障碍物:",
         obstacleSummary.buildDisplayValue(),
         "新增",
         e -> addNewObstacle(dikuai));
      setInfoItemTooltip(obstaclePanel, obstacleSummary.buildTooltip());
      // 让障碍物标题可点击,打开障碍物管理页面
      configureInteractiveLabel(getInfoItemTitleLabel(obstaclePanel),
         () -> showObstacleManagementPage(dikuai),
         "点击查看/管理障碍物");
      contentPanel.add(obstaclePanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      // 路径坐标(带查看按钮)
      JPanel pathPanel = createCardInfoItemWithButtonOnly("路径坐标:",
         "查看", e -> editPlannedPath(dikuai));
      configureInteractiveLabel(getInfoItemTitleLabel(pathPanel),
         () -> editPlannedPath(dikuai),
         "点击查看/编辑路径坐标");
      contentPanel.add(pathPanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
   JPanel baseStationPanel = createCardInfoItemWithButtonOnly("基站坐标:",
      "查看", e -> editBaseStationCoordinates(dikuai));
   configureInteractiveLabel(getInfoItemTitleLabel(baseStationPanel),
      () -> editBaseStationCoordinates(dikuai),
      "点击查看/编辑基站坐标");
   contentPanel.add(baseStationPanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
   JPanel boundaryOriginalPanel = createCardInfoItemWithButtonOnly("边界原始坐标:",
      "查看", e -> editBoundaryOriginalCoordinates(dikuai));
   configureInteractiveLabel(getInfoItemTitleLabel(boundaryOriginalPanel),
      () -> editBoundaryOriginalCoordinates(dikuai),
      "点击查看/编辑边界原始坐标");
   contentPanel.add(boundaryOriginalPanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      JPanel mowingPatternPanel = createCardInfoItem("割草模式:",
         formatMowingPatternForDisplay(dikuai.getMowingPattern()));
@@ -319,7 +268,7 @@
         () -> editMowingPattern(dikuai),
         "点击查看/编辑割草模式");
      contentPanel.add(mowingPatternPanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 割草机割刀宽度
      String mowingBladeWidthValue = dikuai.getMowingBladeWidth();
@@ -335,7 +284,7 @@
      }
      JPanel mowingBladeWidthPanel = createCardInfoItem("割草机割刀宽度:", displayBladeWidth);
      contentPanel.add(mowingBladeWidthPanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      String mowingWidthValue = dikuai.getMowingWidth();
      String displayWidth = "未设置";
@@ -344,7 +293,81 @@
      }
      JPanel mowingWidthPanel = createCardInfoItem("割草宽度:", displayWidth);
      contentPanel.add(mowingWidthPanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
      contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 割草安全距离
      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 = "未设置";
            }
         }
      }
      JPanel mowingSafetyDistancePanel = createCardInfoItem("割草安全距离:", displaySafetyDistance);
      contentPanel.add(mowingSafetyDistancePanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 返回点坐标(带修改按钮)
      contentPanel.add(createCardInfoItemWithButton("返回点坐标:",
         getDisplayValue(dikuai.getReturnPointCoordinates(), "未设置"),
         "修改", e -> editReturnPoint(dikuai)));
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      ObstacleSummary obstacleSummary = getObstacleSummaryFromCache(dikuai.getLandNumber());
      JPanel obstaclePanel = createCardInfoItemWithButton("障碍物:",
         obstacleSummary.buildDisplayValue(),
         "新增",
         e -> addNewObstacle(dikuai));
      setInfoItemTooltip(obstaclePanel, obstacleSummary.buildTooltip());
      // 让障碍物标题可点击,打开障碍物管理页面
      configureInteractiveLabel(getInfoItemTitleLabel(obstaclePanel),
         () -> showObstacleManagementPage(dikuai),
         "点击查看/管理障碍物");
      contentPanel.add(obstaclePanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 地块边界坐标(带显示顶点按钮)
      JPanel boundaryPanel = createBoundaryInfoItem(dikuai);
      configureInteractiveLabel(getInfoItemTitleLabel(boundaryPanel),
         () -> editBoundaryCoordinates(dikuai),
         "点击查看/编辑地块边界坐标");
      contentPanel.add(boundaryPanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      // 路径坐标(带查看按钮)
      JPanel pathPanel = createCardInfoItemWithButtonOnly("路径坐标:",
         "查看", 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));
   configureInteractiveLabel(getInfoItemTitleLabel(baseStationPanel),
      () -> editBaseStationCoordinates(dikuai),
      "点击查看/编辑基站坐标");
   contentPanel.add(baseStationPanel);
   contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
   JPanel boundaryOriginalPanel = createCardInfoItemWithButtonOnly("边界原始坐标:",
      "查看", e -> editBoundaryOriginalCoordinates(dikuai));
   configureInteractiveLabel(getInfoItemTitleLabel(boundaryOriginalPanel),
      () -> editBoundaryOriginalCoordinates(dikuai),
      "点击查看/编辑边界原始坐标");
   contentPanel.add(boundaryOriginalPanel);
      contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
      JPanel completedTrackPanel = createCardInfoItemWithButton("已完成割草路径:",
         getTruncatedValue(dikuai.getMowingTrack(), 12, "未记录"),
@@ -464,12 +487,12 @@
      private JPanel createBoundaryInfoItem(Dikuai dikuai) {
         JPanel itemPanel = new JPanel(new BorderLayout());
         itemPanel.setBackground(CARD_BACKGROUND);
         // 增加高度以确保按钮下边缘完整显示(按钮高度56,加上上下边距)
         int rowHeight = Math.max(60, BOUNDARY_TOGGLE_ICON_SIZE + 16);
         // 增加高度以确保按钮下边缘完整显示(按钮高度28,加上上下边距)
         int rowHeight = Math.max(30, BOUNDARY_TOGGLE_ICON_SIZE + 8);
         Dimension rowDimension = new Dimension(Integer.MAX_VALUE, rowHeight);
         itemPanel.setMaximumSize(rowDimension);
         itemPanel.setPreferredSize(rowDimension);
         itemPanel.setMinimumSize(new Dimension(0, 56));
         itemPanel.setMinimumSize(new Dimension(0, 28));
         JLabel labelComp = new JLabel("地块边界:");
         labelComp.setFont(new Font("微软雅黑", Font.PLAIN, 14));
@@ -514,7 +537,7 @@
         button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
         button.setMargin(new Insets(0, 0, 0, 0));
         button.setIconTextGap(0);
         button.setPreferredSize(new Dimension(56, 56));
         button.setPreferredSize(new Dimension(28, 28));
         String landNumber = dikuai.getLandNumber();
         boolean isVisible = boundaryPointVisibility.getOrDefault(landNumber, false);