package set; import baseStation.BaseStation; import zhuye.MapRenderer; import zhuye.Shouye; import zhuye.buttonset; import set.Setsys; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.*; import java.awt.geom.RoundRectangle2D; import java.io.File; import java.util.ArrayList; import java.util.List; /** * 设置对话框 - 参考Shouye.java样式 */ public class Sets extends JDialog { private static final long serialVersionUID = 1L; private static final int ROW_HEIGHT = 50; // 增加行高以适应分割线 private static final int ITEM_PADDING = 16; // 列表项内边距 // 主题颜色 private final Color THEME_COLOR; private final Color BACKGROUND_COLOR = new Color(245, 247, 250); // 更柔和的浅灰色背景 private final Color PANEL_BACKGROUND = new Color(255, 255, 255); // 白色面板 private final Color BORDER_COLOR = new Color(233, 236, 239); // 浅边框色 private final Color DIVIDER_COLOR = new Color(233, 236, 239); // 分割线颜色 // 设置项组件 private JLabel mowerIdLabel; private JLabel baseStationIdLabel; private JLabel handheldMarkerLabel; private JLabel simCardNumberLabel; private JLabel baseStationSimLabel; private JLabel firmwareVersionLabel; private JLabel appVersionLabel; private JLabel idleTrailDurationLabel; private JLabel boundaryLengthVisibleLabel; private JButton mowerIdEditBtn; private JButton baseStationIdEditBtn; private JButton handheldEditBtn; private JButton checkUpdateBtn; private JButton feedbackButton; private JButton idleTrailEditBtn; // 数据模型 private Setsys setData; private final BaseStation baseStation; public Sets(JFrame parent, Color themeColor) { super(parent, "系统设置", true); this.THEME_COLOR = themeColor; this.setData = new Setsys(); this.baseStation = new BaseStation(); initializeUI(); loadData(); } public Sets(JDialog parent, Color themeColor) { super(parent, "系统设置", true); this.THEME_COLOR = themeColor; this.setData = new Setsys(); this.baseStation = new BaseStation(); initializeUI(); loadData(); } private void initializeUI() { setLayout(new BorderLayout()); setBackground(BACKGROUND_COLOR); setSize(400, 800); setPreferredSize(new Dimension(400, 800)); setMinimumSize(new Dimension(400, 800)); setLocationRelativeTo(getParent()); setResizable(false); // 创建主内容面板(使用更柔和的浅灰色背景) JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.setBackground(BACKGROUND_COLOR); mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // 创建设置项面板(圆角白色面板) JPanel settingsPanel = createSettingsPanel(); // 添加组件到主面板 mainPanel.add(settingsPanel, BorderLayout.CENTER); add(mainPanel, BorderLayout.CENTER); } private JPanel createSettingsPanel() { // 创建圆角白色面板容器 JPanel container = new JPanel() { @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(PANEL_BACKGROUND); // 绘制圆角矩形背景 g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 16, 16); g2d.dispose(); } }; container.setLayout(new BorderLayout()); container.setOpaque(false); // 内容面板 JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.setOpaque(false); panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 8, 0)); // 割草机编号 JPanel mowerIdPanel = createSettingItemPanel("割草机编号", setData.getMowerId() != null ? setData.getMowerId() : "未设置", true); mowerIdLabel = (JLabel) mowerIdPanel.getClientProperty("valueLabel"); mowerIdEditBtn = (JButton) mowerIdPanel.getClientProperty("editButton"); JPanel baseStationIdPanel = createSettingItemPanel("差分基准站编号", resolveBaseStationId(), true); baseStationIdLabel = (JLabel) baseStationIdPanel.getClientProperty("valueLabel"); baseStationIdEditBtn = (JButton) baseStationIdPanel.getClientProperty("editButton"); JPanel handheldPanel = createSettingItemPanel("便携打点器编号", setData.getHandheldMarkerId() != null ? setData.getHandheldMarkerId() : "未设置", true); handheldMarkerLabel = (JLabel) handheldPanel.getClientProperty("valueLabel"); handheldEditBtn = (JButton) handheldPanel.getClientProperty("editButton"); // 物联卡号 JPanel simCardPanel = createSettingItemPanel("割草机物联网卡号", setData.getSimCardNumber() != null ? setData.getSimCardNumber() : "未设置", false); simCardNumberLabel = (JLabel) simCardPanel.getClientProperty("valueLabel"); JPanel baseStationSimPanel = createSettingItemPanel("基准站物联网卡号", resolveBaseStationSimCard(), false); baseStationSimLabel = (JLabel) baseStationSimPanel.getClientProperty("valueLabel"); // 固件版本 JPanel firmwarePanel = createSettingItemPanel("固件版本", setData.getFirmwareVersion() != null ? setData.getFirmwareVersion() : "未设置", false); firmwareVersionLabel = (JLabel) firmwarePanel.getClientProperty("valueLabel"); JPanel idleTrailPanel = createSettingItemPanel("轨迹拖尾时长", formatIdleTrailDurationValue(), true); idleTrailDurationLabel = (JLabel) idleTrailPanel.getClientProperty("valueLabel"); idleTrailEditBtn = (JButton) idleTrailPanel.getClientProperty("editButton"); // 显示边界距离设置项 JPanel boundaryLengthPanel = createBoundaryLengthPanel(); boundaryLengthVisibleLabel = (JLabel) boundaryLengthPanel.getClientProperty("valueLabel"); JPanel feedbackPanel = createFeedbackPanel(); // APP版本 JPanel appVersionPanel = createAppVersionPanel(); // 添加设置项,使用分割线分隔 addSettingItem(panel, mowerIdPanel, true); addSettingItem(panel, baseStationIdPanel, true); addSettingItem(panel, handheldPanel, true); addSettingItem(panel, simCardPanel, true); addSettingItem(panel, baseStationSimPanel, true); addSettingItem(panel, firmwarePanel, true); addSettingItem(panel, idleTrailPanel, true); addSettingItem(panel, boundaryLengthPanel, true); addSettingItem(panel, feedbackPanel, true); addSettingItem(panel, appVersionPanel, false); // 最后一项不加分割线 container.add(panel, BorderLayout.CENTER); return container; } /** * 添加设置项(带分割线) */ private void addSettingItem(JPanel container, JPanel itemPanel, boolean showDivider) { container.add(itemPanel); if (showDivider) { // 添加分割线 JSeparator divider = new JSeparator(); divider.setForeground(DIVIDER_COLOR); divider.setMaximumSize(new Dimension(Integer.MAX_VALUE, 1)); divider.setAlignmentX(Component.LEFT_ALIGNMENT); container.add(divider); } } private String formatIdleTrailDurationValue() { int seconds = setData != null ? setData.getIdleTrailDurationSeconds() : Setsys.DEFAULT_IDLE_TRAIL_DURATION_SECONDS; if (seconds <= 0) { seconds = Setsys.DEFAULT_IDLE_TRAIL_DURATION_SECONDS; } return seconds + "秒"; } private JPanel createSettingItemPanel(String title, String value, boolean editable) { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); // 透明背景,由容器绘制 panel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setMinimumSize(new Dimension(0, ROW_HEIGHT)); panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING)); GridBagConstraints gbc = new GridBagConstraints(); JLabel titleLabel = new JLabel(title); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); titleLabel.setForeground(Color.BLACK); titleLabel.setHorizontalAlignment(SwingConstants.RIGHT); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 0, 12); panel.add(titleLabel, gbc); JLabel valueLabel = new JLabel(value); valueLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14)); valueLabel.setForeground(Color.DARK_GRAY); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.EAST; panel.add(valueLabel, gbc); panel.putClientProperty("valueLabel", valueLabel); if (editable) { JButton editBtn = createEditButton(); editBtn.setPreferredSize(new Dimension(30, 30)); editBtn.setMinimumSize(new Dimension(30, 30)); editBtn.setMaximumSize(new Dimension(30, 30)); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; panel.add(editBtn, gbc); panel.putClientProperty("editButton", editBtn); } return panel; } private JPanel createAppVersionPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); // 透明背景 panel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setMinimumSize(new Dimension(0, ROW_HEIGHT)); panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING)); GridBagConstraints gbc = new GridBagConstraints(); JLabel titleLabel = new JLabel("APP版本"); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); titleLabel.setForeground(Color.BLACK); titleLabel.setHorizontalAlignment(SwingConstants.RIGHT); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 0, 12); panel.add(titleLabel, gbc); appVersionLabel = new JLabel(setData.getAppVersion() != null ? setData.getAppVersion() : "未设置"); appVersionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14)); appVersionLabel.setForeground(Color.DARK_GRAY); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.EAST; panel.add(appVersionLabel, gbc); checkUpdateBtn = buttonset.createStyledButton("检查更新", THEME_COLOR); checkUpdateBtn.setFont(new Font("微软雅黑", Font.PLAIN, 12)); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; panel.add(checkUpdateBtn, gbc); return panel; } private JPanel createFeedbackPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); // 透明背景 panel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setMinimumSize(new Dimension(0, ROW_HEIGHT)); panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING)); GridBagConstraints gbc = new GridBagConstraints(); JLabel titleLabel = new JLabel("问题反馈咨询"); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); titleLabel.setForeground(Color.BLACK); titleLabel.setHorizontalAlignment(SwingConstants.RIGHT); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 0, 12); panel.add(titleLabel, gbc); feedbackButton = buttonset.createStyledButton("反馈", THEME_COLOR); feedbackButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.EAST; panel.add(feedbackButton, gbc); return panel; } /** * 创建显示边界距离设置面板 */ private JPanel createBoundaryLengthPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); // 透明背景 panel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setMinimumSize(new Dimension(0, ROW_HEIGHT)); panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING)); GridBagConstraints gbc = new GridBagConstraints(); JLabel titleLabel = new JLabel("显示边界距离"); titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); titleLabel.setForeground(Color.BLACK); titleLabel.setHorizontalAlignment(SwingConstants.RIGHT); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 0, 12); panel.add(titleLabel, gbc); boundaryLengthVisibleLabel = new JLabel(setData.isBoundaryLengthVisible() ? "已开启" : "已关闭"); boundaryLengthVisibleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14)); boundaryLengthVisibleLabel.setForeground(Color.DARK_GRAY); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.EAST; panel.add(boundaryLengthVisibleLabel, gbc); panel.putClientProperty("valueLabel", boundaryLengthVisibleLabel); // 创建切换按钮(使用图标) JButton toggleBtn = createBoundaryLengthToggleButton(); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; panel.add(toggleBtn, gbc); panel.putClientProperty("toggleButton", toggleBtn); return panel; } /** * 创建边界距离显示切换按钮 */ private JButton createBoundaryLengthToggleButton() { JButton button = new JButton(); button.setContentAreaFilled(false); button.setBorder(null); button.setFocusPainted(false); button.setCursor(new Cursor(Cursor.HAND_CURSOR)); button.setPreferredSize(new Dimension(32, 32)); button.setMinimumSize(new Dimension(32, 32)); button.setMaximumSize(new Dimension(32, 32)); updateBoundaryLengthToggleButton(button); button.addActionListener(e -> toggleBoundaryLengthVisible(button)); return button; } /** * 更新边界距离切换按钮图标 */ private void updateBoundaryLengthToggleButton(JButton button) { boolean isVisible = setData.isBoundaryLengthVisible(); try { String iconPath = isVisible ? "image/open.png" : "image/close.png"; ImageIcon icon = new ImageIcon(iconPath); if (icon.getIconWidth() > 0) { Image scaledImage = icon.getImage().getScaledInstance(32, 32, Image.SCALE_SMOOTH); button.setIcon(new ImageIcon(scaledImage)); button.setText(null); } else { button.setIcon(null); button.setText(isVisible ? "开" : "关"); } } catch (Exception e) { button.setIcon(null); button.setText(isVisible ? "开" : "关"); System.err.println("无法加载边界距离图标: " + e.getMessage()); } } /** * 切换边界距离显示状态 */ private void toggleBoundaryLengthVisible(JButton button) { boolean newValue = !setData.isBoundaryLengthVisible(); setData.setBoundaryLengthVisible(newValue); // 保存到配置文件 setData.updateProperty("boundaryLengthVisible", String.valueOf(newValue)); // 更新UI if (boundaryLengthVisibleLabel != null) { boundaryLengthVisibleLabel.setText(newValue ? "已开启" : "已关闭"); } updateBoundaryLengthToggleButton(button); // 通知MapRenderer更新 Shouye shouye = Shouye.getInstance(); if (shouye != null) { MapRenderer renderer = shouye.getMapRenderer(); if (renderer != null) { renderer.setBoundaryLengthVisible(newValue); } } } private JButton createEditButton() { JButton button = new JButton(); try { // 加载编辑图标 ImageIcon editIcon = new ImageIcon("image/bianjie.png"); // 调整图片大小 Image scaledImage = editIcon.getImage().getScaledInstance(20, 20, Image.SCALE_SMOOTH); button.setIcon(new ImageIcon(scaledImage)); } catch (Exception e) { // 如果图片加载失败,使用文本 button.setText("编辑"); System.err.println("无法加载编辑图标: " + e.getMessage()); } button.setPreferredSize(new Dimension(30, 30)); button.setBackground(PANEL_BACKGROUND); button.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); button.setFocusPainted(false); // 悬停效果 button.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { button.setBackground(new Color(240, 240, 240)); } public void mouseExited(MouseEvent e) { button.setBackground(PANEL_BACKGROUND); } }); return button; } private void loadData() { // 从Setsys类加载数据 setData.initializeFromProperties(); baseStation.load(); updateDisplay(); // 加载并应用上次保存的视图中心坐标 loadViewCenterFromProperties(); } /** * 从配置文件加载视图中心坐标并应用到MapRenderer */ private void loadViewCenterFromProperties() { Shouye shouye = Shouye.getInstance(); if (shouye == null) { return; } MapRenderer renderer = shouye.getMapRenderer(); if (renderer == null) { return; } // 从配置文件读取视图中心坐标 String viewCenterXValue = Setsys.getPropertyValue("viewCenterX"); String viewCenterYValue = Setsys.getPropertyValue("viewCenterY"); double savedTranslateX = 0.0; double savedTranslateY = 0.0; if (viewCenterXValue != null && !viewCenterXValue.trim().isEmpty()) { try { savedTranslateX = Double.parseDouble(viewCenterXValue.trim()); } catch (NumberFormatException e) { savedTranslateX = 0.0; } } if (viewCenterYValue != null && !viewCenterYValue.trim().isEmpty()) { try { savedTranslateY = Double.parseDouble(viewCenterYValue.trim()); } catch (NumberFormatException e) { savedTranslateY = 0.0; } } // 应用视图中心坐标(保持当前缩放比例) double currentScale = renderer.getScale(); renderer.setViewTransform(currentScale, savedTranslateX, savedTranslateY); } private void updateDisplay() { // 更新割草机编号显示 if (mowerIdLabel != null) { mowerIdLabel.setText(setData.getMowerId() != null ? setData.getMowerId() : "未设置"); } if (baseStationIdLabel != null) { baseStationIdLabel.setText(resolveBaseStationId()); } if (handheldMarkerLabel != null) { handheldMarkerLabel.setText(setData.getHandheldMarkerId() != null ? setData.getHandheldMarkerId() : "未设置"); } // 更新物联卡号显示 if (simCardNumberLabel != null) { simCardNumberLabel.setText(setData.getSimCardNumber() != null ? setData.getSimCardNumber() : "未设置"); } if (baseStationSimLabel != null) { baseStationSimLabel.setText(resolveBaseStationSimCard()); } // 更新固件版本显示 if (firmwareVersionLabel != null) { firmwareVersionLabel.setText(setData.getFirmwareVersion() != null ? setData.getFirmwareVersion() : "未设置"); } if (idleTrailDurationLabel != null) { idleTrailDurationLabel.setText(formatIdleTrailDurationValue()); } // 更新显示边界距离状态 if (boundaryLengthVisibleLabel != null) { boundaryLengthVisibleLabel.setText(setData.isBoundaryLengthVisible() ? "已开启" : "已关闭"); } // 更新切换按钮图标 JPanel boundaryLengthPanel = (JPanel) boundaryLengthVisibleLabel.getParent(); if (boundaryLengthPanel != null) { JButton toggleBtn = (JButton) boundaryLengthPanel.getClientProperty("toggleButton"); if (toggleBtn != null) { updateBoundaryLengthToggleButton(toggleBtn); } } // 更新APP版本显示 if (appVersionLabel != null) { appVersionLabel.setText(setData.getAppVersion() != null ? setData.getAppVersion() : "未设置"); } } private String resolveBaseStationSimCard() { if (baseStation == null) { return "未设置"; } String value = baseStation.getIotSimCardNumber(); if (value == null) { return "未设置"; } String trimmed = value.trim(); if (trimmed.isEmpty() || "-1".equals(trimmed)) { return "未设置"; } return trimmed; } private String resolveBaseStationId() { if (baseStation == null) { return "未设置"; } String value = baseStation.getDeviceId(); if (value == null) { return "未设置"; } String trimmed = value.trim(); if (trimmed.isEmpty() || "-1".equals(trimmed)) { return "未设置"; } return trimmed; } private void setupEventHandlers() { // 割草机编号编辑按钮事件 if (mowerIdEditBtn != null) { mowerIdEditBtn.addActionListener(e -> editMowerId()); } if (baseStationIdEditBtn != null) { baseStationIdEditBtn.addActionListener(e -> editBaseStationId()); } // 检查更新按钮事件 if (checkUpdateBtn != null) { checkUpdateBtn.addActionListener(e -> checkForUpdates()); } if (handheldEditBtn != null) { handheldEditBtn.addActionListener(e -> editHandheldMarkerId()); } if (feedbackButton != null) { feedbackButton.addActionListener(e -> showFeedbackDialog()); } if (idleTrailEditBtn != null) { idleTrailEditBtn.addActionListener(e -> editIdleTrailDuration()); } } private void editMowerId() { String currentValue = setData.getMowerId() != null ? setData.getMowerId() : ""; String newValue = (String) JOptionPane.showInputDialog(this, "请输入割草机编号:", "修改割草机编号", JOptionPane.QUESTION_MESSAGE, null, null, currentValue); if (newValue == null) { return; // 用户取消 } newValue = newValue.trim(); if (!newValue.isEmpty()) { if (setData.updateProperty("mowerId", newValue)) { mowerIdLabel.setText(newValue); JOptionPane.showMessageDialog(this, "割草机编号更新成功", "成功", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(this, "割草机编号更新失败", "错误", JOptionPane.ERROR_MESSAGE); } } } private void editHandheldMarkerId() { String currentValue = setData.getHandheldMarkerId() != null ? setData.getHandheldMarkerId() : ""; String newValue = (String) JOptionPane.showInputDialog(this, "请输入便携打点器编号:", "修改便携打点器编号", JOptionPane.QUESTION_MESSAGE, null, null, currentValue); if (newValue == null) { return; } newValue = newValue.trim(); if (!newValue.isEmpty()) { if (setData.updateProperty("handheldMarkerId", newValue)) { if (handheldMarkerLabel != null) { handheldMarkerLabel.setText(newValue); } JOptionPane.showMessageDialog(this, "便携打点器编号更新成功", "成功", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(this, "便携打点器编号更新失败", "错误", JOptionPane.ERROR_MESSAGE); } } } private void editBaseStationId() { String currentValue = "未设置".equals(resolveBaseStationId()) ? "" : resolveBaseStationId(); String newValue = (String) JOptionPane.showInputDialog(this, "请输入差分基准站编号:", "修改差分基准站编号", JOptionPane.QUESTION_MESSAGE, null, null, currentValue); if (newValue == null) { return; } newValue = newValue.trim(); if (newValue.isEmpty()) { JOptionPane.showMessageDialog(this, "差分基准站编号不能为空", "提示", JOptionPane.WARNING_MESSAGE); return; } try { baseStation.updateByDeviceId(newValue, baseStation.getInstallationCoordinates(), baseStation.getIotSimCardNumber(), baseStation.getDeviceActivationTime(), baseStation.getDataUpdateTime()); baseStation.load(); if (baseStationIdLabel != null) { baseStationIdLabel.setText(resolveBaseStationId()); } JOptionPane.showMessageDialog(this, "差分基准站编号更新成功", "成功", JOptionPane.INFORMATION_MESSAGE); } catch (IllegalArgumentException ex) { JOptionPane.showMessageDialog(this, ex.getMessage(), "输入错误", JOptionPane.WARNING_MESSAGE); } catch (Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "差分基准站编号更新失败", "错误", JOptionPane.ERROR_MESSAGE); } } private void editIdleTrailDuration() { int currentSeconds = setData != null ? setData.getIdleTrailDurationSeconds() : Setsys.DEFAULT_IDLE_TRAIL_DURATION_SECONDS; if (currentSeconds <= 0) { currentSeconds = Setsys.DEFAULT_IDLE_TRAIL_DURATION_SECONDS; } String input = JOptionPane.showInputDialog(this, "请输入轨迹拖尾时长(单位:秒)", currentSeconds); if (input == null) { return; } String trimmed = input.trim(); if (trimmed.isEmpty()) { JOptionPane.showMessageDialog(this, "轨迹拖尾时长不能为空", "提示", JOptionPane.WARNING_MESSAGE); return; } int parsedSeconds; try { parsedSeconds = Integer.parseInt(trimmed); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, "请输入有效的整数秒数", "提示", JOptionPane.WARNING_MESSAGE); return; } if (parsedSeconds < 5 || parsedSeconds > 600) { JOptionPane.showMessageDialog(this, "请输入5到600之间的秒数", "提示", JOptionPane.WARNING_MESSAGE); return; } if (setData.updateProperty("idleTrailDurationSeconds", String.valueOf(parsedSeconds))) { int appliedSeconds = setData.getIdleTrailDurationSeconds(); if (idleTrailDurationLabel != null) { idleTrailDurationLabel.setText(appliedSeconds + "秒"); } MapRenderer renderer = null; Shouye shouye = Shouye.getInstance(); if (shouye != null) { renderer = shouye.getMapRenderer(); } if (renderer != null) { renderer.setIdleTrailDurationSeconds(appliedSeconds); } JOptionPane.showMessageDialog(this, "轨迹拖尾时长已更新为 " + appliedSeconds + " 秒", "成功", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(this, "轨迹拖尾时长更新失败", "错误", JOptionPane.ERROR_MESSAGE); } } private void showFeedbackDialog() { JDialog dialog = new JDialog(this, "问题反馈咨询", true); dialog.setLayout(new BorderLayout(0, 12)); dialog.setResizable(false); dialog.setPreferredSize(new Dimension(400, 800)); dialog.setSize(new Dimension(400, 800)); dialog.setMinimumSize(new Dimension(400, 800)); JPanel content = new JPanel(); content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); content.setBorder(BorderFactory.createEmptyBorder(20, 24, 20, 24)); dialog.add(content, BorderLayout.CENTER); JLabel descriptionLabel = new JLabel("问题描述:"); descriptionLabel.setFont(new Font("微软雅黑", Font.BOLD, 13)); descriptionLabel.setAlignmentX(Component.LEFT_ALIGNMENT); content.add(descriptionLabel); content.add(Box.createRigidArea(new Dimension(0, 8))); JTextArea descriptionArea = new JTextArea(5, 30); descriptionArea.setLineWrap(true); descriptionArea.setWrapStyleWord(true); descriptionArea.setFont(new Font("微软雅黑", Font.PLAIN, 13)); JScrollPane scrollPane = new JScrollPane(descriptionArea); scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT); content.add(scrollPane); content.add(Box.createRigidArea(new Dimension(0, 16))); JPanel photoControls = new JPanel(new FlowLayout(FlowLayout.LEFT, 12, 0)); photoControls.setAlignmentX(Component.LEFT_ALIGNMENT); JLabel photoLabel = new JLabel("选择照片(最多6张):"); photoLabel.setFont(new Font("微软雅黑", Font.BOLD, 13)); JButton selectPhotosButton = buttonset.createStyledButton("选择照片", THEME_COLOR); selectPhotosButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); photoControls.add(photoLabel); photoControls.add(selectPhotosButton); content.add(photoControls); content.add(Box.createRigidArea(new Dimension(0, 20))); JPanel photoGrid = new JPanel(new GridLayout(2, 3, 12, 12)); photoGrid.setAlignmentX(Component.LEFT_ALIGNMENT); photoGrid.setMaximumSize(new Dimension(Integer.MAX_VALUE, 220)); List photoSlots = new ArrayList<>(); for (int i = 0; i < 6; i++) { JLabel slot = buildPhotoSlot(); photoGrid.add(slot); photoSlots.add(slot); } content.add(photoGrid); content.add(Box.createRigidArea(new Dimension(0, 20))); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JButton cancelButton = buttonset.createStyledButton("放弃", new Color(128, 128, 128)); cancelButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); JButton submitButton = buttonset.createStyledButton("提交", THEME_COLOR); submitButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); buttonPanel.add(cancelButton); buttonPanel.add(submitButton); dialog.add(buttonPanel, BorderLayout.SOUTH); List selectedPhotos = new ArrayList<>(); selectPhotosButton.addActionListener(e -> { JFileChooser chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(true); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setFileFilter(new FileNameExtensionFilter("图片文件", "jpg", "jpeg", "png", "bmp", "gif", "webp")); if (chooser.showOpenDialog(dialog) == JFileChooser.APPROVE_OPTION) { File[] files = chooser.getSelectedFiles(); if (files != null) { if (selectedPhotos.size() >= 6) { JOptionPane.showMessageDialog(dialog, "已达到6张照片上限", "提示", JOptionPane.WARNING_MESSAGE); return; } for (File file : files) { if (selectedPhotos.size() >= 6) { break; } if (file != null && file.exists() && file.isFile()) { selectedPhotos.add(file); } } updatePhotoPreview(photoSlots, selectedPhotos); } } }); cancelButton.addActionListener(e -> dialog.dispose()); submitButton.addActionListener(e -> { String description = descriptionArea.getText() != null ? descriptionArea.getText().trim() : ""; if (description.isEmpty()) { JOptionPane.showMessageDialog(dialog, "请填写问题描述", "提示", JOptionPane.WARNING_MESSAGE); descriptionArea.requestFocusInWindow(); return; } // 提交逻辑占位 JOptionPane.showMessageDialog(dialog, "反馈已提交,感谢您的支持!\n描述字数:" + description.length() + ",照片数量:" + selectedPhotos.size(), "提交成功", JOptionPane.INFORMATION_MESSAGE); dialog.dispose(); }); dialog.pack(); dialog.setLocationRelativeTo(this); dialog.setVisible(true); } private JLabel buildPhotoSlot() { JLabel slot = new JLabel(); slot.setPreferredSize(new Dimension(100, 100)); slot.setMinimumSize(new Dimension(100, 100)); slot.setOpaque(true); slot.setBackground(new Color(245, 245, 245)); slot.setHorizontalAlignment(SwingConstants.CENTER); slot.setVerticalAlignment(SwingConstants.CENTER); slot.setBorder(BorderFactory.createLineBorder(new Color(220, 220, 220), 1)); slot.setText("+"); slot.setFont(new Font("微软雅黑", Font.BOLD, 18)); slot.setForeground(new Color(180, 180, 180)); return slot; } private void updatePhotoPreview(List slots, List photos) { for (int i = 0; i < slots.size(); i++) { JLabel slot = slots.get(i); if (i < photos.size()) { File photo = photos.get(i); ImageIcon icon = new ImageIcon(photo.getAbsolutePath()); Image scaled = icon.getImage().getScaledInstance(100, 100, Image.SCALE_SMOOTH); slot.setIcon(new ImageIcon(scaled)); slot.setText(null); } else { slot.setIcon(null); slot.setText("+"); } } } private void checkForUpdates() { // 模拟检查更新过程 checkUpdateBtn.setEnabled(false); checkUpdateBtn.setText("检查中..."); // 使用定时器模拟网络请求 Timer timer = new Timer(2000, e -> { // 这里应该是实际的检查更新逻辑 // 目前只是模拟 checkUpdateBtn.setEnabled(true); checkUpdateBtn.setText("检查更新"); // 假设当前已是最新版本 JOptionPane.showMessageDialog(this, "当前已是最新版本: " + (setData.getAppVersion() != null ? setData.getAppVersion() : "未知"), "检查更新", JOptionPane.INFORMATION_MESSAGE); }); timer.setRepeats(false); timer.start(); } @Override public void setVisible(boolean visible) { if (visible) { setupEventHandlers(); loadData(); // 每次显示时重新加载数据 } super.setVisible(visible); } }