package dikuai;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.util.Properties;
import zhuye.MowerLocationData;
import java.text.DecimalFormat;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
/**
* 返回点设置对话框 - 将当前车辆位置设置为地块返回点
*/
public class FanhuiDialog extends JDialog {
private static final long serialVersionUID = 1L;
private Dikuai dikuai;
private boolean updated = false;
public FanhuiDialog(Window parent, Dikuai dikuai) {
super(parent instanceof Frame ? (Frame) parent : null, "设置返回点", ModalityType.APPLICATION_MODAL);
this.dikuai = dikuai;
initialize();
}
private void initialize() {
// 适配 6.5 寸竖屏,宽窄高布局
setSize(360, 640);
setResizable(false);
setLocationRelativeTo(getOwner());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// 主面板
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
panel.setBackground(new Color(248, 248, 248));
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(8, 10, 8, 10);
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
// 标题
JLabel title = new JLabel("设置返回点");
title.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
title.setForeground(new Color(0, 100, 200));
c.gridx = 0; c.gridy = 0; c.gridwidth = 2; c.weighty = 0;
panel.add(title, c);
// 提示信息
JLabel hintLabel = new JLabel("
返回点坐标为割草机完成任务后返回的位置。
");
hintLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
hintLabel.setForeground(new Color(100, 100, 100));
hintLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
c.gridx = 0; c.gridy = 1; c.gridwidth = 2; c.insets = new Insets(5, 10, 15, 10);
panel.add(hintLabel, c);
// 分隔线
JSeparator separator = new JSeparator();
c.gridx = 0; c.gridy = 2; c.gridwidth = 2; c.insets = new Insets(5, 0, 15, 0);
panel.add(separator, c);
// 检测到的坐标
c.insets = new Insets(12, 10, 12, 10);
final String[] detectedHolder = new String[1];
try {
detectedHolder[0] = getCurrentVehicleCoordinates();
} catch (Throwable ignored) {
detectedHolder[0] = null;
}
JLabel detectedLabel = new JLabel("检测到坐标:");
detectedLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
detectedLabel.setForeground(Color.DARK_GRAY);
c.gridx = 0; c.gridy = 3; c.gridwidth = 2; c.weighty = 0;
panel.add(detectedLabel, c);
// 坐标显示区域
JTextArea coordArea = new JTextArea(detectedHolder[0] == null ? "未检测到车辆坐标" : detectedHolder[0]);
coordArea.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
coordArea.setForeground(detectedHolder[0] == null ? Color.GRAY : new Color(0, 120, 0));
coordArea.setEditable(false);
coordArea.setBackground(new Color(255, 255, 255));
coordArea.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(220, 220, 220)),
BorderFactory.createEmptyBorder(8, 8, 8, 8)
));
coordArea.setLineWrap(true);
coordArea.setWrapStyleWord(true);
c.gridx = 0; c.gridy = 4; c.gridwidth = 2; c.ipady = 50; c.weighty = 0;
panel.add(coordArea, c);
c.ipady = 0;
// 添加一个弹性空间,将按钮推到底部
c.gridx = 0; c.gridy = 5; c.gridwidth = 2; c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
panel.add(Box.createGlue(), c);
// 按钮面板
JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
btnPanel.setBackground(new Color(248, 248, 248));
btnPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
JButton cancelBtn = new JButton("取消");
JButton okBtn = new JButton("确定");
// 美化按钮
cancelBtn.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
cancelBtn.setPreferredSize(new Dimension(90, 35));
cancelBtn.setBackground(new Color(250, 250, 250));
cancelBtn.setForeground(new Color(80, 80, 80));
cancelBtn.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(200, 200, 200)),
BorderFactory.createEmptyBorder(5, 15, 5, 15)
));
cancelBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
okBtn.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
okBtn.setPreferredSize(new Dimension(90, 35));
okBtn.setBackground(new Color(70, 130, 220));
okBtn.setForeground(Color.WHITE);
okBtn.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(60, 120, 210)),
BorderFactory.createEmptyBorder(5, 15, 5, 15)
));
okBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
// 添加按钮悬停效果
cancelBtn.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
cancelBtn.setBackground(new Color(240, 240, 240));
}
public void mouseExited(java.awt.event.MouseEvent evt) {
cancelBtn.setBackground(new Color(250, 250, 250));
}
});
okBtn.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
okBtn.setBackground(new Color(80, 140, 230));
}
public void mouseExited(java.awt.event.MouseEvent evt) {
okBtn.setBackground(new Color(70, 130, 220));
}
});
btnPanel.add(cancelBtn);
btnPanel.add(okBtn);
c.gridx = 0; c.gridy = 6; c.gridwidth = 2; c.anchor = GridBagConstraints.NORTHEAST;
c.insets = new Insets(10, 10, 0, 10);
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(btnPanel, c);
// 按钮事件
okBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 仅使用检测到的实时坐标
if (detectedHolder[0] == null) {
JOptionPane.showMessageDialog(FanhuiDialog.this,
"未能获取到当前车辆坐标,无法设置返回点", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
String normalized = normalizeCoordinates(detectedHolder[0]);
if (normalized == null) {
JOptionPane.showMessageDialog(FanhuiDialog.this,
"检测到的坐标格式异常,无法保存", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
Dikuai.updateField(dikuai.getLandNumber(), "returnPointCoordinates", normalized);
Dikuai.updateField(dikuai.getLandNumber(), "updateTime",
new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
Dikuai.saveToProperties();
JOptionPane.showMessageDialog(FanhuiDialog.this, "返回点坐标已更新!", "成功", JOptionPane.INFORMATION_MESSAGE);
updated = true;
dispose();
}
});
// 取消按钮立即退出对话框
cancelBtn.addActionListener(e -> {
dispose();
});
setContentPane(panel);
setVisible(true);
}
/**
* 尝试读取当前车辆位置的简易实现
*/
private String getCurrentVehicleCoordinates() {
// 1) 优先尝试从内存中的 MowerLocationData 获取实时位置
try {
double latDm = MowerLocationData.getLatitude();
double lonDm = MowerLocationData.getLongitude();
String latHem = MowerLocationData.getLatitudeHemisphere();
String lonHem = MowerLocationData.getLongitudeHemisphere();
if ((latDm != 0.0 || lonDm != 0.0)) {
double lat = dmToDecimal(latDm);
double lon = dmToDecimal(lonDm);
if (latHem != null && latHem.equalsIgnoreCase("S")) lat = -Math.abs(lat);
if (lonHem != null && lonHem.equalsIgnoreCase("W")) lon = -Math.abs(lon);
DecimalFormat df = new DecimalFormat("0.######");
return df.format(lat) + "," + df.format(lon);
}
} catch (Throwable ignored) {}
// 2) 尝试从配置文件获取
try (FileInputStream fis = new FileInputStream("current_position.properties")) {
Properties p = new Properties();
p.load(fis);
String v = p.getProperty("currentPosition");
if (v != null && !v.trim().isEmpty()) return v.trim();
String lat = p.getProperty("latitude");
String lon = p.getProperty("longitude");
if (lat != null && lon != null) return lat.trim() + "," + lon.trim();
} catch (Exception ignored) {}
try (FileInputStream fis = new FileInputStream("device.properties")) {
Properties dp = new Properties();
dp.load(new java.io.InputStreamReader(fis, java.nio.charset.StandardCharsets.UTF_8));
String coords = dp.getProperty("mowerCoordinates");
if (coords != null && !coords.trim().isEmpty()) return coords.trim();
coords = dp.getProperty("mowerPosition");
if (coords != null && !coords.trim().isEmpty()) return coords.trim();
} catch (Exception ignored) {}
return null;
}
public boolean isUpdated() {
return updated;
}
/**
* 将度分格式转换为十进制度
*/
private static double dmToDecimal(double dm) {
double sign = dm < 0 ? -1.0 : 1.0;
double abs = Math.abs(dm);
int degrees = (int) (abs / 100);
double minutes = abs - (degrees * 100);
return sign * (degrees + minutes / 60.0);
}
/**
* 规范化坐标字符串
*/
private String normalizeCoordinates(String input) {
if (input == null) return null;
String s = input.trim();
if (s.isEmpty()) return null;
String[] parts = s.split("\\s*,\\s*");
if (parts.length != 2) return null;
try {
double lat = Double.parseDouble(parts[0]);
double lon = Double.parseDouble(parts[1]);
// 如果看起来像十进制度,直接格式化返回
if (Math.abs(lat) <= 90.0 && Math.abs(lon) <= 180.0) {
DecimalFormat df = new DecimalFormat("0.######");
return df.format(lat) + "," + df.format(lon);
}
// 否则尝试按度分格式转换
double latDec = dmToDecimal(lat);
double lonDec = dmToDecimal(lon);
DecimalFormat df = new DecimalFormat("0.######");
return df.format(latDec) + "," + df.format(lonDec);
} catch (NumberFormatException ex) {
return null;
}
}
}