package zhuye;
import javax.swing.*;
import baseStation.BaseStation;
import baseStation.BaseStationDialog;
import java.awt.*;
import java.awt.event.*;
import dikuai.Dikuai;
import dikuai.Dikuaiguanli;
import dikuai.addzhangaiwu;
import gecaoji.Device;
import set.Sets;
import udpdell.UDPServer;
import java.util.Map;
/**
* 首页界面 - 适配6.5寸竖屏,使用独立的MapRenderer进行绘制
*/
public class Shouye extends JPanel {
private static final long serialVersionUID = 1L;
private static Shouye instance;
// 主题颜色
private final Color THEME_COLOR = new Color(46, 139, 87);
private final Color THEME_HOVER_COLOR = new Color(30, 107, 69);
private final Color BACKGROUND_COLOR = new Color(250, 250, 250);
private final Color PANEL_BACKGROUND = new Color(255, 255, 255);
// 组件
private JPanel headerPanel;
private JPanel mainContentPanel;
private JPanel controlPanel;
private JPanel navigationPanel;
private JPanel visualizationPanel;
// 按钮
private JButton startBtn;
private JButton pauseBtn;
private JButton legendBtn;
private JButton remoteBtn;
private JButton areaSelectBtn;
private JButton baseStationBtn;
// 导航按钮
private JButton homeNavBtn;
private JButton areasNavBtn;
private JButton settingsNavBtn;
// 状态显示
private JLabel statusLabel;
private JLabel areaNameLabel;
// 当前选中的导航按钮
private JButton currentNavButton;
// 对话框引用
private LegendDialog legendDialog;
private RemoteControlDialog remoteDialog;
private AreaSelectionDialog areaDialog;
private BaseStationDialog baseStationDialog;
private Sets settingsDialog;
private BaseStation baseStation;
// 地图渲染器
private MapRenderer mapRenderer;
private static final int FLOAT_ICON_SIZE = 32;
private JButton endDrawingButton;
private JButton drawingPauseButton;
private JPanel floatingButtonPanel;
private JPanel floatingButtonColumn;
private Runnable endDrawingCallback;
private boolean drawingPaused;
private ImageIcon pauseIcon;
private ImageIcon pauseActiveIcon;
private ImageIcon endIcon;
private JPanel circleGuidancePanel;
private JLabel circleGuidanceLabel;
private JButton circleGuidancePrimaryButton;
private JButton circleGuidanceSecondaryButton;
private int circleGuidanceStep;
private JDialog circleGuidanceDialog;
private boolean circleDialogMode;
private ComponentAdapter circleDialogOwnerAdapter;
public Shouye() {
instance = this;
baseStation = new BaseStation();
baseStation.load();
initializeUI();
setupEventHandlers();
}
public static Shouye getInstance() {
return instance;
}
private void initializeUI() {
setLayout(new BorderLayout());
setBackground(BACKGROUND_COLOR);
// 创建各个面板
createHeaderPanel();
createMainContentPanel();
createControlPanel();
createNavigationPanel();
// 添加到主面板
add(headerPanel, BorderLayout.NORTH);
add(mainContentPanel, BorderLayout.CENTER);
add(controlPanel, BorderLayout.SOUTH);
// 初始化地图渲染器
mapRenderer = new MapRenderer(visualizationPanel);
// 初始化对话框引用为null,延迟创建
legendDialog = null;
remoteDialog = null;
areaDialog = null;
baseStationDialog = null;
settingsDialog = null;
// 设置默认状态
setNavigationActive(homeNavBtn);
initializeDefaultAreaSelection();
refreshMapForSelectedArea();
}
private void createHeaderPanel() {
headerPanel = new JPanel(new BorderLayout());
headerPanel.setBackground(PANEL_BACKGROUND);
headerPanel.setBorder(BorderFactory.createEmptyBorder(15, 20, 15, 20));
headerPanel.setPreferredSize(new Dimension(0, 80));
// 左侧信息区域
JPanel leftInfoPanel = new JPanel(new GridLayout(2, 1));
leftInfoPanel.setBackground(PANEL_BACKGROUND);
areaNameLabel = new JLabel("未选择地块");
areaNameLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
areaNameLabel.setForeground(Color.BLACK);
areaNameLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
areaNameLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Dikuaiguanli.showDikuaiManagement(Shouye.this, null);
}
@Override
public void mouseEntered(MouseEvent e) {
areaNameLabel.setForeground(THEME_COLOR);
}
@Override
public void mouseExited(MouseEvent e) {
areaNameLabel.setForeground(Color.BLACK);
}
});
statusLabel = new JLabel("待机");
statusLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
statusLabel.setForeground(Color.GRAY);
leftInfoPanel.add(areaNameLabel);
leftInfoPanel.add(statusLabel);
// 右侧操作区域
JPanel rightActionPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
rightActionPanel.setBackground(PANEL_BACKGROUND);
JButton notificationBtn = createIconButton("🔔", 40);
// 修改设置按钮:使用图片替代Unicode图标
JButton settingsBtn = new JButton();
try {
ImageIcon settingsIcon = new ImageIcon("image/sets.png");
// 调整图片大小以适应按钮
Image scaledImage = settingsIcon.getImage().getScaledInstance(30, 30, Image.SCALE_SMOOTH);
settingsBtn.setIcon(new ImageIcon(scaledImage));
} catch (Exception e) {
// 如果图片加载失败,使用默认文本
settingsBtn.setText("设置");
System.err.println("无法加载设置图标: " + e.getMessage());
}
settingsBtn.setPreferredSize(new Dimension(40, 40));
settingsBtn.setBackground(PANEL_BACKGROUND);
settingsBtn.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
settingsBtn.setFocusPainted(false);
// 添加悬停效果
settingsBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
settingsBtn.setBackground(new Color(240, 240, 240));
}
public void mouseExited(MouseEvent e) {
settingsBtn.setBackground(PANEL_BACKGROUND);
}
});
// 添加设置按钮事件
settingsBtn.addActionListener(e -> showSettingsDialog());
rightActionPanel.add(notificationBtn);
rightActionPanel.add(settingsBtn);
headerPanel.add(leftInfoPanel, BorderLayout.WEST);
headerPanel.add(rightActionPanel, BorderLayout.EAST);
}
private void createMainContentPanel() {
mainContentPanel = new JPanel(new BorderLayout());
mainContentPanel.setBackground(BACKGROUND_COLOR);
// 可视化区域 - 使用MapRenderer进行绘制
visualizationPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 委托给MapRenderer进行绘制
if (mapRenderer != null) {
mapRenderer.renderMap(g);
}
}
};
visualizationPanel.setLayout(new BorderLayout());
// 创建功能按钮面板(放在左上角)
JPanel functionButtonsPanel = new JPanel();
functionButtonsPanel.setLayout(new BoxLayout(functionButtonsPanel, BoxLayout.Y_AXIS));
functionButtonsPanel.setOpaque(false);
functionButtonsPanel.setBorder(BorderFactory.createEmptyBorder(20, 5, 0, 0)); // 左边距改为5像素
legendBtn = createFunctionButton("图例", "📖");
baseStationBtn = createFunctionButton("基准站", "📡"); // 调整到第二位
areaSelectBtn = createFunctionButton("地块", "🌿"); // 调整到第三位
remoteBtn = createFunctionButton("遥控", "🎮"); // 调整到最后
functionButtonsPanel.add(legendBtn);
functionButtonsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
functionButtonsPanel.add(baseStationBtn);
functionButtonsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
functionButtonsPanel.add(areaSelectBtn);
functionButtonsPanel.add(Box.createRigidArea(new Dimension(0, 10)));
functionButtonsPanel.add(remoteBtn);
visualizationPanel.add(functionButtonsPanel, BorderLayout.WEST);
mainContentPanel.add(visualizationPanel, BorderLayout.CENTER);
}
private void createControlPanel() {
controlPanel = new JPanel(new BorderLayout());
controlPanel.setBackground(PANEL_BACKGROUND);
controlPanel.setBorder(BorderFactory.createEmptyBorder(15, 20, 15, 20));
controlPanel.setPreferredSize(new Dimension(0, 100));
JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 20, 0));
buttonPanel.setBackground(PANEL_BACKGROUND);
startBtn = createControlButton("开始", THEME_COLOR);
applyButtonIcon(startBtn, "image/startzuoye.png");
pauseBtn = createControlButton("暂停", Color.ORANGE);
applyButtonIcon(pauseBtn, "image/zantingzuoye.png");
pauseBtn.setEnabled(false);
buttonPanel.add(startBtn);
buttonPanel.add(pauseBtn);
controlPanel.add(buttonPanel, BorderLayout.CENTER);
}
private void createNavigationPanel() {
navigationPanel = new JPanel(new GridLayout(1, 3));
navigationPanel.setBackground(PANEL_BACKGROUND);
navigationPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
navigationPanel.setPreferredSize(new Dimension(0, 70));
homeNavBtn = createNavButton("首页", "🏠");
areasNavBtn = createNavButton("地块", "🌿");
settingsNavBtn = createNavButton("设置", "⚙️");
navigationPanel.add(homeNavBtn);
navigationPanel.add(areasNavBtn);
navigationPanel.add(settingsNavBtn);
// 添加到主界面底部
add(navigationPanel, BorderLayout.SOUTH);
}
private JButton createIconButton(String icon, int size) {
JButton button = new JButton(icon);
button.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 20));
button.setPreferredSize(new Dimension(size, size));
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 JButton createFunctionButton(String text, String icon) {
JButton button = new JButton("
" + icon + "
" + text + "");
button.setFont(new Font("微软雅黑", Font.PLAIN, 12));
button.setPreferredSize(new Dimension(80, 70));
button.setBackground(new Color(0, 0, 0, 0)); // 完全透明背景
button.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 只保留内边距
button.setFocusPainted(false);
button.setOpaque(false); // 设置为不透明,确保背景透明
// 去掉悬停效果
button.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
// 悬停时不改变任何样式
}
public void mouseExited(MouseEvent e) {
// 悬停时不改变任何样式
}
});
return button;
}
private JButton createControlButton(String text, Color color) {
JButton button = new JButton(text);
button.setFont(new Font("微软雅黑", Font.BOLD, 16));
button.setBackground(color);
button.setForeground(Color.WHITE);
button.setBorder(BorderFactory.createEmptyBorder(15, 0, 15, 0));
button.setFocusPainted(false);
// 悬停效果
button.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
if (button.isEnabled()) {
if (color == THEME_COLOR) {
button.setBackground(THEME_HOVER_COLOR);
} else {
button.setBackground(new Color(255, 165, 0));
}
}
}
public void mouseExited(MouseEvent e) {
if (button.isEnabled()) {
button.setBackground(color);
}
}
});
return button;
}
private void applyButtonIcon(JButton button, String imagePath) {
try {
ImageIcon icon = new ImageIcon(imagePath);
Image scaledImage = icon.getImage().getScaledInstance(28, 28, Image.SCALE_SMOOTH);
button.setIcon(new ImageIcon(scaledImage));
button.setHorizontalAlignment(SwingConstants.CENTER);
button.setIconTextGap(10);
button.setHorizontalTextPosition(SwingConstants.RIGHT);
button.setVerticalTextPosition(SwingConstants.CENTER);
} catch (Exception e) {
System.err.println("无法加载按钮图标: " + imagePath + " -> " + e.getMessage());
}
}
private JButton createNavButton(String text, String icon) {
JButton button = new JButton("" + icon + "
" + text + "");
button.setFont(new Font("微软雅黑", Font.PLAIN, 12));
button.setBackground(PANEL_BACKGROUND);
button.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
button.setFocusPainted(false);
// 悬停效果
button.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
if (button != currentNavButton) {
button.setBackground(new Color(240, 240, 240));
}
}
public void mouseExited(MouseEvent e) {
if (button != currentNavButton) {
button.setBackground(PANEL_BACKGROUND);
}
}
});
return button;
}
private void setNavigationActive(JButton navButton) {
// 重置所有导航按钮样式
for (Component comp : navigationPanel.getComponents()) {
if (comp instanceof JButton) {
JButton btn = (JButton) comp;
btn.setBackground(PANEL_BACKGROUND);
btn.setForeground(Color.BLACK);
}
}
// 设置当前选中按钮样式
navButton.setBackground(THEME_COLOR);
navButton.setForeground(Color.WHITE);
currentNavButton = navButton;
}
private void setupEventHandlers() {
// 导航按钮事件
homeNavBtn.addActionListener(e -> setNavigationActive(homeNavBtn));
areasNavBtn.addActionListener(e -> setNavigationActive(areasNavBtn));
settingsNavBtn.addActionListener(e -> setNavigationActive(settingsNavBtn));
// 功能按钮事件
legendBtn.addActionListener(e -> showLegendDialog());
remoteBtn.addActionListener(e -> showRemoteControlDialog());
areaSelectBtn.addActionListener(e -> {
// 点击“地块”直接打开地块管理对话框(若需要可传入特定地块编号)
Dikuaiguanli.showDikuaiManagement(this, null);
});
baseStationBtn.addActionListener(e -> showBaseStationDialog());
// 控制按钮事件
startBtn.addActionListener(e -> startMowing());
pauseBtn.addActionListener(e -> pauseMowing());
}
private void showSettingsDialog() {
if (settingsDialog == null) {
Window parentWindow = SwingUtilities.getWindowAncestor(this);
if (parentWindow instanceof JFrame) {
settingsDialog = new Sets((JFrame) parentWindow, THEME_COLOR);
} else if (parentWindow instanceof JDialog) {
settingsDialog = new Sets((JDialog) parentWindow, THEME_COLOR);
} else {
// Fallback to a frameless dialog when no parent is available
settingsDialog = new Sets((JFrame) null, THEME_COLOR);
}
}
settingsDialog.setVisible(true);
}
private void showLegendDialog() {
if (legendDialog == null) {
Window parentWindow = SwingUtilities.getWindowAncestor(this);
if (parentWindow != null) {
legendDialog = new LegendDialog(this, THEME_COLOR);
} else {
// 如果没有父窗口,创建无父窗口的对话框
legendDialog = new LegendDialog((JFrame) null, THEME_COLOR);
}
}
legendDialog.setVisible(true);
}
private void showRemoteControlDialog() {
if (remoteDialog == null) {
Window parentWindow = SwingUtilities.getWindowAncestor(this);
if (parentWindow != null) {
remoteDialog = new RemoteControlDialog(this, THEME_COLOR);
} else {
remoteDialog = new RemoteControlDialog((JFrame) null, THEME_COLOR);
}
}
remoteDialog.setVisible(true);
}
private void showAreaSelectionDialog() {
if (areaDialog == null) {
Window parentWindow = SwingUtilities.getWindowAncestor(this);
if (parentWindow != null) {
areaDialog = new AreaSelectionDialog(this, THEME_COLOR, areaNameLabel, statusLabel);
} else {
areaDialog = new AreaSelectionDialog((JFrame) null, THEME_COLOR, areaNameLabel, statusLabel);
}
}
areaDialog.setVisible(true);
}
private void showBaseStationDialog() {
if (baseStation == null) {
baseStation = new BaseStation();
}
baseStation.load();
Component dialogParent = this;
if (!hasValidBaseStationId()) {
boolean recorded = promptForBaseStationId(dialogParent);
if (!recorded) {
return;
}
}
Device device = new Device();
device.initFromProperties();
if (baseStationDialog == null) {
baseStationDialog = new BaseStationDialog(dialogParent, THEME_COLOR, device, baseStation);
} else {
baseStationDialog.refreshData();
}
baseStationDialog.setVisible(true);
}
private boolean hasValidBaseStationId() {
if (baseStation == null) {
return false;
}
String deviceId = baseStation.getDeviceId();
if (deviceId == null) {
return false;
}
String trimmed = deviceId.trim();
return !trimmed.isEmpty() && !"-1".equals(trimmed);
}
private boolean promptForBaseStationId(Component parentComponent) {
if (baseStation == null) {
baseStation = new BaseStation();
}
while (true) {
String input = JOptionPane.showInputDialog(parentComponent,
"请输入基准站编号", "录入基准站编号", JOptionPane.PLAIN_MESSAGE);
if (input == null) {
return false;
}
String trimmed = input.trim();
if (trimmed.isEmpty()) {
JOptionPane.showMessageDialog(parentComponent,
"基准站编号不能为空,请重新输入。", "提示", JOptionPane.WARNING_MESSAGE);
continue;
}
try {
baseStation.updateByDeviceId(trimmed,
baseStation.getInstallationCoordinates(),
baseStation.getIotSimCardNumber(),
baseStation.getDeviceActivationTime(),
baseStation.getDataUpdateTime());
baseStation.load();
JOptionPane.showMessageDialog(parentComponent,
"基准站编号已保存。", "操作成功", JOptionPane.INFORMATION_MESSAGE);
return true;
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(parentComponent,
ex.getMessage(), "输入错误", JOptionPane.ERROR_MESSAGE);
}
}
}
private void startMowing() {
statusLabel.setText("作业中");
startBtn.setEnabled(false);
pauseBtn.setEnabled(true);
}
private void pauseMowing() {
statusLabel.setText("暂停中");
startBtn.setEnabled(true);
pauseBtn.setEnabled(false);
}
private JButton createFloatingIconButton() {
JButton button = new JButton();
button.setContentAreaFilled(false);
button.setBorder(BorderFactory.createEmptyBorder());
button.setFocusPainted(false);
button.setOpaque(false);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
int size = FLOAT_ICON_SIZE + 8;
button.setPreferredSize(new Dimension(size, size));
return button;
}
private ImageIcon loadScaledIcon(String path, int width, int height) {
try {
ImageIcon icon = new ImageIcon(path);
if (icon.getIconWidth() <= 0 || icon.getIconHeight() <= 0) {
return null;
}
Image scaled = icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
return new ImageIcon(scaled);
} catch (Exception ex) {
System.err.println("加载图标失败: " + path + " - " + ex.getMessage());
return null;
}
}
private void ensureFloatingIconsLoaded() {
if (pauseIcon == null) {
pauseIcon = loadScaledIcon("image/zanting.png", FLOAT_ICON_SIZE, FLOAT_ICON_SIZE);
}
if (pauseActiveIcon == null) {
pauseActiveIcon = loadScaledIcon("image/zantingzhong.png", FLOAT_ICON_SIZE, FLOAT_ICON_SIZE);
}
if (endIcon == null) {
endIcon = loadScaledIcon("image/end.png", FLOAT_ICON_SIZE, FLOAT_ICON_SIZE);
}
}
private void updatePauseButtonVisual() {
if (drawingPauseButton == null) {
return;
}
if (drawingPaused) {
if (pauseActiveIcon != null) {
drawingPauseButton.setIcon(pauseActiveIcon);
drawingPauseButton.setText(null);
} else {
drawingPauseButton.setText("暂停中");
drawingPauseButton.setIcon(null);
}
drawingPauseButton.setToolTipText("点击恢复绘制");
} else {
if (pauseIcon != null) {
drawingPauseButton.setIcon(pauseIcon);
drawingPauseButton.setText(null);
} else {
drawingPauseButton.setText("暂停");
drawingPauseButton.setIcon(null);
}
drawingPauseButton.setToolTipText("点击暂停绘制");
}
}
private void applyDrawingPauseState(boolean paused, boolean notifyCoordinate) {
drawingPaused = paused;
updatePauseButtonVisual();
if (notifyCoordinate) {
Coordinate.setStartSaveGngga(!paused);
}
}
private void toggleDrawingPause() {
applyDrawingPauseState(!drawingPaused, true);
}
public void showEndDrawingButton(Runnable callback) {
showEndDrawingButton(callback, null);
}
public void showEndDrawingButton(Runnable callback, String drawingShape) {
endDrawingCallback = callback;
applyDrawingPauseState(false, false);
circleDialogMode = drawingShape != null && "circle".equalsIgnoreCase(drawingShape);
if (circleDialogMode) {
hideFloatingDrawingControls();
ensureCircleGuidancePanel();
showCircleGuidanceStep(1);
visualizationPanel.revalidate();
visualizationPanel.repaint();
return;
}
circleDialogMode = false;
hideCircleGuidancePanel();
ensureFloatingIconsLoaded();
ensureFloatingButtonInfrastructure();
endDrawingButton.setVisible(true);
if (drawingPauseButton != null) {
drawingPauseButton.setVisible(true);
}
floatingButtonPanel.setVisible(true);
if (floatingButtonPanel.getParent() != visualizationPanel) {
visualizationPanel.add(floatingButtonPanel, BorderLayout.SOUTH);
}
rebuildFloatingButtonColumn();
visualizationPanel.revalidate();
visualizationPanel.repaint();
}
private void ensureFloatingButtonInfrastructure() {
if (endDrawingButton == null) {
endDrawingButton = createFloatingIconButton();
endDrawingButton.addActionListener(e -> {
if (endDrawingCallback != null) {
endDrawingCallback.run();
}
});
}
if (endIcon != null) {
endDrawingButton.setIcon(endIcon);
endDrawingButton.setText(null);
} else {
endDrawingButton.setText("结束绘制");
}
endDrawingButton.setToolTipText("结束绘制");
if (drawingPauseButton == null) {
drawingPauseButton = createFloatingIconButton();
drawingPauseButton.addActionListener(e -> toggleDrawingPause());
}
updatePauseButtonVisual();
if (floatingButtonPanel == null) {
floatingButtonPanel = new JPanel(new BorderLayout());
floatingButtonPanel.setOpaque(false);
floatingButtonPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 20));
floatingButtonColumn = new JPanel();
floatingButtonColumn.setOpaque(false);
floatingButtonColumn.setLayout(new BoxLayout(floatingButtonColumn, BoxLayout.Y_AXIS));
floatingButtonPanel.add(floatingButtonColumn, BorderLayout.EAST);
}
}
private void hideFloatingDrawingControls() {
if (drawingPauseButton != null) {
drawingPauseButton.setVisible(false);
}
if (endDrawingButton != null) {
endDrawingButton.setVisible(false);
}
if (floatingButtonPanel != null) {
floatingButtonPanel.setVisible(false);
}
if (!circleDialogMode) {
rebuildFloatingButtonColumn();
}
}
private void rebuildFloatingButtonColumn() {
if (floatingButtonColumn == null) {
return;
}
floatingButtonColumn.removeAll();
boolean added = false;
if (!circleDialogMode && circleGuidancePanel != null && circleGuidancePanel.isVisible()) {
floatingButtonColumn.add(circleGuidancePanel);
added = true;
}
if (!circleDialogMode && drawingPauseButton != null && drawingPauseButton.isVisible()) {
if (added) {
floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10)));
}
floatingButtonColumn.add(drawingPauseButton);
added = true;
}
if (!circleDialogMode && endDrawingButton != null && endDrawingButton.isVisible()) {
if (added) {
floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10)));
}
floatingButtonColumn.add(endDrawingButton);
}
floatingButtonColumn.revalidate();
floatingButtonColumn.repaint();
}
private void showCircleGuidanceStep(int step) {
ensureCircleGuidancePanel();
if (circleGuidancePanel == null) {
return;
}
circleGuidanceStep = step;
if (step == 1) {
circleGuidanceLabel.setText("是否将当前点设置为圆心?");
circleGuidancePrimaryButton.setText("是");
circleGuidanceSecondaryButton.setText("返回");
circleGuidanceSecondaryButton.setVisible(true);
} else if (step == 2) {
circleGuidanceLabel.setText("是否将当前点设置为半径点?");
circleGuidancePrimaryButton.setText("是");
circleGuidanceSecondaryButton.setVisible(false);
} else {
hideCircleGuidancePanel();
return;
}
circleGuidancePanel.setVisible(true);
if (circleDialogMode) {
ensureCircleGuidanceDialog();
if (circleGuidanceDialog != null) {
circleGuidanceDialog.pack();
positionCircleGuidanceDialog();
circleGuidanceDialog.setVisible(true);
circleGuidanceDialog.toFront();
}
} else {
rebuildFloatingButtonColumn();
}
}
private void ensureCircleGuidancePanel() {
if (circleGuidancePanel != null) {
return;
}
circleGuidancePanel = new JPanel();
circleGuidancePanel.setLayout(new BoxLayout(circleGuidancePanel, BoxLayout.Y_AXIS));
circleGuidancePanel.setOpaque(true);
circleGuidancePanel.setBackground(new Color(255, 255, 255, 235));
circleGuidancePanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(THEME_COLOR, 1),
BorderFactory.createEmptyBorder(10, 12, 10, 12)));
circleGuidancePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
circleGuidanceLabel = new JLabel();
circleGuidanceLabel.setFont(new Font("微软雅黑", Font.BOLD, 13));
circleGuidanceLabel.setForeground(new Color(33, 37, 41));
circleGuidanceLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel buttonRow = new JPanel();
buttonRow.setLayout(new BoxLayout(buttonRow, BoxLayout.X_AXIS));
buttonRow.setOpaque(false);
buttonRow.setAlignmentX(Component.LEFT_ALIGNMENT);
circleGuidancePrimaryButton = createGuidanceButton("是", THEME_COLOR, Color.WHITE, true);
circleGuidancePrimaryButton.addActionListener(e -> onCircleGuidancePrimary());
circleGuidanceSecondaryButton = createGuidanceButton("否", Color.WHITE, THEME_COLOR, false);
circleGuidanceSecondaryButton.addActionListener(e -> onCircleGuidanceSecondary());
buttonRow.add(circleGuidancePrimaryButton);
buttonRow.add(Box.createRigidArea(new Dimension(8, 0)));
buttonRow.add(circleGuidanceSecondaryButton);
circleGuidancePanel.add(circleGuidanceLabel);
circleGuidancePanel.add(Box.createRigidArea(new Dimension(0, 8)));
circleGuidancePanel.add(buttonRow);
circleGuidancePanel.setVisible(false);
}
private void ensureCircleGuidanceDialog() {
if (circleGuidancePanel == null) {
return;
}
if (circleGuidanceDialog != null) {
if (circleGuidancePanel.getParent() != circleGuidanceDialog.getContentPane()) {
detachCircleGuidancePanel();
circleGuidanceDialog.getContentPane().removeAll();
circleGuidanceDialog.getContentPane().add(circleGuidancePanel, BorderLayout.CENTER);
circleGuidanceDialog.pack();
}
return;
}
Window owner = SwingUtilities.getWindowAncestor(this);
circleGuidanceDialog = new JDialog(owner, "绘制提示", Dialog.ModalityType.MODELESS);
circleGuidanceDialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
circleGuidanceDialog.setResizable(false);
circleGuidanceDialog.setAlwaysOnTop(true);
if (owner != null && circleDialogOwnerAdapter == null) {
circleDialogOwnerAdapter = new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
positionCircleGuidanceDialog();
}
@Override
public void componentResized(ComponentEvent e) {
positionCircleGuidanceDialog();
}
};
owner.addComponentListener(circleDialogOwnerAdapter);
}
detachCircleGuidancePanel();
circleGuidanceDialog.getContentPane().setLayout(new BorderLayout());
circleGuidanceDialog.getContentPane().add(circleGuidancePanel, BorderLayout.CENTER);
circleGuidanceDialog.pack();
}
private void detachCircleGuidancePanel() {
if (circleGuidancePanel == null) {
return;
}
Container parent = circleGuidancePanel.getParent();
if (parent != null) {
parent.remove(circleGuidancePanel);
parent.revalidate();
parent.repaint();
}
}
private void positionCircleGuidanceDialog() {
if (circleGuidanceDialog == null) {
return;
}
Window owner = SwingUtilities.getWindowAncestor(this);
if (owner == null || !owner.isShowing()) {
return;
}
try {
Point ownerLocation = owner.getLocationOnScreen();
int x = ownerLocation.x + owner.getWidth() - circleGuidanceDialog.getWidth() - 30;
int y = ownerLocation.y + owner.getHeight() - circleGuidanceDialog.getHeight() - 40;
x = Math.max(ownerLocation.x, x);
y = Math.max(ownerLocation.y, y);
circleGuidanceDialog.setLocation(x, y);
} catch (IllegalComponentStateException ex) {
// Owner not yet displayable; skip positioning
}
}
private JButton createGuidanceButton(String text, Color bg, Color fg, boolean filled) {
JButton button = new JButton(text);
button.setFont(new Font("微软雅黑", Font.BOLD, 12));
button.setForeground(fg);
button.setBackground(bg);
button.setOpaque(true);
button.setFocusPainted(false);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.setAlignmentX(Component.LEFT_ALIGNMENT);
if (filled) {
button.setBorder(BorderFactory.createEmptyBorder(6, 14, 6, 14));
} else {
button.setBackground(Color.WHITE);
button.setOpaque(true);
button.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(THEME_COLOR, 1),
BorderFactory.createEmptyBorder(5, 12, 5, 12)));
}
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
if (filled) {
button.setBackground(THEME_HOVER_COLOR);
} else {
button.setBackground(new Color(245, 245, 245));
}
}
@Override
public void mouseExited(MouseEvent e) {
if (filled) {
button.setBackground(bg);
} else {
button.setBackground(Color.WHITE);
}
}
});
return button;
}
private void onCircleGuidancePrimary() {
if (circleGuidanceStep == 1) {
showCircleGuidanceStep(2);
} else {
handleCircleCompletion();
}
}
private void onCircleGuidanceSecondary() {
if (circleGuidanceStep == 1) {
handleCircleAbort(null);
} else if (circleGuidanceStep == 2) {
handleCircleAbort(null);
} else {
hideCircleGuidancePanel();
}
}
private void hideCircleGuidancePanel() {
circleGuidanceStep = 0;
if (circleGuidancePanel != null) {
circleGuidancePanel.setVisible(false);
}
if (circleGuidanceDialog != null) {
circleGuidanceDialog.setVisible(false);
}
if (!circleDialogMode) {
rebuildFloatingButtonColumn();
}
}
private void handleCircleAbort(String message) {
// Return the wizard to step 2 without committing any captured points
hideEndDrawingButton();
addzhangaiwu.abortCircleDrawingAndReturn(message);
}
private void handleCircleCompletion() {
hideCircleGuidancePanel();
if (endDrawingCallback != null) {
endDrawingCallback.run();
} else {
addzhangaiwu.finishDrawingSession();
}
}
public void hideEndDrawingButton() {
hideCircleGuidancePanel();
hideFloatingDrawingControls();
circleDialogMode = false;
applyDrawingPauseState(false, false);
endDrawingCallback = null;
visualizationPanel.revalidate();
visualizationPanel.repaint();
}
/**
* 获取地图渲染器实例
*/
public MapRenderer getMapRenderer() {
return mapRenderer;
}
public void updateCurrentAreaName(String areaName) {
if (areaNameLabel == null) {
return;
}
if (areaName == null || areaName.trim().isEmpty()) {
areaNameLabel.setText("未选择地块");
} else {
areaNameLabel.setText(areaName);
}
}
/**
* 重置地图视图
*/
public void resetMapView() {
if (mapRenderer != null) {
mapRenderer.resetView();
}
}
private void initializeDefaultAreaSelection() {
Dikuai.initFromProperties();
Map all = Dikuai.getAllDikuai();
if (all.isEmpty()) {
Dikuaiguanli.setCurrentWorkLand(null, null);
} else if (all.size() == 1) {
Dikuai only = all.values().iterator().next();
if (only != null) {
Dikuaiguanli.setCurrentWorkLand(only.getLandNumber(), only.getLandName());
}
}
}
private void refreshMapForSelectedArea() {
if (mapRenderer == null) {
return;
}
String currentLandNumber = Dikuaiguanli.getCurrentWorkLandNumber();
if (isMeaningfulValue(currentLandNumber)) {
Dikuai current = Dikuai.getDikuai(currentLandNumber);
String landName = current != null ? current.getLandName() : null;
Dikuaiguanli.setCurrentWorkLand(currentLandNumber, landName);
return;
}
String labelName = areaNameLabel != null ? areaNameLabel.getText() : null;
if (!isMeaningfulAreaName(labelName)) {
Dikuaiguanli.setCurrentWorkLand(null, null);
return;
}
Map all = Dikuai.getAllDikuai();
for (Dikuai dikuai : all.values()) {
if (dikuai == null) {
continue;
}
String candidateName = dikuai.getLandName();
if (candidateName != null && candidateName.trim().equals(labelName.trim())) {
Dikuaiguanli.setCurrentWorkLand(dikuai.getLandNumber(), candidateName);
return;
}
}
Dikuaiguanli.setCurrentWorkLand(null, null);
}
private boolean isMeaningfulValue(String value) {
if (value == null) {
return false;
}
String trimmed = value.trim();
return !trimmed.isEmpty() && !"-1".equals(trimmed);
}
private boolean isMeaningfulAreaName(String value) {
if (value == null) {
return false;
}
String trimmed = value.trim();
if (trimmed.isEmpty()) {
return false;
}
return !"未选择地块".equals(trimmed);
}
// 测试方法
public static void main(String[] args) {
JFrame frame = new JFrame("AutoMow - 首页");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 800);
frame.setLocationRelativeTo(null);
Shouye shouye = new Shouye();
frame.add(shouye);
frame.setVisible(true);
UDPServer.startAsync();//启动数据接收线程
}
}