From a3b05960fe629e9006b45d61618b01f724e757fd Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 19 十二月 2025 17:41:08 +0800
Subject: [PATCH] 美化了地块管理的排版

---
 src/dikuai/Dikuaiguanli.java |  271 +++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 198 insertions(+), 73 deletions(-)

diff --git a/src/dikuai/Dikuaiguanli.java b/src/dikuai/Dikuaiguanli.java
index c84eecb..b70c499 100644
--- a/src/dikuai/Dikuaiguanli.java
+++ b/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,23 +260,68 @@
 			landArea = "鏈煡";
 		}
 		contentPanel.add(createCardInfoItem("鍦板潡闈㈢Н:", landArea));
-	contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
+	contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+
+		JPanel mowingPatternPanel = createCardInfoItem("鍓茶崏妯″紡:",
+			formatMowingPatternForDisplay(dikuai.getMowingPattern()));
+		configureInteractiveLabel(getInfoItemTitleLabel(mowingPatternPanel),
+			() -> editMowingPattern(dikuai),
+			"鐐瑰嚮鏌ョ湅/缂栬緫鍓茶崏妯″紡");
+		contentPanel.add(mowingPatternPanel);
+		contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+
+		// 鍓茶崏鏈哄壊鍒�瀹藉害
+		String mowingBladeWidthValue = dikuai.getMowingBladeWidth();
+		String displayBladeWidth = "鏈缃�";
+		if (mowingBladeWidthValue != null && !"-1".equals(mowingBladeWidthValue) && !mowingBladeWidthValue.trim().isEmpty()) {
+			try {
+				double bladeWidthMeters = Double.parseDouble(mowingBladeWidthValue.trim());
+				double bladeWidthCm = bladeWidthMeters * 100.0;
+				displayBladeWidth = String.format("%.2f鍘樼背", bladeWidthCm);
+			} catch (NumberFormatException e) {
+				displayBladeWidth = "鏈缃�";
+			}
+		}
+		JPanel mowingBladeWidthPanel = createCardInfoItem("鍓茶崏鏈哄壊鍒�瀹藉害:", displayBladeWidth);
+		contentPanel.add(mowingBladeWidthPanel);
+		contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
+
+		String mowingWidthValue = dikuai.getMowingWidth();
+		String displayWidth = "鏈缃�";
+		if (mowingWidthValue != null && !"-1".equals(mowingWidthValue) && !mowingWidthValue.trim().isEmpty()) {
+			displayWidth = mowingWidthValue + "鍘樼背";
+		}
+		JPanel mowingWidthPanel = createCardInfoItem("鍓茶崏瀹藉害:", displayWidth);
+		contentPanel.add(mowingWidthPanel);
+		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, 15)));
-
-		// 鍦板潡杈圭晫鍧愭爣锛堝甫鏄剧ず椤剁偣鎸夐挳锛�
-		JPanel boundaryPanel = createBoundaryInfoItem(dikuai,
-			getTruncatedValue(dikuai.getBoundaryCoordinates(), 12, "鏈缃�"));
-		setInfoItemTooltip(boundaryPanel, dikuai.getBoundaryCoordinates());
-		configureInteractiveLabel(getInfoItemTitleLabel(boundaryPanel),
-			() -> editBoundaryCoordinates(dikuai),
-			"鐐瑰嚮鏌ョ湅/缂栬緫鍦板潡杈圭晫鍧愭爣");
-		contentPanel.add(boundaryPanel);
-	contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
+	contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
 
 		ObstacleSummary obstacleSummary = getObstacleSummaryFromCache(dikuai.getLandNumber());
 		JPanel obstaclePanel = createCardInfoItemWithButton("闅滅鐗�:",
@@ -288,61 +334,40 @@
 			() -> showObstacleManagementPage(dikuai),
 			"鐐瑰嚮鏌ョ湅/绠$悊闅滅鐗�");
 		contentPanel.add(obstaclePanel);
-	contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
+	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 = createCardInfoItemWithButton("璺緞鍧愭爣:",
-			getTruncatedValue(dikuai.getPlannedPath(), 12, "鏈缃�"),
-			"澶嶅埗", e -> copyCoordinatesAction("璺緞鍧愭爣", dikuai.getPlannedPath()));
-		setInfoItemTooltip(pathPanel, dikuai.getPlannedPath());
+		JPanel pathPanel = createCardInfoItemWithButtonOnly("璺緞鍧愭爣:",
+			"鏌ョ湅", e -> editPlannedPath(dikuai));
 		configureInteractiveLabel(getInfoItemTitleLabel(pathPanel),
 			() -> editPlannedPath(dikuai),
 			"鐐瑰嚮鏌ョ湅/缂栬緫璺緞鍧愭爣");
 		contentPanel.add(pathPanel);
-	contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
+	contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
 
-		JPanel baseStationPanel = createCardInfoItemWithButton("鍩虹珯鍧愭爣:",
-			getTruncatedValue(dikuai.getBaseStationCoordinates(), 12, "鏈缃�"),
-			"澶嶅埗", e -> copyCoordinatesAction("鍩虹珯鍧愭爣", dikuai.getBaseStationCoordinates()));
-		setInfoItemTooltip(baseStationPanel, dikuai.getBaseStationCoordinates());
-		configureInteractiveLabel(getInfoItemTitleLabel(baseStationPanel),
-			() -> editBaseStationCoordinates(dikuai),
-			"鐐瑰嚮鏌ョ湅/缂栬緫鍩虹珯鍧愭爣");
-		contentPanel.add(baseStationPanel);
-	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, 10)));
 
-		JPanel boundaryOriginalPanel = createCardInfoItemWithButton("杈圭晫鍘熷鍧愭爣:",
-			getTruncatedValue(dikuai.getBoundaryOriginalCoordinates(), 12, "鏈缃�"),
-			"澶嶅埗", e -> copyCoordinatesAction("杈圭晫鍘熷鍧愭爣", dikuai.getBoundaryOriginalCoordinates()));
-		setInfoItemTooltip(boundaryOriginalPanel, dikuai.getBoundaryOriginalCoordinates());
-		configureInteractiveLabel(getInfoItemTitleLabel(boundaryOriginalPanel),
-			() -> editBoundaryOriginalCoordinates(dikuai),
-			"鐐瑰嚮鏌ョ湅/缂栬緫杈圭晫鍘熷鍧愭爣");
-		contentPanel.add(boundaryOriginalPanel);
-		contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
-
-		JPanel mowingPatternPanel = createCardInfoItemWithButton("鍓茶崏妯″紡:",
-			getTruncatedValue(dikuai.getMowingPattern(), 12, "鏈缃�"),
-			"澶嶅埗", e -> copyCoordinatesAction("鍓茶崏妯″紡", dikuai.getMowingPattern()));
-		setInfoItemTooltip(mowingPatternPanel, dikuai.getMowingPattern());
-		configureInteractiveLabel(getInfoItemTitleLabel(mowingPatternPanel),
-			() -> editMowingPattern(dikuai),
-			"鐐瑰嚮鏌ョ湅/缂栬緫鍓茶崏妯″紡");
-		contentPanel.add(mowingPatternPanel);
-		contentPanel.add(Box.createRigidArea(new Dimension(0, 15)));
-
-		String mowingWidthValue = dikuai.getMowingWidth();
-		String widthSource = null;
-		if (mowingWidthValue != null && !"-1".equals(mowingWidthValue) && !mowingWidthValue.trim().isEmpty()) {
-			widthSource = mowingWidthValue + "鍘樼背";
-		}
-		String displayWidth = getTruncatedValue(widthSource, 12, "鏈缃�");
-		JPanel mowingWidthPanel = createCardInfoItemWithButton("鍓茶崏瀹藉害:",
-			displayWidth,
-			"缂栬緫", e -> editMowingWidth(dikuai));
-		setInfoItemTooltip(mowingWidthPanel, widthSource);
-		contentPanel.add(mowingWidthPanel);
-		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, 10)));
 
 		JPanel completedTrackPanel = createCardInfoItemWithButton("宸插畬鎴愬壊鑽夎矾寰�:",
 			getTruncatedValue(dikuai.getMowingTrack(), 12, "鏈褰�"),
@@ -361,11 +386,16 @@
 		JButton generatePathBtn = createPrimaryFooterButton("璺緞瑙勫垝");
 		generatePathBtn.addActionListener(e -> showPathPlanningPage(dikuai));
 
+		JButton navigationPreviewBtn = createPrimaryFooterButton("瀵艰埅棰勮");
+		navigationPreviewBtn.addActionListener(e -> startNavigationPreview(dikuai));
+
 		JPanel footerPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 		footerPanel.setBackground(CARD_BACKGROUND);
 		footerPanel.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0));
 		footerPanel.add(generatePathBtn);
 		footerPanel.add(Box.createHorizontalStrut(12));
+		footerPanel.add(navigationPreviewBtn);
+		footerPanel.add(Box.createHorizontalStrut(12));
 		footerPanel.add(deleteBtn);
 		card.add(footerPanel, BorderLayout.SOUTH);
 
@@ -387,6 +417,7 @@
 		
 		itemPanel.add(labelComp, BorderLayout.WEST);
 		itemPanel.add(valueComp, BorderLayout.EAST);
+		itemPanel.putClientProperty("titleLabel", labelComp);
 		
 		return itemPanel;
 	}
@@ -425,15 +456,43 @@
 		return itemPanel;
 	}
 
-		private JPanel createBoundaryInfoItem(Dikuai dikuai, String displayValue) {
+	private JPanel createCardInfoItemWithButtonOnly(String label, String buttonText, ActionListener listener) {
+		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));
+		
+		JButton button = createSmallLinkButton(buttonText, listener);
+		
+		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);
-			// 澧炲姞楂樺害浠ョ‘淇濇寜閽笅杈圭紭瀹屾暣鏄剧ず锛堟寜閽珮搴�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));
@@ -445,18 +504,25 @@
 			rightPanel.setBackground(CARD_BACKGROUND);
 			rightPanel.setBorder(BorderFactory.createEmptyBorder(verticalPadding, 0, verticalPadding, 0));
 
-			JLabel valueComp = new JLabel(displayValue);
-			valueComp.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 14));
-			valueComp.setForeground(TEXT_COLOR);
+			// 鐘舵�佹彁绀烘枃瀛楁爣绛�
+			JLabel statusLabel = new JLabel();
+			statusLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 13));
+			statusLabel.setForeground(LIGHT_TEXT);
 
 			JButton toggleButton = createBoundaryToggleButton(dikuai);
+			// 灏嗙姸鎬佹爣绛惧拰鎸夐挳鍏宠仈锛屼互渚垮湪鎸夐挳鐘舵�佸彉鍖栨椂鏇存柊鏍囩
+			toggleButton.putClientProperty("statusLabel", statusLabel);
 
-			rightPanel.add(valueComp);
+			// 鍒濆鍖栫姸鎬佹枃瀛�
+			String landNumber = dikuai.getLandNumber();
+			boolean isVisible = boundaryPointVisibility.getOrDefault(landNumber, false);
+			updateBoundaryStatusLabel(statusLabel, isVisible);
+
+			rightPanel.add(statusLabel);
 			rightPanel.add(toggleButton);
 
 			itemPanel.add(labelComp, BorderLayout.WEST);
 			itemPanel.add(rightPanel, BorderLayout.CENTER);
-			itemPanel.putClientProperty("valueLabel", valueComp);
 			itemPanel.putClientProperty("titleLabel", labelComp);
 
 			return itemPanel;
@@ -471,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);
@@ -499,6 +565,24 @@
 				button.setOpaque(true);
 			}
 			button.setToolTipText(active ? "闅愯棌杈圭晫鐐瑰簭鍙�" : "鏄剧ず杈圭晫鐐瑰簭鍙�");
+			
+			// 鏇存柊鐘舵�佹彁绀烘枃瀛�
+			Object statusLabelObj = button.getClientProperty("statusLabel");
+			if (statusLabelObj instanceof JLabel) {
+				JLabel statusLabel = (JLabel) statusLabelObj;
+				updateBoundaryStatusLabel(statusLabel, active);
+			}
+		}
+		
+		private void updateBoundaryStatusLabel(JLabel statusLabel, boolean active) {
+			if (statusLabel == null) {
+				return;
+			}
+			if (active) {
+				statusLabel.setText("宸插紑鍚竟鐣岀偣鏄剧ず");
+			} else {
+				statusLabel.setText("宸插叧闂竟鐣岀偣鏄剧ず");
+			}
 		}
 
 		private void ensureBoundaryToggleIconsLoaded() {
@@ -859,6 +943,31 @@
 	}
 
 	/**
+	 * 鍚姩瀵艰埅棰勮
+	 */
+	private void startNavigationPreview(Dikuai dikuai) {
+		if (dikuai == null) {
+			return;
+		}
+		
+		Window owner = SwingUtilities.getWindowAncestor(this);
+		
+		// 鑾峰彇鍦板潡绠$悊瀵硅瘽妗嗭紝鍑嗗鍦ㄦ墦寮�瀵艰埅棰勮鏃跺叧闂�
+		Window managementWindow = null;
+		if (owner instanceof JDialog) {
+			managementWindow = owner;
+		}
+		
+		// 鍏抽棴鍦板潡绠$悊椤甸潰
+		if (managementWindow != null) {
+			managementWindow.dispose();
+		}
+		
+		// 鍚姩瀵艰埅棰勮
+		daohangyulan.getInstance().startNavigationPreview(dikuai);
+	}
+
+	/**
 	 * 鏄剧ず璺緞瑙勫垝椤甸潰
 	 */
 	private void showPathPlanningPage(Dikuai dikuai) {
@@ -940,6 +1049,7 @@
 		dialog.setVisible(true);
 	}
 
+
 	private void generateMowingPath(Dikuai dikuai) {
 		if (dikuai == null) {
 			return;
@@ -1183,6 +1293,21 @@
 		return section;
 	}
 
+	private String formatMowingPatternForDisplay(String patternValue) {
+		String sanitized = sanitizeValueOrNull(patternValue);
+		if (sanitized == null) {
+			return "鏈缃�";
+		}
+		String normalized = normalizeExistingMowingPattern(sanitized);
+		if ("parallel".equals(normalized)) {
+			return "骞宠妯″紡 (parallel)";
+		}
+		if ("spiral".equals(normalized)) {
+			return "铻烘棆妯″紡 (spiral)";
+		}
+		return sanitized;
+	}
+
 	private String formatMowingPatternForDialog(String patternValue) {
 		String sanitized = sanitizeValueOrNull(patternValue);
 		if (sanitized == null) {

--
Gitblit v1.10.0