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 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; 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(); } 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); pauseBtn = createControlButton("暂停", Color.ORANGE); 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 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) { ensureFloatingIconsLoaded(); 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)); floatingButtonColumn.add(drawingPauseButton); floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10))); floatingButtonColumn.add(endDrawingButton); floatingButtonPanel.add(floatingButtonColumn, BorderLayout.EAST); } else if (floatingButtonColumn != null) { floatingButtonColumn.removeAll(); floatingButtonColumn.add(drawingPauseButton); floatingButtonColumn.add(Box.createRigidArea(new Dimension(0, 10))); floatingButtonColumn.add(endDrawingButton); } endDrawingCallback = callback; endDrawingButton.setVisible(true); if (drawingPauseButton != null) { drawingPauseButton.setVisible(true); } applyDrawingPauseState(false, false); floatingButtonPanel.setVisible(true); if (floatingButtonPanel.getParent() != visualizationPanel) { visualizationPanel.add(floatingButtonPanel, BorderLayout.SOUTH); } visualizationPanel.revalidate(); visualizationPanel.repaint(); } public void hideEndDrawingButton() { if (endDrawingButton != null) { endDrawingButton.setVisible(false); } if (drawingPauseButton != null) { drawingPauseButton.setVisible(false); } if (floatingButtonPanel != null) { floatingButtonPanel.setVisible(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()); } } } // 测试方法 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();//启动数据接收线程 } }