From 32524195d474b74e48916867b2a6c2f022a40d98 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 09 十二月 2025 19:36:32 +0800
Subject: [PATCH] 20251209
---
src/zhuye/Shouye.java | 755 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 690 insertions(+), 65 deletions(-)
diff --git a/src/zhuye/Shouye.java b/src/zhuye/Shouye.java
index 10f9ca0..1dfd462 100644
--- a/src/zhuye/Shouye.java
+++ b/src/zhuye/Shouye.java
@@ -92,6 +92,11 @@
private JPanel floatingButtonPanel;
private JPanel floatingButtonColumn;
private Runnable endDrawingCallback;
+ private JButton pathPreviewReturnButton;
+ private boolean pathPreviewActive;
+ private Runnable pathPreviewReturnAction;
+ private String previewRestoreLandNumber;
+ private String previewRestoreLandName;
private boolean drawingPaused;
private ImageIcon pauseIcon;
private ImageIcon pauseActiveIcon;
@@ -112,7 +117,6 @@
private double[] circleBaseLatLon;
private Timer circleDataMonitor;
private Coordinate lastCapturedCoordinate;
- private HandheldBoundaryCaptureDialog handheldCaptureDialog;
private boolean handheldCaptureActive;
private int handheldCapturedPoints;
private final List<Point2D.Double> handheldTemporaryPoints = new ArrayList<>();
@@ -127,14 +131,26 @@
private boolean stopButtonActive = false;
private boolean bluetoothConnected = false;
private Timer mowerSpeedRefreshTimer;
+ private boolean drawingControlModeActive;
+ private boolean storedStartButtonShowingPause;
+ private boolean storedStopButtonActive;
+ private String storedStatusBeforeDrawing;
+ private boolean handheldCaptureInlineUiActive;
+ private Timer handheldCaptureStatusTimer;
+ private String handheldCaptureStoredStatusText;
+ private Color handheldStartButtonOriginalBackground;
+ private Color handheldStartButtonOriginalForeground;
+ private Color handheldStopButtonOriginalBackground;
+ private Color handheldStopButtonOriginalForeground;
public Shouye() {
instance = this;
baseStation = new BaseStation();
baseStation.load();
- dellmessage.registerLineListener(serialLineListener);
+ dellmessage.registerLineListener(serialLineListener);
initializeUI();
setupEventHandlers();
+ scheduleIdentifierCheck();
}
public static Shouye getInstance() {
@@ -174,6 +190,26 @@
refreshMapForSelectedArea();
}
+ private void scheduleIdentifierCheck() {
+ HierarchyListener listener = new HierarchyListener() {
+ @Override
+ public void hierarchyChanged(HierarchyEvent e) {
+ if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && Shouye.this.isShowing()) {
+ Shouye.this.removeHierarchyListener(this);
+ SwingUtilities.invokeLater(() -> {
+ Shouye.this.checkIdentifiersAndPromptIfNeeded();
+ Shouye.this.showInitialMowerSelfCheckDialogIfNeeded();
+ });
+ }
+ }
+ };
+ addHierarchyListener(listener);
+ }
+
+ private void showInitialMowerSelfCheckDialogIfNeeded() {
+ zijian.showInitialPromptIfNeeded(this, this::showRemoteControlDialog);
+ }
+
private void applyIdleTrailDurationFromSettings() {
if (mapRenderer == null) {
return;
@@ -584,8 +620,9 @@
}
if (remoteDialog != null) {
positionRemoteDialogBottomCenter(remoteDialog);
+ zijian.markSelfCheckCompleted();
+ remoteDialog.setVisible(true);
}
- remoteDialog.setVisible(true);
}
private void positionRemoteDialogBottomCenter(RemoteControlDialog dialog) {
@@ -663,6 +700,142 @@
baseStationDialog.setVisible(true);
}
+ private void checkIdentifiersAndPromptIfNeeded() {
+ if (baseStation == null) {
+ baseStation = new BaseStation();
+ }
+ baseStation.load();
+
+ String currentMowerId = Setsys.getPropertyValue("mowerId");
+ String currentBaseStationId = baseStation.getDeviceId();
+
+ if (!isIdentifierMissing(currentMowerId) && !isIdentifierMissing(currentBaseStationId)) {
+ return;
+ }
+
+ Window owner = SwingUtilities.getWindowAncestor(this);
+ promptForMissingIdentifiers(owner, currentMowerId, currentBaseStationId);
+ }
+
+ private void promptForMissingIdentifiers(Window owner, String currentMowerId, String currentBaseStationId) {
+ while (true) {
+ JTextField mowerField = new JTextField(10);
+ JTextField baseField = new JTextField(10);
+
+ if (!isIdentifierMissing(currentMowerId)) {
+ mowerField.setText(currentMowerId.trim());
+ }
+ if (!isIdentifierMissing(currentBaseStationId)) {
+ baseField.setText(currentBaseStationId.trim());
+ }
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
+
+ JLabel mowerLabel = new JLabel("鍓茶崏鏈虹紪鍙�");
+ JLabel baseLabel = new JLabel("宸垎鍩哄噯绔欑紪鍙�");
+
+ mowerField.setMaximumSize(new Dimension(Integer.MAX_VALUE, mowerField.getPreferredSize().height));
+ baseField.setMaximumSize(new Dimension(Integer.MAX_VALUE, baseField.getPreferredSize().height));
+
+ panel.add(mowerLabel);
+ panel.add(Box.createVerticalStrut(4));
+ panel.add(mowerField);
+ panel.add(Box.createVerticalStrut(10));
+ panel.add(baseLabel);
+ panel.add(Box.createVerticalStrut(4));
+ panel.add(baseField);
+
+ Object[] options = {"淇濆瓨", "鍙栨秷"};
+ int result = JOptionPane.showOptionDialog(owner, panel, "瀹屽杽璁惧淇℃伅",
+ JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
+
+ if (result != 0) {
+ break;
+ }
+
+ String mowerInput = mowerField.getText().trim();
+ String baseInput = baseField.getText().trim();
+
+ if (mowerInput.isEmpty()) {
+ JOptionPane.showMessageDialog(owner, "鍓茶崏鏈虹紪鍙蜂笉鑳戒负绌恒��", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ continue;
+ }
+
+ if (baseInput.isEmpty()) {
+ JOptionPane.showMessageDialog(owner, "宸垎鍩哄噯绔欑紪鍙蜂笉鑳戒负绌恒��", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ continue;
+ }
+
+ boolean mowerSaved = persistMowerIdentifier(mowerInput);
+ boolean baseSaved = persistBaseStationIdentifier(baseInput);
+
+ if (mowerSaved && baseSaved) {
+ JOptionPane.showMessageDialog(owner, "缂栧彿宸蹭繚瀛樸��", "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
+ break;
+ }
+
+ StringBuilder errorBuilder = new StringBuilder();
+ if (!mowerSaved) {
+ errorBuilder.append("鍓茶崏鏈虹紪鍙蜂繚瀛樺け璐ャ��");
+ }
+ if (!baseSaved) {
+ if (errorBuilder.length() > 0) {
+ errorBuilder.append('\n');
+ }
+ errorBuilder.append("宸垎鍩哄噯绔欑紪鍙蜂繚瀛樺け璐ャ��");
+ }
+
+ JOptionPane.showMessageDialog(owner, errorBuilder.toString(), "淇濆瓨澶辫触", JOptionPane.ERROR_MESSAGE);
+
+ currentMowerId = Setsys.getPropertyValue("mowerId");
+ baseStation.load();
+ currentBaseStationId = baseStation.getDeviceId();
+ }
+ }
+
+ private boolean isIdentifierMissing(String value) {
+ if (value == null) {
+ return true;
+ }
+ String trimmed = value.trim();
+ return trimmed.isEmpty() || "-1".equals(trimmed);
+ }
+
+ private boolean persistMowerIdentifier(String mowerId) {
+ try {
+ Setsys setsys = new Setsys();
+ setsys.initializeFromProperties();
+ boolean updated = setsys.updateProperty("mowerId", mowerId);
+ if (updated) {
+ Device.initializeActiveDevice(mowerId);
+ }
+ return updated;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ private boolean persistBaseStationIdentifier(String baseStationId) {
+ if (baseStation == null) {
+ baseStation = new BaseStation();
+ }
+ try {
+ baseStation.updateByDeviceId(baseStationId,
+ baseStation.getInstallationCoordinates(),
+ baseStation.getIotSimCardNumber(),
+ baseStation.getDeviceActivationTime(),
+ baseStation.getDataUpdateTime());
+ baseStation.load();
+ return true;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
private boolean hasValidBaseStationId() {
if (baseStation == null) {
return false;
@@ -713,9 +886,22 @@
}
private void toggleStartPause() {
+ if (handheldCaptureInlineUiActive) {
+ handleHandheldConfirmAction();
+ return;
+ }
+ if (drawingControlModeActive) {
+ toggleDrawingPause();
+ return;
+ }
if (startBtn == null) {
return;
}
+ if (startButtonShowingPause) {
+ if (!zijian.ensureBeforeMowing(this, this::showRemoteControlDialog)) {
+ return;
+ }
+ }
startButtonShowingPause = !startButtonShowingPause;
if (!startButtonShowingPause) {
statusLabel.setText("浣滀笟涓�");
@@ -737,6 +923,14 @@
}
private void handleStopAction() {
+ if (handheldCaptureInlineUiActive) {
+ handleHandheldFinishAction();
+ return;
+ }
+ if (drawingControlModeActive) {
+ handleDrawingStopFromControlPanel();
+ return;
+ }
stopButtonActive = !stopButtonActive;
updateStopButtonIcon();
if (stopButtonActive) {
@@ -751,6 +945,268 @@
updateStartButtonAppearance();
}
+ private void handleDrawingStopFromControlPanel() {
+ if (endDrawingCallback != null) {
+ endDrawingCallback.run();
+ } else {
+ addzhangaiwu.finishDrawingSession();
+ }
+ }
+
+ private void handleHandheldConfirmAction() {
+ if (!handheldCaptureInlineUiActive) {
+ return;
+ }
+ if (!canConfirmHandheldPoint()) {
+ refreshHandheldCaptureUiState();
+ return;
+ }
+ int count = captureHandheldBoundaryPoint();
+ if (count <= 0) {
+ refreshHandheldCaptureUiState();
+ return;
+ }
+ refreshHandheldCaptureUiState();
+ }
+
+ private void handleHandheldFinishAction() {
+ if (!handheldCaptureInlineUiActive) {
+ return;
+ }
+ if (stopBtn != null && !stopBtn.isEnabled()) {
+ refreshHandheldCaptureUiState();
+ return;
+ }
+ if (!finishHandheldBoundaryCapture()) {
+ refreshHandheldCaptureUiState();
+ }
+ }
+
+ private void enterHandheldCaptureInlineUi() {
+ if (handheldCaptureInlineUiActive) {
+ refreshHandheldCaptureUiState();
+ return;
+ }
+ handheldCaptureInlineUiActive = true;
+ handheldCaptureStoredStatusText = statusLabel != null ? statusLabel.getText() : null;
+ if (statusLabel != null) {
+ statusLabel.setText("鎵嬫寔閲囬泦涓�");
+ }
+ if (startBtn != null) {
+ handheldStartButtonOriginalBackground = startBtn.getBackground();
+ handheldStartButtonOriginalForeground = startBtn.getForeground();
+ startBtn.setIcon(null);
+ startBtn.setIconTextGap(0);
+ startBtn.setHorizontalAlignment(SwingConstants.CENTER);
+ startBtn.setHorizontalTextPosition(SwingConstants.CENTER);
+ startBtn.setVerticalTextPosition(SwingConstants.CENTER);
+ }
+ if (stopBtn != null) {
+ handheldStopButtonOriginalBackground = stopBtn.getBackground();
+ handheldStopButtonOriginalForeground = stopBtn.getForeground();
+ stopBtn.setIcon(null);
+ stopBtn.setIconTextGap(0);
+ stopBtn.setHorizontalAlignment(SwingConstants.CENTER);
+ stopBtn.setHorizontalTextPosition(SwingConstants.CENTER);
+ stopBtn.setVerticalTextPosition(SwingConstants.CENTER);
+ stopBtn.setText("缁撴潫");
+ }
+ startHandheldCaptureStatusTimer();
+ refreshHandheldCaptureUiState();
+ }
+
+ private void exitHandheldCaptureInlineUi() {
+ if (!handheldCaptureInlineUiActive) {
+ return;
+ }
+ handheldCaptureInlineUiActive = false;
+ stopHandheldCaptureStatusTimer();
+ if (statusLabel != null) {
+ statusLabel.setText(handheldCaptureStoredStatusText != null ? handheldCaptureStoredStatusText : "寰呮満");
+ }
+ if (startBtn != null) {
+ startBtn.setToolTipText(null);
+ if (handheldStartButtonOriginalBackground != null) {
+ startBtn.setBackground(handheldStartButtonOriginalBackground);
+ }
+ if (handheldStartButtonOriginalForeground != null) {
+ startBtn.setForeground(handheldStartButtonOriginalForeground);
+ }
+ startBtn.setEnabled(true);
+ updateStartButtonAppearance();
+ }
+ if (stopBtn != null) {
+ stopBtn.setToolTipText(null);
+ if (handheldStopButtonOriginalBackground != null) {
+ stopBtn.setBackground(handheldStopButtonOriginalBackground);
+ }
+ if (handheldStopButtonOriginalForeground != null) {
+ stopBtn.setForeground(handheldStopButtonOriginalForeground);
+ }
+ stopBtn.setEnabled(true);
+ stopBtn.setText("缁撴潫");
+ updateStopButtonIcon();
+ }
+ handheldCaptureStoredStatusText = null;
+ handheldStartButtonOriginalBackground = null;
+ handheldStartButtonOriginalForeground = null;
+ handheldStopButtonOriginalBackground = null;
+ handheldStopButtonOriginalForeground = null;
+ }
+
+ private void startHandheldCaptureStatusTimer() {
+ if (handheldCaptureStatusTimer == null) {
+ handheldCaptureStatusTimer = new Timer(400, e -> refreshHandheldCaptureUiState());
+ handheldCaptureStatusTimer.setRepeats(true);
+ }
+ if (!handheldCaptureStatusTimer.isRunning()) {
+ handheldCaptureStatusTimer.start();
+ }
+ }
+
+ private void stopHandheldCaptureStatusTimer() {
+ if (handheldCaptureStatusTimer != null && handheldCaptureStatusTimer.isRunning()) {
+ handheldCaptureStatusTimer.stop();
+ }
+ }
+
+ // Update inline handheld capture buttons based on the current device reading.
+ private void refreshHandheldCaptureUiState() {
+ if (!handheldCaptureInlineUiActive) {
+ return;
+ }
+ int nextIndex = handheldCapturedPoints + 1;
+ boolean hasFix = hasHighPrecisionFix();
+ boolean hasValid = hasValidRealtimeHandheldPosition();
+ boolean duplicate = hasValid && isCurrentHandheldPointDuplicate();
+ boolean canConfirm = handheldCaptureActive && hasFix && hasValid && !duplicate;
+
+ if (startBtn != null) {
+ String prompt = "<html><center>閲囬泦鐐�" + nextIndex + "<br>纭畾</center></html>";
+ startBtn.setText(prompt);
+ startBtn.setEnabled(canConfirm);
+ if (canConfirm) {
+ if (handheldStartButtonOriginalBackground != null) {
+ startBtn.setBackground(handheldStartButtonOriginalBackground);
+ }
+ if (handheldStartButtonOriginalForeground != null) {
+ startBtn.setForeground(handheldStartButtonOriginalForeground);
+ }
+ startBtn.setToolTipText(null);
+ } else {
+ startBtn.setBackground(new Color(200, 200, 200));
+ startBtn.setForeground(new Color(130, 130, 130));
+ startBtn.setToolTipText(resolveHandheldConfirmTooltip(hasFix, hasValid, duplicate));
+ }
+ }
+
+ if (stopBtn != null) {
+ boolean canFinish = handheldCapturedPoints >= 3;
+ stopBtn.setText("缁撴潫");
+ stopBtn.setEnabled(canFinish);
+ if (canFinish) {
+ if (handheldStopButtonOriginalBackground != null) {
+ stopBtn.setBackground(handheldStopButtonOriginalBackground);
+ }
+ if (handheldStopButtonOriginalForeground != null) {
+ stopBtn.setForeground(handheldStopButtonOriginalForeground);
+ }
+ stopBtn.setToolTipText("缁撴潫閲囬泦骞惰繑鍥炴柊澧炲湴鍧�");
+ } else {
+ stopBtn.setBackground(new Color(220, 220, 220));
+ stopBtn.setForeground(new Color(130, 130, 130));
+ stopBtn.setToolTipText("鑷冲皯閲囬泦涓変釜鐐规墠鑳界粨鏉�");
+ }
+ }
+ }
+
+ private String resolveHandheldConfirmTooltip(boolean hasFix, boolean hasValidPosition, boolean duplicate) {
+ if (!hasFix) {
+ return "褰撳墠瀹氫綅璐ㄩ噺涓嶈冻锛屾棤娉曢噰闆�";
+ }
+ if (!hasValidPosition) {
+ return "褰撳墠瀹氫綅鏁版嵁鏃犳晥锛岃绋嶅悗鍐嶈瘯";
+ }
+ if (duplicate) {
+ return "褰撳墠鍧愭爣宸查噰闆嗭紝璇风Щ鍔ㄥ埌鏂扮殑浣嶇疆";
+ }
+ return null;
+ }
+
+ private boolean hasHighPrecisionFix() {
+ Device device = Device.getGecaoji();
+ if (device == null) {
+ return false;
+ }
+ String status = device.getPositioningStatus();
+ return status != null && "4".equals(status.trim());
+ }
+
+ private boolean canConfirmHandheldPoint() {
+ return handheldCaptureActive
+ && hasHighPrecisionFix()
+ && hasValidRealtimeHandheldPosition()
+ && !isCurrentHandheldPointDuplicate();
+ }
+
+ private void enterDrawingControlMode() {
+ if (drawingControlModeActive) {
+ return;
+ }
+ storedStartButtonShowingPause = startButtonShowingPause;
+ storedStopButtonActive = stopButtonActive;
+ storedStatusBeforeDrawing = statusLabel != null ? statusLabel.getText() : null;
+ drawingControlModeActive = true;
+ applyDrawingPauseState(false, false);
+ updateDrawingControlButtonLabels();
+ }
+
+ private void exitDrawingControlMode() {
+ if (!drawingControlModeActive) {
+ return;
+ }
+ drawingControlModeActive = false;
+ applyDrawingPauseState(false, false);
+ drawingPaused = false;
+ stopButtonActive = storedStopButtonActive;
+ startButtonShowingPause = storedStartButtonShowingPause;
+ if (startBtn != null) {
+ updateStartButtonAppearance();
+ }
+ if (stopBtn != null) {
+ stopBtn.setText("缁撴潫");
+ updateStopButtonIcon();
+ }
+ if (statusLabel != null) {
+ statusLabel.setText(storedStatusBeforeDrawing != null ? storedStatusBeforeDrawing : "寰呮満");
+ }
+ storedStatusBeforeDrawing = null;
+ }
+
+ private void updateDrawingControlButtonLabels() {
+ if (!drawingControlModeActive) {
+ return;
+ }
+ configureButtonForDrawingMode(startBtn);
+ configureButtonForDrawingMode(stopBtn);
+ if (startBtn != null) {
+ startBtn.setText(drawingPaused ? "寮�濮嬬粯鍒�" : "鏆傚仠缁樺埗");
+ }
+ if (stopBtn != null) {
+ stopBtn.setText("缁撴潫缁樺埗");
+ }
+ }
+
+ private void configureButtonForDrawingMode(JButton button) {
+ if (button == null) {
+ return;
+ }
+ button.setIcon(null);
+ button.setIconTextGap(0);
+ button.setHorizontalAlignment(SwingConstants.CENTER);
+ button.setHorizontalTextPosition(SwingConstants.CENTER);
+ }
+
private void updateStartButtonAppearance() {
if (startBtn == null) {
return;
@@ -1028,6 +1484,13 @@
refreshMowerSpeedLabel();
}
+ public void setHandheldMowerIconActive(boolean active) {
+ if (mapRenderer == null) {
+ return;
+ }
+ mapRenderer.setHandheldMowerIconActive(active);
+ }
+
public boolean startMowerBoundaryCapture() {
if (mapRenderer == null) {
return false;
@@ -1037,6 +1500,8 @@
return false;
}
+ mapRenderer.clearIdleTrail();
+
activeBoundaryMode = BoundaryCaptureMode.MOWER;
mowerBoundaryCaptureActive = true;
mowerBaseLatLon = baseLatLonCandidate;
@@ -1053,9 +1518,12 @@
Coordinate.setStartSaveGngga(true);
if (mapRenderer != null) {
+ mapRenderer.setBoundaryPreviewMarkerScale(2.0d);
mapRenderer.beginHandheldBoundaryPreview();
}
+ setHandheldMowerIconActive(false);
+
startMowerBoundaryMonitor();
return true;
}
@@ -1064,15 +1532,12 @@
if (mapRenderer == null) {
return false;
}
- if (handheldCaptureDialog != null && handheldCaptureDialog.isShowing()) {
- handheldCaptureDialog.toFront();
- return true;
- }
-
if (activeBoundaryMode == BoundaryCaptureMode.MOWER) {
stopMowerBoundaryCapture();
}
+ mapRenderer.clearIdleTrail();
+
activeBoundaryMode = BoundaryCaptureMode.HANDHELD;
handheldCaptureActive = true;
handheldCapturedPoints = 0;
@@ -1084,19 +1549,10 @@
handheldTemporaryPoints.clear();
}
AddDikuai.recordTemporaryBoundaryPoints(Collections.emptyList());
- mapRenderer.beginHandheldBoundaryPreview();
-
- Window ownerWindow = SwingUtilities.getWindowAncestor(this);
- SwingUtilities.invokeLater(() -> {
- Window targetOwner = ownerWindow;
- if (targetOwner == null) {
- targetOwner = SwingUtilities.getWindowAncestor(Shouye.this);
- }
- HandheldBoundaryCaptureDialog dialog = new HandheldBoundaryCaptureDialog(targetOwner, Shouye.this, visualizationPanel, THEME_COLOR);
- handheldCaptureDialog = dialog;
- dialog.setVisible(true);
- });
-
+ mapRenderer.setBoundaryPreviewMarkerScale(1.0d);
+ mapRenderer.beginHandheldBoundaryPreview();
+ setHandheldMowerIconActive(true);
+ enterHandheldCaptureInlineUi();
return true;
}
@@ -1188,6 +1644,7 @@
if (activeBoundaryMode == BoundaryCaptureMode.MOWER) {
activeBoundaryMode = BoundaryCaptureMode.NONE;
}
+ setHandheldMowerIconActive(false);
}
private void discardLatestCoordinate(Coordinate coordinate) {
@@ -1282,6 +1739,7 @@
List<Point2D.Double> closedSnapshot = createClosedHandheldPointSnapshot();
handheldCaptureActive = false;
+ activeBoundaryMode = BoundaryCaptureMode.NONE;
Coordinate.setStartSaveGngga(false);
if (mapRenderer != null) {
mapRenderer.clearHandheldBoundaryPreview();
@@ -1289,20 +1747,12 @@
AddDikuai.recordTemporaryBoundaryPoints(closedSnapshot);
+ exitHandheldCaptureInlineUi();
+
SwingUtilities.invokeLater(AddDikuai::finishDrawingSession);
return true;
}
- void handheldBoundaryCaptureDialogClosed(HandheldBoundaryCaptureDialog dialog) {
- if (handheldCaptureDialog == dialog) {
- handheldCaptureDialog = null;
- }
- handheldCaptureActive = false;
- if (activeBoundaryMode == BoundaryCaptureMode.HANDHELD) {
- activeBoundaryMode = BoundaryCaptureMode.NONE;
- }
- }
-
int getHandheldCapturedPointCount() {
return handheldCapturedPoints;
}
@@ -1571,9 +2021,9 @@
if (statusLabel == null) {
return;
}
- if ("浣滀笟涓�".equals(statusText)) {
+ if ("浣滀笟涓�".equals(statusText) || "缁樺埗涓�".equals(statusText)) {
statusLabel.setForeground(THEME_COLOR);
- } else if ("鏆傚仠涓�".equals(statusText)) {
+ } else if ("鏆傚仠涓�".equals(statusText) || "缁樺埗鏆傚仠".equals(statusText)) {
statusLabel.setForeground(STATUS_PAUSE_COLOR);
} else {
statusLabel.setForeground(Color.GRAY);
@@ -1601,6 +2051,29 @@
return button;
}
+ private JButton createFloatingTextButton(String text) {
+ JButton button = new JButton(text);
+ button.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 15));
+ button.setForeground(Color.WHITE);
+ button.setBackground(THEME_COLOR);
+ button.setBorder(BorderFactory.createEmptyBorder(10, 18, 10, 18));
+ button.setFocusPainted(false);
+ button.setOpaque(true);
+ button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ button.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ button.setBackground(THEME_HOVER_COLOR);
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ button.setBackground(THEME_COLOR);
+ }
+ });
+ return button;
+ }
+
private ImageIcon loadScaledIcon(String path, int width, int height) {
try {
ImageIcon icon = new ImageIcon(path);
@@ -1658,6 +2131,12 @@
if (notifyCoordinate) {
Coordinate.setStartSaveGngga(!paused);
}
+ if (drawingControlModeActive) {
+ updateDrawingControlButtonLabels();
+ if (statusLabel != null) {
+ statusLabel.setText(paused ? "缁樺埗鏆傚仠" : "缁樺埗涓�");
+ }
+ }
}
private void toggleDrawingPause() {
@@ -1670,36 +2149,33 @@
public void showEndDrawingButton(Runnable callback, String drawingShape) {
endDrawingCallback = callback;
- applyDrawingPauseState(false, false);
circleDialogMode = false;
hideCircleGuidancePanel();
-
- ensureFloatingIconsLoaded();
- ensureFloatingButtonInfrastructure();
+ enterDrawingControlMode();
boolean enableCircleGuidance = drawingShape != null
&& "circle".equalsIgnoreCase(drawingShape.trim());
if (enableCircleGuidance) {
- prepareCircleGuidanceState();
- showCircleGuidanceStep(1);
- endDrawingButton.setVisible(false);
+ ensureFloatingIconsLoaded();
+ ensureFloatingButtonInfrastructure();
if (drawingPauseButton != null) {
drawingPauseButton.setVisible(false);
}
+ if (endDrawingButton != null) {
+ endDrawingButton.setVisible(false);
+ }
+ prepareCircleGuidanceState();
+ showCircleGuidanceStep(1);
+ floatingButtonPanel.setVisible(true);
+ if (floatingButtonPanel.getParent() != visualizationPanel) {
+ visualizationPanel.add(floatingButtonPanel, BorderLayout.SOUTH);
+ }
+ rebuildFloatingButtonColumn();
} else {
clearCircleGuidanceArtifacts();
- endDrawingButton.setVisible(true);
- if (drawingPauseButton != null) {
- drawingPauseButton.setVisible(true);
- }
+ hideFloatingDrawingControls();
}
- floatingButtonPanel.setVisible(true);
- if (floatingButtonPanel.getParent() != visualizationPanel) {
- visualizationPanel.add(floatingButtonPanel, BorderLayout.SOUTH);
- }
-
- rebuildFloatingButtonColumn();
visualizationPanel.revalidate();
visualizationPanel.repaint();
}
@@ -1776,6 +2252,14 @@
floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10)));
}
floatingButtonColumn.add(endDrawingButton);
+ added = true;
+ }
+ if (pathPreviewReturnButton != null && pathPreviewReturnButton.isVisible()) {
+ if (added) {
+ floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10)));
+ }
+ floatingButtonColumn.add(pathPreviewReturnButton);
+ added = true;
}
floatingButtonColumn.revalidate();
floatingButtonColumn.repaint();
@@ -2184,21 +2668,27 @@
private double[] resolveCircleBaseLatLon() {
String coords = null;
- String landNumber = Dikuaiguanli.getCurrentWorkLandNumber();
- if (isMeaningfulValue(landNumber)) {
- Dikuai current = Dikuai.getDikuai(landNumber);
- if (current != null) {
- coords = current.getBaseStationCoordinates();
+
+ if (baseStation == null) {
+ baseStation = new BaseStation();
+ }
+ baseStation.load();
+ coords = baseStation.getInstallationCoordinates();
+
+ if (!isMeaningfulValue(coords)) {
+ String landNumber = Dikuaiguanli.getCurrentWorkLandNumber();
+ if (isMeaningfulValue(landNumber)) {
+ Dikuai current = Dikuai.getDikuai(landNumber);
+ if (current != null) {
+ coords = current.getBaseStationCoordinates();
+ }
}
- }
- if (!isMeaningfulValue(coords)) {
- coords = addzhangaiwu.getActiveSessionBaseStation();
- }
- if (!isMeaningfulValue(coords) && baseStation != null) {
- coords = baseStation.getInstallationCoordinates();
- }
- if (!isMeaningfulValue(coords)) {
- return null;
+ if (!isMeaningfulValue(coords)) {
+ coords = addzhangaiwu.getActiveSessionBaseStation();
+ }
+ if (!isMeaningfulValue(coords)) {
+ return null;
+ }
}
String[] parts = coords.split(",");
if (parts.length < 4) {
@@ -2330,7 +2820,9 @@
clearCircleGuidanceArtifacts();
hideFloatingDrawingControls();
circleDialogMode = false;
- applyDrawingPauseState(false, false);
+ exitHandheldCaptureInlineUi();
+ handheldCaptureActive = false;
+ exitDrawingControlMode();
if (activeBoundaryMode == BoundaryCaptureMode.MOWER) {
stopMowerBoundaryCapture();
} else if (activeBoundaryMode == BoundaryCaptureMode.HANDHELD && !handheldCaptureActive) {
@@ -2339,6 +2831,129 @@
endDrawingCallback = null;
visualizationPanel.revalidate();
visualizationPanel.repaint();
+ setHandheldMowerIconActive(false);
+ }
+
+ private void showPathPreviewReturnControls() {
+ ensureFloatingButtonInfrastructure();
+ if (drawingPauseButton != null) {
+ drawingPauseButton.setVisible(false);
+ }
+ if (endDrawingButton != null) {
+ endDrawingButton.setVisible(false);
+ }
+ if (pathPreviewReturnButton == null) {
+ pathPreviewReturnButton = createFloatingTextButton("杩斿洖");
+ pathPreviewReturnButton.setToolTipText("杩斿洖鏂板鍦板潡姝ラ");
+ pathPreviewReturnButton.addActionListener(e -> handlePathPreviewReturn());
+ }
+ pathPreviewReturnButton.setVisible(true);
+ if (floatingButtonPanel != null) {
+ floatingButtonPanel.setVisible(true);
+ if (floatingButtonPanel.getParent() != visualizationPanel) {
+ visualizationPanel.add(floatingButtonPanel, BorderLayout.SOUTH);
+ }
+ }
+ rebuildFloatingButtonColumn();
+ }
+
+ private void hidePathPreviewReturnControls() {
+ if (pathPreviewReturnButton != null) {
+ pathPreviewReturnButton.setVisible(false);
+ }
+ rebuildFloatingButtonColumn();
+ if (floatingButtonPanel != null && floatingButtonColumn != null
+ && floatingButtonColumn.getComponentCount() == 0) {
+ floatingButtonPanel.setVisible(false);
+ }
+ }
+
+ private void handlePathPreviewReturn() {
+ Runnable callback = pathPreviewReturnAction;
+ exitMowingPathPreview();
+ if (callback != null) {
+ callback.run();
+ }
+ }
+
+ public boolean startMowingPathPreview(String landNumber,
+ String landName,
+ String boundary,
+ String obstacles,
+ String plannedPath,
+ Runnable returnAction) {
+ if (mapRenderer == null || !isMeaningfulValue(plannedPath)) {
+ return false;
+ }
+
+ if (pathPreviewActive) {
+ exitMowingPathPreview();
+ }
+
+ exitDrawingControlMode();
+ hideCircleGuidancePanel();
+ clearCircleGuidanceArtifacts();
+
+ pathPreviewReturnAction = returnAction;
+ pathPreviewActive = true;
+ mapRenderer.setPathPreviewSizingEnabled(true);
+
+ previewRestoreLandNumber = Dikuaiguanli.getCurrentWorkLandNumber();
+ previewRestoreLandName = null;
+ if (isMeaningfulValue(previewRestoreLandNumber)) {
+ Dikuai existing = Dikuai.getDikuai(previewRestoreLandNumber);
+ if (existing != null) {
+ previewRestoreLandName = existing.getLandName();
+ }
+ }
+
+ mapRenderer.setCurrentBoundary(boundary, landNumber, landName);
+ mapRenderer.setCurrentObstacles(obstacles, landNumber);
+ mapRenderer.setCurrentPlannedPath(plannedPath);
+ mapRenderer.clearHandheldBoundaryPreview();
+ mapRenderer.setBoundaryPointSizeScale(1.0d);
+ mapRenderer.setBoundaryPointsVisible(isMeaningfulValue(boundary));
+
+ String displayName = isMeaningfulValue(landName) ? landName : landNumber;
+ updateCurrentAreaName(displayName);
+
+ showPathPreviewReturnControls();
+ visualizationPanel.revalidate();
+ visualizationPanel.repaint();
+ return true;
+ }
+
+ public void exitMowingPathPreview() {
+ if (!pathPreviewActive) {
+ return;
+ }
+ pathPreviewActive = false;
+ if (mapRenderer != null) {
+ mapRenderer.setPathPreviewSizingEnabled(false);
+ }
+ hidePathPreviewReturnControls();
+
+ String restoreNumber = previewRestoreLandNumber;
+ String restoreName = previewRestoreLandName;
+ previewRestoreLandNumber = null;
+ previewRestoreLandName = null;
+ pathPreviewReturnAction = null;
+
+ if (restoreNumber != null) {
+ Dikuaiguanli.setCurrentWorkLand(restoreNumber, restoreName);
+ } else if (mapRenderer != null) {
+ mapRenderer.setCurrentBoundary(null, null, null);
+ mapRenderer.setCurrentObstacles((String) null, null);
+ mapRenderer.setCurrentPlannedPath(null);
+ mapRenderer.setBoundaryPointsVisible(false);
+ mapRenderer.setBoundaryPointSizeScale(1.0d);
+ mapRenderer.clearHandheldBoundaryPreview();
+ mapRenderer.resetView();
+ updateCurrentAreaName(null);
+ }
+
+ visualizationPanel.revalidate();
+ visualizationPanel.repaint();
}
/**
@@ -2370,6 +2985,16 @@
private void initializeDefaultAreaSelection() {
Dikuai.initFromProperties();
+ String persistedLandNumber = Dikuaiguanli.getPersistedWorkLandNumber();
+ if (persistedLandNumber != null) {
+ Dikuai stored = Dikuai.getDikuai(persistedLandNumber);
+ if (stored != null) {
+ Dikuaiguanli.setCurrentWorkLand(persistedLandNumber, stored.getLandName());
+ return;
+ }
+ Dikuaiguanli.setCurrentWorkLand(null, null);
+ }
+
Map<String, Dikuai> all = Dikuai.getAllDikuai();
if (all.isEmpty()) {
Dikuaiguanli.setCurrentWorkLand(null, null);
--
Gitblit v1.10.0