package set;
|
|
import baseStation.BaseStation;
|
|
import zhuye.MapRenderer;
|
import zhuye.Shouye;
|
import zhuye.buttonset;
|
import zhuye.celiangmoshi;
|
import javax.swing.*;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
|
import java.awt.*;
|
import java.awt.event.*;
|
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 JLabel measurementModeEnabledLabel;
|
|
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 measurementModePanel = createMeasurementModePanel();
|
measurementModeEnabledLabel = (JLabel) measurementModePanel.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, measurementModePanel, 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 JPanel createMeasurementModePanel() {
|
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);
|
|
measurementModeEnabledLabel = new JLabel(setData.isMeasurementModeEnabled() ? "已开启" : "已关闭");
|
measurementModeEnabledLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
measurementModeEnabledLabel.setForeground(Color.DARK_GRAY);
|
gbc = new GridBagConstraints();
|
gbc.gridx = 1;
|
gbc.gridy = 0;
|
gbc.weightx = 1.0;
|
gbc.anchor = GridBagConstraints.EAST;
|
panel.add(measurementModeEnabledLabel, gbc);
|
|
panel.putClientProperty("valueLabel", measurementModeEnabledLabel);
|
|
// 创建切换按钮(使用图标)
|
JButton toggleBtn = createMeasurementModeToggleButton();
|
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 createMeasurementModeToggleButton() {
|
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));
|
|
updateMeasurementModeToggleButton(button);
|
|
button.addActionListener(e -> toggleMeasurementMode(button));
|
|
return button;
|
}
|
|
/**
|
* 更新测量模式切换按钮图标
|
*/
|
private void updateMeasurementModeToggleButton(JButton button) {
|
boolean isEnabled = setData.isMeasurementModeEnabled();
|
try {
|
String iconPath = isEnabled ? "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(isEnabled ? "开" : "关");
|
}
|
} catch (Exception e) {
|
button.setIcon(null);
|
button.setText(isEnabled ? "开" : "关");
|
System.err.println("无法加载测量模式图标: " + e.getMessage());
|
}
|
}
|
|
/**
|
* 切换测量模式状态
|
*/
|
private void toggleMeasurementMode(JButton button) {
|
boolean newValue = !setData.isMeasurementModeEnabled();
|
setData.setMeasurementModeEnabled(newValue);
|
|
// 保存到配置文件
|
setData.updateProperty("measurementModeEnabled", String.valueOf(newValue));
|
|
// 更新UI
|
if (measurementModeEnabledLabel != null) {
|
measurementModeEnabledLabel.setText(newValue ? "已开启" : "已关闭");
|
}
|
updateMeasurementModeToggleButton(button);
|
|
// 通知MapRenderer更新
|
Shouye shouye = Shouye.getInstance();
|
if (shouye != null) {
|
MapRenderer renderer = shouye.getMapRenderer();
|
if (renderer != null) {
|
renderer.setMeasurementMode(newValue);
|
}
|
if (newValue) {
|
celiangmoshi.start();
|
} else {
|
celiangmoshi.stop();
|
}
|
// 刷新地图显示(通过MapRenderer触发重绘)
|
if (renderer != null) {
|
renderer.repaint();
|
}
|
}
|
}
|
|
/**
|
* 创建边界距离显示切换按钮
|
*/
|
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);
|
}
|
}
|
|
// 更新测量模式状态
|
if (measurementModeEnabledLabel != null) {
|
measurementModeEnabledLabel.setText(setData.isMeasurementModeEnabled() ? "已开启" : "已关闭");
|
}
|
// 更新测量模式切换按钮图标
|
JPanel measurementModePanel = (JPanel) measurementModeEnabledLabel.getParent();
|
if (measurementModePanel != null) {
|
JButton toggleBtn = (JButton) measurementModePanel.getClientProperty("toggleButton");
|
if (toggleBtn != null) {
|
updateMeasurementModeToggleButton(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<JLabel> 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<File> 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<JLabel> slots, List<File> 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);
|
}
|
|
}
|