张世豪
2025-12-01 d709e6dad60398fd599900cf781d0dd1e8c37c1c
src/zhuye/Shouye.java
@@ -10,6 +10,7 @@
import dikuai.Dikuai;
import dikuai.Dikuaiguanli;
import dikuai.addzhangaiwu;
import gecaoji.Device;
import set.Sets;
import udpdell.UDPServer;
@@ -75,6 +76,14 @@
    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;
@@ -117,6 +126,7 @@
        setNavigationActive(homeNavBtn);
        initializeDefaultAreaSelection();
        refreshMapForSelectedArea();
    }
    
    private void createHeaderPanel() {
@@ -250,8 +260,10 @@
        JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 20, 0));
        buttonPanel.setBackground(PANEL_BACKGROUND);
        
        startBtn = createControlButton("开始", THEME_COLOR);
        pauseBtn = createControlButton("暂停", Color.ORANGE);
    startBtn = createControlButton("开始", THEME_COLOR);
    applyButtonIcon(startBtn, "image/startzuoye.png");
    pauseBtn = createControlButton("暂停", Color.ORANGE);
    applyButtonIcon(pauseBtn, "image/zantingzuoye.png");
        pauseBtn.setEnabled(false);
        
        buttonPanel.add(startBtn);
@@ -349,6 +361,20 @@
        
        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("<html><center>" + icon + "<br>" + text + "</center></html>");
@@ -625,8 +651,45 @@
    }
    public void showEndDrawingButton(Runnable callback) {
        ensureFloatingIconsLoaded();
        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 -> {
@@ -657,41 +720,288 @@
            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);
        }
    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();
@@ -738,6 +1048,59 @@
        }
    }
    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<String, Dikuai> 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 - 首页");