| | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import ui.UIConfig; |
| | | import ui.UIUtils; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | |
| | | |
| | | import lujing.Lunjingguihua; |
| | | import lujing.MowingPathGenerationPage; |
| | | import publicway.Fuzhibutton; |
| | | import publicway.Lookbutton; |
| | | import publicway.buttonset; |
| | | import zhangaiwu.AddDikuai; |
| | | import zhangaiwu.Obstacledge; |
| | | import zhuye.MapRenderer; |
| | |
| | | contentPanel.add(mowingSafetyDistancePanel); |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | // 返回点坐标(带修改按钮) |
| | | contentPanel.add(createCardInfoItemWithButton("返回点坐标:", |
| | | getDisplayValue(dikuai.getReturnPointCoordinates(), "未设置"), |
| | | "修改", e -> editReturnPoint(dikuai))); |
| | | // 往返点路径(带查看图标按钮) |
| | | JPanel returnPathPanel = createCardInfoItemWithIconButton("往返点路径:", |
| | | createViewButton(e -> editReturnPath(dikuai))); |
| | | configureInteractiveLabel(getInfoItemTitleLabel(returnPathPanel), |
| | | () -> editReturnPath(dikuai), |
| | | "点击查看/编辑往返点路径"); |
| | | contentPanel.add(returnPathPanel); |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | ObstacleSummary obstacleSummary = getObstacleSummaryFromCache(dikuai.getLandNumber()); |
| | |
| | | } |
| | | |
| | | private String promptCoordinateEditing(String title, String initialValue) { |
| | | return promptCoordinateEditing(title, initialValue, null); |
| | | } |
| | | |
| | | private String promptCoordinateEditing(String title, String initialValue, Dikuai dikuai) { |
| | | // 判断是否是往返点路径对话框 |
| | | boolean isReturnPathDialog = title != null && title.contains("往返点路径"); |
| | | |
| | | if (isReturnPathDialog) { |
| | | Window owner = SwingUtilities.getWindowAncestor(this); |
| | | Wangfanpathpage page = new Wangfanpathpage(owner, title, initialValue, dikuai); |
| | | page.setVisible(true); |
| | | return page.getResult(); |
| | | } |
| | | |
| | | JTextArea textArea = new JTextArea(prepareCoordinateForEditor(initialValue)); |
| | | textArea.setLineWrap(true); |
| | | textArea.setWrapStyleWord(true); |
| | |
| | | textArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); |
| | | |
| | | JScrollPane scrollPane = new JScrollPane(textArea); |
| | | scrollPane.setPreferredSize(new Dimension(360, 240)); |
| | | // 如果是往返点路径对话框,高度调整为适应两个文本域 |
| | | scrollPane.setPreferredSize(new Dimension(360, isReturnPathDialog ? 100 : 240)); |
| | | |
| | | Window owner = SwingUtilities.getWindowAncestor(this); |
| | | JDialog dialog; |
| | |
| | | } |
| | | dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| | | |
| | | JPanel contentPanel = new JPanel(new BorderLayout()); |
| | | JPanel contentPanel = new JPanel(); |
| | | contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); |
| | | contentPanel.add(scrollPane, BorderLayout.CENTER); |
| | | |
| | | if (isReturnPathDialog) { |
| | | contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); |
| | | // 减小边距以增加文本域宽度 (98%左右) |
| | | contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| | | |
| | | // 1. 原始往返路径坐标区域 |
| | | String rawCoords = dikuai != null ? prepareCoordinateForEditor(dikuai.getReturnPathRawCoordinates()) : ""; |
| | | int rawCount = 0; |
| | | if (rawCoords != null && !rawCoords.isEmpty() && !"-1".equals(rawCoords)) { |
| | | rawCount = rawCoords.split(";").length; |
| | | } |
| | | |
| | | JPanel rawHeaderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
| | | rawHeaderPanel.setAlignmentX(Component.LEFT_ALIGNMENT); |
| | | rawHeaderPanel.setBackground(BACKGROUND_COLOR); |
| | | rawHeaderPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30)); |
| | | |
| | | JLabel rawTitleLabel = new JLabel("原始往返路径坐标 (" + rawCount + "点) "); |
| | | rawTitleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); |
| | | rawHeaderPanel.add(rawTitleLabel); |
| | | |
| | | // 原始坐标复制按钮 |
| | | final String finalRawCoords = rawCoords; |
| | | JButton rawCopyBtn = Fuzhibutton.createCopyButton( |
| | | () -> { |
| | | if (finalRawCoords == null || finalRawCoords.isEmpty() || "-1".equals(finalRawCoords)) return null; |
| | | return finalRawCoords; |
| | | }, |
| | | "复制", |
| | | new Color(230, 250, 240) |
| | | ); |
| | | rawCopyBtn.setFont(new Font("微软雅黑", Font.PLAIN, 12)); |
| | | rawCopyBtn.setPreferredSize(new Dimension(50, 24)); |
| | | rawCopyBtn.setMargin(new Insets(0,0,0,0)); |
| | | rawHeaderPanel.add(rawCopyBtn); |
| | | |
| | | contentPanel.add(rawHeaderPanel); |
| | | contentPanel.add(Box.createVerticalStrut(5)); |
| | | |
| | | JTextArea rawTextArea = new JTextArea(rawCoords); |
| | | rawTextArea.setLineWrap(true); |
| | | rawTextArea.setWrapStyleWord(true); |
| | | rawTextArea.setFont(new Font("微软雅黑", Font.PLAIN, 13)); |
| | | rawTextArea.setEditable(false); // 原始坐标通常不可编辑 |
| | | rawTextArea.setRows(4); |
| | | rawTextArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| | | |
| | | JScrollPane rawScroll = new JScrollPane(rawTextArea); |
| | | rawScroll.setAlignmentX(Component.LEFT_ALIGNMENT); |
| | | // 设置最大宽度允许扩展,首选宽度适中 |
| | | rawScroll.setPreferredSize(new Dimension(300, 100)); |
| | | rawScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, 100)); |
| | | contentPanel.add(rawScroll); |
| | | |
| | | contentPanel.add(Box.createVerticalStrut(15)); |
| | | |
| | | // 2. 优化后往返路径坐标区域 |
| | | String optCoords = prepareCoordinateForEditor(initialValue); |
| | | int optCount = 0; |
| | | if (optCoords != null && !optCoords.isEmpty() && !"-1".equals(optCoords)) { |
| | | optCount = optCoords.split(";").length; |
| | | } |
| | | |
| | | JPanel optHeaderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
| | | optHeaderPanel.setAlignmentX(Component.LEFT_ALIGNMENT); |
| | | optHeaderPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30)); |
| | | |
| | | JLabel optTitleLabel = new JLabel("优化后往返路径坐标 (" + optCount + "点) "); |
| | | optTitleLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); |
| | | optHeaderPanel.add(optTitleLabel); |
| | | |
| | | // 优化坐标复制按钮 - 动态获取文本域内容 |
| | | JButton optCopyBtn = Fuzhibutton.createCopyButton( |
| | | () -> { |
| | | String text = textArea.getText(); |
| | | if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) return null; |
| | | return text; |
| | | }, |
| | | "复制", |
| | | new Color(230, 250, 240) |
| | | ); |
| | | optCopyBtn.setFont(new Font("微软雅黑", Font.PLAIN, 12)); |
| | | optCopyBtn.setPreferredSize(new Dimension(50, 24)); |
| | | optCopyBtn.setMargin(new Insets(0,0,0,0)); |
| | | optHeaderPanel.add(optCopyBtn); |
| | | |
| | | contentPanel.add(optHeaderPanel); |
| | | contentPanel.add(Box.createVerticalStrut(5)); |
| | | |
| | | // 使用传入的 textArea (已初始化为 initialValue) |
| | | textArea.setRows(4); |
| | | scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT); |
| | | scrollPane.setPreferredSize(new Dimension(300, 100)); |
| | | scrollPane.setMaximumSize(new Dimension(Integer.MAX_VALUE, 100)); |
| | | contentPanel.add(scrollPane); |
| | | |
| | | } else { |
| | | contentPanel.setLayout(new BorderLayout()); |
| | | contentPanel.add(scrollPane, BorderLayout.CENTER); |
| | | } |
| | | |
| | | JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
| | | JButton okButton = new JButton("确定"); |
| | | JButton cancelButton = new JButton("取消"); |
| | | JButton copyButton = new JButton("复制"); |
| | | |
| | | JButton okButton; |
| | | JButton cancelButton; |
| | | JButton copyButton = null; // 初始化为null |
| | | |
| | | if (isReturnPathDialog) { |
| | | // 往返点路径对话框:使用 buttonset 风格的确定按钮,图标按钮 |
| | | okButton = buttonset.createStyledButton("去绘制", new Color(70, 130, 220)); |
| | | |
| | | // 取消按钮使用 closepage.png 图标 |
| | | cancelButton = new JButton(); |
| | | ImageIcon closeIcon = loadIcon("image/closepage.png", 25, 25); |
| | | if (closeIcon != null) { |
| | | cancelButton.setIcon(closeIcon); |
| | | } else { |
| | | cancelButton.setText("关闭"); |
| | | } |
| | | cancelButton.setFont(new Font("微软雅黑", Font.PLAIN, 11)); |
| | | cancelButton.setForeground(PRIMARY_COLOR); |
| | | cancelButton.setBorder(BorderFactory.createEmptyBorder()); |
| | | cancelButton.setContentAreaFilled(false); |
| | | cancelButton.setFocusPainted(false); |
| | | cancelButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | cancelButton.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { cancelButton.setOpaque(true); cancelButton.setBackground(new Color(255, 240, 240)); } |
| | | public void mouseExited(MouseEvent e) { cancelButton.setOpaque(false); } |
| | | }); |
| | | |
| | | // 使用 Fuzhibutton 创建复制按钮 (这里不再需要底部的复制按钮,因为上面已经有了) |
| | | // copyButton = ... |
| | | |
| | | } else { |
| | | // 其他对话框保持原有样式 |
| | | okButton = new JButton("确定"); |
| | | cancelButton = new JButton("取消"); |
| | | copyButton = new JButton("复制"); |
| | | |
| | | // 其他对话框的复制按钮逻辑 |
| | | copyButton.addActionListener(e -> { |
| | | String text = textArea.getText(); |
| | | if (text == null) { |
| | | text = ""; |
| | | } |
| | | String trimmed = text.trim(); |
| | | if (trimmed.isEmpty() || "-1".equals(trimmed)) { |
| | | JOptionPane.showMessageDialog(dialog, title + " 未设置", "提示", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | try { |
| | | StringSelection selection = new StringSelection(text); |
| | | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); |
| | | clipboard.setContents(selection, selection); |
| | | JOptionPane.showMessageDialog(dialog, title + " 已复制到剪贴板", "提示", JOptionPane.INFORMATION_MESSAGE); |
| | | } catch (Exception ex) { |
| | | JOptionPane.showMessageDialog(dialog, "复制失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | final boolean[] confirmed = new boolean[] {false}; |
| | | final String[] resultHolder = new String[1]; |
| | | |
| | | okButton.addActionListener(e -> { |
| | | resultHolder[0] = textArea.getText(); |
| | | confirmed[0] = true; |
| | | dialog.dispose(); |
| | | if (isReturnPathDialog) { |
| | | // 往返点路径对话框:标记为打开绘制页面 |
| | | // 如果文本域中已经有坐标,表示要重新绘制 |
| | | String currentText = textArea.getText(); |
| | | if (currentText != null && !currentText.trim().isEmpty() && !"-1".equals(currentText.trim())) { |
| | | // 有坐标,表示重新绘制 |
| | | resultHolder[0] = "__OPEN_DRAW_PAGE_REFRESH__"; |
| | | } else { |
| | | // 没有坐标,正常绘制 |
| | | resultHolder[0] = "__OPEN_DRAW_PAGE__"; |
| | | } |
| | | confirmed[0] = true; |
| | | dialog.dispose(); |
| | | } else { |
| | | resultHolder[0] = textArea.getText(); |
| | | confirmed[0] = true; |
| | | dialog.dispose(); |
| | | } |
| | | }); |
| | | |
| | | cancelButton.addActionListener(e -> dialog.dispose()); |
| | | |
| | | copyButton.addActionListener(e -> { |
| | | String text = textArea.getText(); |
| | | if (text == null) { |
| | | text = ""; |
| | | } |
| | | String trimmed = text.trim(); |
| | | if (trimmed.isEmpty() || "-1".equals(trimmed)) { |
| | | JOptionPane.showMessageDialog(dialog, title + " 未设置", "提示", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | try { |
| | | StringSelection selection = new StringSelection(text); |
| | | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); |
| | | clipboard.setContents(selection, selection); |
| | | JOptionPane.showMessageDialog(dialog, title + " 已复制到剪贴板", "提示", JOptionPane.INFORMATION_MESSAGE); |
| | | } catch (Exception ex) { |
| | | JOptionPane.showMessageDialog(dialog, "复制失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | }); |
| | | |
| | | buttonPanel.add(okButton); |
| | | buttonPanel.add(cancelButton); |
| | | buttonPanel.add(copyButton); |
| | | if (copyButton != null) { |
| | | buttonPanel.add(copyButton); |
| | | } |
| | | |
| | | contentPanel.add(buttonPanel, BorderLayout.SOUTH); |
| | | contentPanel.add(buttonPanel, isReturnPathDialog ? null : BorderLayout.SOUTH); |
| | | if (isReturnPathDialog) { |
| | | // 对于 BoxLayout,直接添加到底部 |
| | | JPanel bottomWrapper = new JPanel(new BorderLayout()); |
| | | bottomWrapper.add(buttonPanel, BorderLayout.EAST); |
| | | contentPanel.add(bottomWrapper); |
| | | } |
| | | dialog.setContentPane(contentPanel); |
| | | dialog.getRootPane().setDefaultButton(okButton); |
| | | dialog.pack(); |
| | | |
| | | // 如果是往返点路径对话框,设置宽度为首页的90%,高度保持不变 |
| | | if (isReturnPathDialog) { |
| | | Shouye shouye = Shouye.getInstance(); |
| | | if (shouye != null && shouye.getWidth() > 0) { |
| | | int homeWidth = shouye.getWidth(); |
| | | int dialogWidth = (int)(homeWidth * 0.9); |
| | | Dimension currentSize = dialog.getSize(); |
| | | dialog.setSize(dialogWidth, currentSize.height); |
| | | } |
| | | } |
| | | |
| | | dialog.setLocationRelativeTo(this); |
| | | dialog.setVisible(true); |
| | | |
| | |
| | | } |
| | | |
| | | private JButton createViewButton(ActionListener listener) { |
| | | JButton btn = new JButton(); |
| | | ImageIcon lookIcon = loadIcon("image/look.png", 25, 25); |
| | | if (lookIcon != null) { |
| | | btn.setIcon(lookIcon); |
| | | } else { |
| | | btn.setText("查看"); |
| | | } |
| | | btn.setFont(new Font("微软雅黑", Font.PLAIN, 11)); |
| | | btn.setForeground(PRIMARY_COLOR); |
| | | btn.setBorder(BorderFactory.createEmptyBorder()); |
| | | btn.setContentAreaFilled(false); |
| | | btn.setFocusPainted(false); |
| | | btn.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | btn.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { btn.setOpaque(true); btn.setBackground(new Color(230, 250, 240)); } |
| | | public void mouseExited(MouseEvent e) { btn.setOpaque(false); } |
| | | }); |
| | | if (listener != null) { |
| | | btn.addActionListener(listener); |
| | | } |
| | | return btn; |
| | | // 使用 Lookbutton 类创建查看按钮 |
| | | return Lookbutton.createViewButton(listener, new Color(230, 250, 240)); |
| | | } |
| | | |
| | | private JButton createPrimaryFooterButton(String text) { |
| | |
| | | }); |
| | | } |
| | | |
| | | private void editReturnPoint(Dikuai dikuai) { |
| | | FanhuiDialog fd = new FanhuiDialog(SwingUtilities.getWindowAncestor(this), dikuai); |
| | | fd.setVisible(true); |
| | | // 如果对话框已更新数据,刷新显示 |
| | | if (fd.isUpdated()) { |
| | | loadDikuaiData(); |
| | | private void editReturnPath(Dikuai dikuai) { |
| | | if (dikuai == null) { |
| | | return; |
| | | } |
| | | String edited = promptCoordinateEditing("查看 / 编辑往返点路径", dikuai.getReturnPathCoordinates(), dikuai); |
| | | if (edited == null) { |
| | | return; |
| | | } |
| | | // 检查是否是特殊标记,表示点击了"去绘制"按钮 |
| | | if ("__OPEN_DRAW_PAGE__".equals(edited) || "__OPEN_DRAW_PAGE_REFRESH__".equals(edited)) { |
| | | // 获取地块管理对话框 |
| | | Window owner = SwingUtilities.getWindowAncestor(this); |
| | | Window managementWindow = null; |
| | | if (owner instanceof JDialog) { |
| | | managementWindow = owner; |
| | | } |
| | | |
| | | // 获取地块管理对话框的父窗口(主窗口),作为绘制页面的父窗口 |
| | | Window drawPageOwner = null; |
| | | if (managementWindow != null) { |
| | | drawPageOwner = managementWindow.getOwner(); |
| | | } |
| | | if (drawPageOwner == null && owner != null) { |
| | | drawPageOwner = owner.getOwner(); |
| | | } |
| | | if (drawPageOwner == null) { |
| | | drawPageOwner = owner; |
| | | } |
| | | |
| | | // 先关闭地块管理页面 |
| | | if (managementWindow != null) { |
| | | managementWindow.dispose(); |
| | | } |
| | | |
| | | // 然后打开绘制页面,如果是重新绘制,传递标记 |
| | | boolean isRefresh = "__OPEN_DRAW_PAGE_REFRESH__".equals(edited); |
| | | Huizhiwanfanpath.showDrawReturnPathDialog(drawPageOwner, dikuai, isRefresh); |
| | | return; |
| | | } |
| | | String normalized = normalizeCoordinateInput(edited); |
| | | if (!saveFieldAndRefresh(dikuai, "returnPathCoordinates", normalized)) { |
| | | JOptionPane.showMessageDialog(this, "无法更新往返点路径", "错误", JOptionPane.ERROR_MESSAGE); |
| | | return; |
| | | } |
| | | String message = "-1".equals(normalized) ? "往返点路径已清空" : "往返点路径已更新"; |
| | | JOptionPane.showMessageDialog(this, message, "成功", JOptionPane.INFORMATION_MESSAGE); |
| | | } |
| | | |
| | | /** |
| | |
| | | return new ArrayList<>(names); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |