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 zhuye.buttonset;
|
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("<html><div style='text-align: left;'>返回点坐标为割草机完成任务后返回的位置。</div></html>");
|
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 = buttonset.createStyledButton("取消", new Color(250, 250, 250));
|
cancelBtn.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
|
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));
|
|
JButton okBtn = buttonset.createStyledButton("确定", new Color(70, 130, 220));
|
okBtn.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
|
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;
|
}
|
}
|
}
|