| | |
| | | import javax.swing.*; |
| | | |
| | | import gecaoji.Device; |
| | | import publicway.buttonset; |
| | | |
| | | import java.awt.*; |
| | | import java.awt.event.ActionListener; |
| | |
| | | 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 { |
| | |
| | | baseStation.load(); |
| | | |
| | | String currentRaw = baseStation.getInstallationCoordinates(); |
| | | String normalizedCurrent = currentRaw == null ? "-1" : currentRaw.trim(); |
| | | if (normalizedCurrent.isEmpty()) { |
| | | normalizedCurrent = "-1"; |
| | | } |
| | | String normalizedCurrent = canonicalizeCoordinateValue(currentRaw); |
| | | boolean hasExistingCoordinate = normalizedCurrent != null && !"-1".equals(normalizedCurrent); |
| | | |
| | | JTextField inputField = new JTextField("-1".equals(normalizedCurrent) ? "" : normalizedCurrent); |
| | | JTextField inputField = new JTextField(hasExistingCoordinate ? normalizedCurrent : ""); |
| | | inputField.setColumns(28); |
| | | |
| | | JPanel dialogPanel = new JPanel(new BorderLayout(0, 8)); |
| | | JLabel hintLabel = new JLabel("请输入新的基准站坐标(格式示例:2324.194945,N,11330.938547,E)"); |
| | | 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(); |
| | | 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(); |
| | |
| | | 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) { |
| | | dialog.setResizable(false); |
| | | dialog.setLocationRelativeTo(this); |
| | | dialog.setVisible(true); |
| | | Object selectedValue = optionPane.getValue(); |
| | | if (!(selectedValue instanceof Integer) || ((Integer) selectedValue) != JOptionPane.OK_OPTION) { |
| | | return; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | String valueToSave = trimmed.isEmpty() ? "-1" : trimmed; |
| | | String valueToSave = trimmed.isEmpty() ? "-1" : canonicalizeCoordinateValue(trimmed); |
| | | |
| | | if (!"-1".equals(valueToSave) && !looksLikeCoordinateFormat(valueToSave)) { |
| | | int confirm = JOptionPane.showConfirmDialog(this, |
| | |
| | | } |
| | | } |
| | | |
| | | if (valueToSave.equals(normalizedCurrent)) { |
| | | if (normalizedCurrent.equals(valueToSave)) { |
| | | JOptionPane.showMessageDialog(this, |
| | | "基准站位置未发生变化。", |
| | | "提示", |
| | |
| | | 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); |
| | |
| | | |
| | | 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); |
| | |
| | | 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() { |
| | |
| | | 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() { |
| | |
| | | JOptionPane.INFORMATION_MESSAGE); |
| | | |
| | | // 更新基准站位置(这里使用模拟数据,实际应从GPS获取) |
| | | 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()) { |