From b272034a1fdbfe32b355fc6c264a4c45df107190 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 23 十二月 2025 14:55:03 +0800
Subject: [PATCH] 优化了新增地块功能

---
 src/baseStation/BaseStationDialog.java |  292 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 233 insertions(+), 59 deletions(-)

diff --git a/src/baseStation/BaseStationDialog.java b/src/baseStation/BaseStationDialog.java
index 88c39f9..a878c06 100644
--- a/src/baseStation/BaseStationDialog.java
+++ b/src/baseStation/BaseStationDialog.java
@@ -3,14 +3,18 @@
 import javax.swing.*;
 
 import gecaoji.Device;
+import publicway.buttonset;
 
 import java.awt.*;
 import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Locale;
 import java.util.Properties;
 
 public class BaseStationDialog extends JDialog {
@@ -132,6 +136,28 @@
             updateTimeLabel = valueLabel;
         } else if ("鍩哄噯绔欎綅缃細".equals(title)) {
             positionLabel = valueLabel;
+            final Color clickableColor = THEME_COLOR != null ? THEME_COLOR : new Color(70, 130, 180);
+            titleLabel.setForeground(clickableColor);
+            titleLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            titleLabel.setToolTipText("鐐瑰嚮淇敼鍩哄噯绔欎綅缃�");
+            titleLabel.addMouseListener(new MouseAdapter() {
+                @Override
+                public void mouseClicked(MouseEvent e) {
+                    if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 1) {
+                        promptEditBaseStationPosition();
+                    }
+                }
+
+                @Override
+                public void mouseEntered(MouseEvent e) {
+                    titleLabel.setForeground(brightenColor(clickableColor));
+                }
+
+                @Override
+                public void mouseExited(MouseEvent e) {
+                    titleLabel.setForeground(clickableColor);
+                }
+            });
         } else if ("鍩哄噯绔欏崱鍙凤細".equals(title)) {
             simCardLabel = valueLabel;
         }
@@ -143,6 +169,122 @@
         
         return panel;
     }
+
+    private void promptEditBaseStationPosition() {
+        if (baseStation == null) {
+            JOptionPane.showMessageDialog(this,
+                    "鍩哄噯绔欎俊鎭湭鍒濆鍖栵紝鏃犳硶淇敼浣嶇疆銆�",
+                    "閿欒",
+                    JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        baseStation.load();
+
+        String currentRaw = baseStation.getInstallationCoordinates();
+        String normalizedCurrent = canonicalizeCoordinateValue(currentRaw);
+        boolean hasExistingCoordinate = normalizedCurrent != null && !"-1".equals(normalizedCurrent);
+
+        JTextField inputField = new JTextField(hasExistingCoordinate ? normalizedCurrent : "");
+        inputField.setColumns(28);
+
+        JPanel dialogPanel = new JPanel(new BorderLayout(0, 8));
+        JLabel hintLabel = new JLabel("璇疯緭鍏ユ柊鐨勫熀鍑嗙珯鍧愭爣锛堢ず渚嬶細3949.90238860,N,11616.75692000,E锛�");
+        hintLabel.setFont(new Font("寰蒋闆呴粦", Font.PLAIN, 12));
+        dialogPanel.add(hintLabel, BorderLayout.NORTH);
+        dialogPanel.add(inputField, BorderLayout.CENTER);
+
+        JOptionPane optionPane = new JOptionPane(dialogPanel,
+            JOptionPane.PLAIN_MESSAGE,
+            JOptionPane.OK_CANCEL_OPTION);
+        JDialog dialog = optionPane.createDialog(this, "淇敼鍩哄噯绔欎綅缃�");
+        dialog.setModal(true);
+        dialog.pack();
+
+        Dimension packedSize = dialog.getSize();
+        Window ownerWindow = getOwner();
+        int referenceWidth = ownerWindow != null ? ownerWindow.getWidth() : getWidth();
+        if (referenceWidth <= 0) {
+            referenceWidth = 400;
+        }
+        dialog.setSize(new Dimension(referenceWidth, packedSize.height));
+        dialog.setResizable(false);
+        dialog.setLocationRelativeTo(this);
+        dialog.setVisible(true);
+        Object selectedValue = optionPane.getValue();
+        if (!(selectedValue instanceof Integer) || ((Integer) selectedValue) != JOptionPane.OK_OPTION) {
+            return;
+        }
+
+        String userInput = inputField.getText();
+        if (userInput == null) {
+            return;
+        }
+
+        String trimmed = userInput.trim();
+        if (trimmed.isEmpty()) {
+            int confirm = JOptionPane.showConfirmDialog(this,
+                    "鏈緭鍏ュ潗鏍囷紝淇濆瓨鍚庡皢瑙嗕负鏈畨瑁呯姸鎬侊紝鏄惁缁х画锛�",
+                    "纭",
+                    JOptionPane.OK_CANCEL_OPTION,
+                    JOptionPane.WARNING_MESSAGE);
+            if (confirm != JOptionPane.OK_OPTION) {
+                return;
+            }
+        }
+
+        String valueToSave = trimmed.isEmpty() ? "-1" : canonicalizeCoordinateValue(trimmed);
+
+        if (!"-1".equals(valueToSave) && !looksLikeCoordinateFormat(valueToSave)) {
+            int confirm = JOptionPane.showConfirmDialog(this,
+                    "鍧愭爣鏍煎紡浼间箮涓嶇鍚堚�滅含搴�,鏂瑰悜,缁忓害,鏂瑰悜鈥濈殑棰勬湡锛屼粛鐒朵繚瀛樺悧锛�",
+                    "鏍煎紡纭",
+                    JOptionPane.OK_CANCEL_OPTION,
+                    JOptionPane.WARNING_MESSAGE);
+            if (confirm != JOptionPane.OK_OPTION) {
+                return;
+            }
+        }
+
+        if (normalizedCurrent.equals(valueToSave)) {
+            JOptionPane.showMessageDialog(this,
+                    "鍩哄噯绔欎綅缃湭鍙戠敓鍙樺寲銆�",
+                    "鎻愮ず",
+                    JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+
+        baseStation.updateInstallationCoordinates(valueToSave);
+        baseStation.load();
+
+        if (device != null) {
+            device.setBaseStationCoordinates(valueToSave);
+            updatePropertiesFile("baseStationCoordinates", valueToSave);
+        }
+
+        refreshLabels();
+
+        JOptionPane.showMessageDialog(this,
+                "鍩哄噯绔欎綅缃凡鏇存柊銆�",
+                "鏇存柊鎴愬姛",
+                JOptionPane.INFORMATION_MESSAGE);
+    }
+
+    private boolean looksLikeCoordinateFormat(String value) {
+        if (value == null) {
+            return false;
+        }
+        String[] parts = value.split(",");
+        if (parts.length != 4) {
+            return false;
+        }
+        for (String part : parts) {
+            if (part.trim().isEmpty()) {
+                return false;
+            }
+        }
+        return true;
+    }
     
     private JPanel createActionPanel(String title, String buttonText, Color buttonColor, ActionListener actionListener) {
         JPanel panel = new JPanel();
@@ -155,7 +297,7 @@
         titleLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 14));
         titleLabel.setForeground(Color.DARK_GRAY);
 
-        JButton actionButton = createInlineButton(buttonText, buttonColor);
+        JButton actionButton = buttonset.createStyledButton(buttonText, buttonColor);
         actionButton.addActionListener(actionListener);
 
         panel.add(titleLabel);
@@ -164,30 +306,6 @@
 
         return panel;
     }
-
-    private JButton createInlineButton(String text, Color bgColor) {
-        JButton button = new JButton(text);
-        button.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 14));
-        button.setBackground(bgColor);
-        button.setForeground(Color.WHITE);
-        button.setFocusPainted(false);
-        button.setBorder(BorderFactory.createEmptyBorder(8, 18, 8, 18));
-        Dimension size = new Dimension(90, 36);
-        button.setPreferredSize(size);
-        button.setMinimumSize(size);
-        button.setMaximumSize(size);
-
-        button.addMouseListener(new java.awt.event.MouseAdapter() {
-            public void mouseEntered(java.awt.event.MouseEvent evt) {
-                button.setBackground(brightenColor(bgColor));
-            }
-            public void mouseExited(java.awt.event.MouseEvent evt) {
-                button.setBackground(bgColor);
-            }
-        });
-
-        return button;
-    }
     
     private Color brightenColor(Color color) {
         int r = Math.min(255, color.getRed() + 30);
@@ -282,26 +400,11 @@
             return "璁惧娌℃湁瀹夎鍥哄畾";
         }
         String coordinates = baseStation.getInstallationCoordinates();
-        if (coordinates == null) {
+        String canonical = canonicalizeCoordinateValue(coordinates);
+        if (canonical == null || "-1".equals(canonical)) {
             return "璁惧娌℃湁瀹夎鍥哄畾";
         }
-        String trimmed = coordinates.trim();
-        if (trimmed.isEmpty() || "-1".equals(trimmed)) {
-            return "璁惧娌℃湁瀹夎鍥哄畾";
-        }
-        try {
-            String[] parts = trimmed.split(",");
-            if (parts.length == 4) {
-                String lat = formatCoordinate(parts[0].trim(), true);
-                String latDir = parts[1].trim();
-                String lon = formatCoordinate(parts[2].trim(), false);
-                String lonDir = parts[3].trim();
-                return String.format("%s掳%s, %s掳%s", lat, latDir, lon, lonDir);
-            }
-        } catch (Exception e) {
-            // ignore formatting errors and fall back to raw value
-        }
-        return trimmed;
+        return canonical;
     }
 
     private String getSimCardDisplay() {
@@ -354,22 +457,93 @@
         return !trimmed.isEmpty() && !"-1".equals(trimmed);
     }
     
-    private String formatCoordinate(String coordinate, boolean isLatitude) {
-        // 鏍煎紡鍖栧潗鏍囷細2324.194945 -> 23掳24.1949'
-        try {
-            // 搴︽暟鏄墠2浣嶏紙绾害锛夋垨3浣嶏紙缁忓害锛�
-            int degreeDigits = isLatitude ? 2 : 3;
-            String degreeStr = coordinate.substring(0, degreeDigits);
-            String minuteStr = coordinate.substring(degreeDigits);
-            
-            // 淇濈暀4浣嶅皬鏁�
-            double minutes = Double.parseDouble(minuteStr);
-            String formattedMinutes = String.format("%.4f", minutes);
-            
-            return degreeStr + "掳" + formattedMinutes + "'";
-        } catch (Exception e) {
-            return coordinate;
+    // Normalizes coordinate strings into degree-minute format when possible for consistent display/storage
+    private String canonicalizeCoordinateValue(String value) {
+        if (value == null) {
+            return "-1";
         }
+        String trimmed = value.trim();
+        if (trimmed.isEmpty() || "-1".equals(trimmed)) {
+            return "-1";
+        }
+        String[] parts = trimmed.split(",");
+        if (parts.length != 4) {
+            return trimmed;
+        }
+        String latDirRaw = parts[1] == null ? "" : parts[1].trim();
+        String lonDirRaw = parts[3] == null ? "" : parts[3].trim();
+        if (latDirRaw.isEmpty() || lonDirRaw.isEmpty()) {
+            return trimmed;
+        }
+        String latDir = latDirRaw.toUpperCase(Locale.ROOT);
+        String lonDir = lonDirRaw.toUpperCase(Locale.ROOT);
+        if (!isValidDirection(latDir, true) || !isValidDirection(lonDir, false)) {
+            return trimmed;
+        }
+        String formattedLat = convertToDegreeMinuteString(parts[0], latDir, true);
+        String formattedLon = convertToDegreeMinuteString(parts[2], lonDir, false);
+        if (formattedLat == null || formattedLon == null) {
+            return trimmed;
+        }
+        return formattedLat + "," + latDir + "," + formattedLon + "," + lonDir;
+    }
+
+    private boolean isValidDirection(String direction, boolean isLatitude) {
+        if (direction == null) {
+            return false;
+        }
+        if (isLatitude) {
+            return "N".equals(direction) || "S".equals(direction);
+        }
+        return "E".equals(direction) || "W".equals(direction);
+    }
+
+    // Converts decimal degrees or degree-minute input into a canonical degree-minute string (8 decimal places)
+    private String convertToDegreeMinuteString(String rawValue, String direction, boolean isLatitude) {
+        double decimal = parseCoordinateToDecimalDegrees(rawValue, direction, isLatitude);
+        if (!Double.isFinite(decimal)) {
+            return null;
+        }
+        double absDecimal = Math.abs(decimal);
+        int degrees = (int) Math.floor(absDecimal);
+        double minutes = (absDecimal - degrees) * 60.0d;
+        double degreeMinutes = degrees * 100.0d + minutes;
+        return String.format(Locale.US, "%.8f", degreeMinutes);
+    }
+
+    private double parseCoordinateToDecimalDegrees(String rawValue, String direction, boolean isLatitude) {
+        if (rawValue == null) {
+            return Double.NaN;
+        }
+        String trimmed = rawValue.trim();
+        if (trimmed.isEmpty()) {
+            return Double.NaN;
+        }
+        double numeric;
+        try {
+            numeric = Double.parseDouble(trimmed);
+        } catch (NumberFormatException ex) {
+            return Double.NaN;
+        }
+
+        double abs = Math.abs(numeric);
+        double boundary = isLatitude ? 90d : 180d;
+        double decimal;
+        if (abs <= boundary) {
+            decimal = abs;
+        } else {
+            double degrees = Math.floor(abs / 100d);
+            double minutes = abs - degrees * 100d;
+            decimal = degrees + minutes / 60d;
+        }
+
+        String dirUpper = direction == null ? "" : direction.trim().toUpperCase(Locale.ROOT);
+        if ("S".equals(dirUpper) || "W".equals(dirUpper)) {
+            decimal = -decimal;
+        } else if (!"N".equals(dirUpper) && !"E".equals(dirUpper) && numeric < 0d) {
+            decimal = -decimal;
+        }
+        return decimal;
     }
     
     private void lockBaseStationPosition() {
@@ -399,7 +573,7 @@
                 JOptionPane.INFORMATION_MESSAGE);
             
             // 鏇存柊鍩哄噯绔欎綅缃紙杩欓噷浣跨敤妯℃嫙鏁版嵁锛屽疄闄呭簲浠嶨PS鑾峰彇锛�
-            String newPosition = "2324.194945,N,11330.938547,E";
+            String newPosition = canonicalizeCoordinateValue("2324.194945,N,11330.938547,E");
             String timestamp = String.valueOf(System.currentTimeMillis());
 
             if (!hasBaseStationId()) {

--
Gitblit v1.10.0