package dell_system; // ¶¨Òå°üÃûΪdell_system
|
|
import javax.swing.*; // µ¼ÈëSwing GUI×é¼þ
|
import javax.swing.table.DefaultTableModel; // µ¼Èë±í¸ñÄ£ÐÍ
|
|
import publicsWay.CoordinateTranslator;
|
import publicsWay.XyToLatLngConverter;
|
|
import java.awt.*; // µ¼ÈëAWTͼÐÎ×é¼þ
|
import java.util.Locale;
|
import java.util.ResourceBundle; // µ¼Èë×ÊÔ´ÊøÓÃÓÚ¹ú¼Ê»¯
|
|
public class QuickCalculationPanel extends JPanel { // ¶¨Òå¿ìËÙ¼ÆËãÃæ°åÀà
|
private static final long serialVersionUID = 1L; // ÐòÁл¯°æ±¾ID
|
private ResourceBundle messages; // ¹ú¼Ê»¯ÏûÏ¢×ÊÔ´Êø
|
private JTextField pointATextField; // µãAÊäÈë¿ò
|
private JTextField pointBTextField; // µãBÊäÈë¿ò
|
private JTextField xyToLonLatTextField; // XYת¾Î³¶ÈÊäÈë¿ò
|
private JTextField lonLatToXYTextField; // ¾Î³¶ÈתXYÊäÈë¿ò
|
private JTextField point1RawTextField; // Ôʼµã1ÊäÈë¿ò
|
private JTextField point2RawTextField; // Ôʼµã2ÊäÈë¿ò
|
private JTextField distanceResultTextField; // ¾àÀë¼ÆËã½á¹û¿ò
|
private JTable nmeaTable; // NMEAÊý¾ÝÏÔʾ±í¸ñ
|
private DefaultTableModel tableModel; // ±í¸ñÊý¾ÝÄ£ÐÍ
|
private JTextField result1TextField; // ת»»½á¹û1ÏÔʾ¿ò
|
private JTextField result2TextField; // ת»»½á¹û2ÏÔʾ¿ò
|
|
// ¹¹Ô캯Êý
|
public QuickCalculationPanel(ResourceBundle messages) {
|
this.messages = messages; // ³õʼ»¯ÏûÏ¢×ÊÔ´
|
setLayout(new BorderLayout()); // ÉèÖñ߽粼¾Ö
|
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // ÉèÖÃÃæ°å±ß¾à
|
initUI(); // ³õʼ»¯Óû§½çÃæ
|
}
|
|
// ³õʼ»¯Óû§½çÃæ
|
private void initUI() {
|
JPanel mainPanel = new JPanel(null); // ´´½¨Ö÷Ãæ°å£¨¾ø¶Ô²¼¾Ö£©
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // ÉèÖÃÖ÷Ãæ°å±ß¾à
|
|
// ³õÊ¼×ø±êºÍ³ß´ç²ÎÊý
|
int x = 10; // ³õʼX×ø±ê
|
int y = 10; // ³õʼY×ø±ê
|
int panelWidth = 760; // Ãæ°å¿í¶È
|
int height = 25; // ×é¼þ¸ß¶È
|
int spacing = 35; // ´¹Ö±¼ä¾à
|
|
// === µãÊäÈëÇøÓò ===
|
JLabel pointInputLabel = new JLabel(messages.getString("POINT_INPUT_SECTION") + ":");
|
pointInputLabel.setBounds(x, y, panelWidth, height); // ÉèÖñêǩλÖÃ
|
mainPanel.add(pointInputLabel); // Ìí¼Ó±êÇ©µ½Ãæ°å
|
y += spacing; // ÏÂÒÆÒ»ÐÐ
|
|
// µãAÊäÈë
|
JLabel pointALabel = new JLabel(messages.getString("POINT_A") + ":");
|
pointALabel.setBounds(x, y, 200, height);
|
pointATextField = new JTextField(); // ´´½¨µãAÊäÈë¿ò
|
pointATextField.setBounds(x + 180, y, 400, height);
|
pointATextField.setToolTipText(messages.getString("POINT_A1")); // ÉèÖÃÌáʾÎı¾
|
mainPanel.add(pointALabel);
|
mainPanel.add(pointATextField);
|
y += spacing; // ÏÂÒÆÒ»ÐÐ
|
|
// µãBÊäÈë
|
JLabel pointBLabel = new JLabel(messages.getString("POINT_B") + ":");
|
pointBLabel.setBounds(x, y, 200, height);
|
pointBTextField = new JTextField(); // ´´½¨µãBÊäÈë¿ò
|
pointBTextField.setBounds(x + 180, y, 400, height);
|
pointBTextField.setToolTipText(messages.getString("POINT_B1")); // ÉèÖÃÌáʾÎı¾
|
mainPanel.add(pointBLabel);
|
mainPanel.add(pointBTextField);
|
y += spacing + 20; // ÏÂÒÆ²¢Ôö¼Ó¶îÍâ¼ä¾à
|
|
// === ×ø±êת»»ÇøÓò ===
|
JLabel coordConvLabel = new JLabel(messages.getString("COORDINATE_CONVERSION") + ":");
|
coordConvLabel.setBounds(x, y, panelWidth, height);
|
mainPanel.add(coordConvLabel);
|
y += spacing;
|
|
// XYת¾Î³¶È
|
JLabel xyToLonLatLabel = new JLabel(messages.getString("XY_TO_LONLAT") + ":");
|
xyToLonLatLabel.setBounds(x, y, 200, height);
|
xyToLonLatTextField = new JTextField(); // ´´½¨ÊäÈë¿ò
|
xyToLonLatTextField.setBounds(x + 180, y, 400, height);
|
xyToLonLatTextField.setToolTipText(messages.getString("XY_TO_LONLAT1")); // ÉèÖÃÌáʾÎı¾
|
JButton convertXYButton = new JButton(messages.getString("CONVERT")); // ת»»°´Å¥
|
convertXYButton.setBounds(x + 600, y, 100, height);
|
convertXYButton.addActionListener(e -> convertXYToLonLat()); // Ìí¼Óµã»÷ʼþ
|
mainPanel.add(xyToLonLatLabel);
|
mainPanel.add(xyToLonLatTextField);
|
mainPanel.add(convertXYButton);
|
y += spacing;
|
|
// ת»»½á¹û1
|
JLabel result1Label = new JLabel(messages.getString("RESULT") + ":");
|
result1Label.setBounds(x, y, 200, height);
|
result1TextField = new JTextField(); // ´´½¨½á¹û¿ò
|
result1TextField.setEditable(false); // ÉèÖÃΪֻ¶Á
|
result1TextField.setBounds(x + 180, y, 400, height);
|
mainPanel.add(result1Label);
|
mainPanel.add(result1TextField);
|
y += spacing;
|
|
// ¾Î³¶ÈתXY
|
JLabel lonLatToXYLabel = new JLabel(messages.getString("LONLAT_TO_XY") + ":");
|
lonLatToXYLabel.setBounds(x, y, 200, height);
|
lonLatToXYTextField = new JTextField(); // ´´½¨ÊäÈë¿ò
|
lonLatToXYTextField.setBounds(x + 180, y, 400, height);
|
lonLatToXYTextField.setToolTipText(messages.getString("LONLAT_TO_XY1")); // ÉèÖÃÌáʾÎı¾
|
JButton convertLonLatButton = new JButton(messages.getString("CONVERT")); // ת»»°´Å¥
|
convertLonLatButton.setBounds(x + 600, y, 100, height);
|
convertLonLatButton.addActionListener(e -> convertLonLatToXY()); // Ìí¼Óµã»÷ʼþ
|
mainPanel.add(lonLatToXYLabel);
|
mainPanel.add(lonLatToXYTextField);
|
mainPanel.add(convertLonLatButton);
|
y += spacing;
|
|
// ת»»½á¹û2
|
JLabel result2Label = new JLabel(messages.getString("RESULT") + ":");
|
result2Label.setBounds(x, y, 100, height);
|
result2TextField = new JTextField(); // ´´½¨½á¹û¿ò
|
result2TextField.setEditable(false); // ÉèÖÃΪֻ¶Á
|
result2TextField.setBounds(x + 180, y, 400, height);
|
mainPanel.add(result2Label);
|
mainPanel.add(result2TextField);
|
y += spacing + 20; // ÏÂÒÆ²¢Ôö¼Ó¶îÍâ¼ä¾à
|
|
// === ¾àÀë¼ÆËãÇøÓò ===
|
JLabel distCalcLabel = new JLabel(messages.getString("DISTANCE_CALCULATION") + ":");
|
distCalcLabel.setBounds(x, y, panelWidth, height);
|
mainPanel.add(distCalcLabel);
|
y += spacing;
|
|
// Ôʼµã1ÊäÈë
|
JLabel point1Label = new JLabel(messages.getString("POINT1_RAW") + ":");
|
point1Label.setBounds(x, y, 200, height);
|
point1RawTextField = new JTextField(); // ´´½¨ÊäÈë¿ò
|
point1RawTextField.setBounds(x + 180, y, 800, height);
|
mainPanel.add(point1Label);
|
mainPanel.add(point1RawTextField);
|
y += spacing;
|
|
// Ôʼµã2ÊäÈë
|
JLabel point2Label = new JLabel(messages.getString("POINT2_RAW") + ":");
|
point2Label.setBounds(x, y, 200, height);
|
point2RawTextField = new JTextField(); // ´´½¨ÊäÈë¿ò
|
point2RawTextField.setBounds(x + 180, y, 800, height);
|
mainPanel.add(point2Label);
|
mainPanel.add(point2RawTextField);
|
y += spacing;
|
|
// ¼ÆËã°´Å¥ºÍ½á¹û
|
JButton calculateButton = new JButton(messages.getString("CALCULATE_DISTANCE")); // ¼ÆËã°´Å¥
|
calculateButton.setBounds(x, y, 100, height);
|
calculateButton.addActionListener(e -> calculateDistance()); // Ìí¼Óµã»÷ʼþ
|
distanceResultTextField = new JTextField(); // ´´½¨½á¹û¿ò
|
distanceResultTextField.setEditable(false); // ÉèÖÃΪֻ¶Á
|
distanceResultTextField.setBounds(x + 180, y, 400, height);
|
mainPanel.add(calculateButton);
|
mainPanel.add(distanceResultTextField);
|
y += spacing + 20; // ÏÂÒÆ²¢Ôö¼Ó¶îÍâ¼ä¾à
|
|
// === NMEA±í¸ñÇøÓò ===
|
JLabel nmeaTableLabel = new JLabel(messages.getString("NMEA_DATA_TABLE") + ":");
|
nmeaTableLabel.setBounds(x, y, panelWidth, height);
|
mainPanel.add(nmeaTableLabel);
|
y += spacing;
|
|
// ´´½¨±í¸ñÁбêÌâ
|
String[] columns = {
|
messages.getString("FIELD_NAME"), // ×Ö¶ÎÃû
|
messages.getString("POINT1"), // µã1
|
messages.getString("POINT2") // µã2
|
};
|
|
// ¶¨Òå±í¸ñÐÐÃû³Æ
|
String[] rowNames = {
|
messages.getString("MSG_ID"),
|
messages.getString("UTC_TIME"),
|
messages.getString("LATITUDE"),
|
messages.getString("LAT_HEMISPHERE"),
|
messages.getString("LONGITUDE"),
|
messages.getString("LON_HEMISPHERE"),
|
messages.getString("QUALITY"),
|
messages.getString("NUM_SATELLITES"),
|
messages.getString("HDOP"),
|
messages.getString("ALTITUDE"),
|
messages.getString("ALTITUDE_UNIT"),
|
messages.getString("GEOID_HEIGHT"),
|
messages.getString("GEOID_HEIGHT_UNIT"),
|
messages.getString("DIFF_TIME"),
|
messages.getString("CHECKSUM"),
|
messages.getString("DEVICE_ID"),
|
messages.getString("DEVICE_POWER"),
|
messages.getString("SIGNAL_STRENGTH"),
|
messages.getString("RESERVED1"),
|
messages.getString("RESERVED2"),
|
messages.getString("RESERVED3")
|
};
|
|
// ³õʼ»¯±í¸ñÄ£ÐÍ
|
tableModel = new DefaultTableModel(columns, 0); // ´´½¨¿ÕÄ£ÐÍ
|
// Ìí¼ÓÐÐÊý¾Ý
|
for (String rowName : rowNames) {
|
tableModel.addRow(new Object[]{rowName, "", ""}); // Ìí¼Ó´ø¿ÕÖµµÄÐÐ
|
}
|
|
// ´´½¨±í¸ñ²¢½ûÓñà¼
|
nmeaTable = new JTable(tableModel);
|
nmeaTable.setEnabled(false); // ½ûÓñí¸ñ±à¼
|
JScrollPane scrollPane = new JScrollPane(nmeaTable); // Ìí¼Ó¹ö¶¯Ìõ
|
scrollPane.setBounds(x, y, panelWidth, 400); // ÉèÖùö¶¯Ãæ°åλÖÃ
|
mainPanel.add(scrollPane); // Ìí¼Óµ½Ö÷Ãæ°å
|
|
add(mainPanel, BorderLayout.CENTER); // ½«Ö÷Ãæ°åÌí¼Óµ½ÖÐÐÄÇøÓò
|
}
|
|
// XY×ø±êת¾Î³¶È
|
private void convertXYToLonLat() {
|
String xy = xyToLonLatTextField.getText().trim(); // »ñÈ¡ÊäÈëÎı¾
|
if (xy.isEmpty()) { // ÑéÖ¤·Ç¿Õ
|
JOptionPane.showMessageDialog(this, messages.getString("FIELD_REQUIRED"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
// »ñÈ¡AµãÊý¾Ý
|
String[] pointA = pointATextField.getText().split(",|£¬");
|
if (pointA.length < 4) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("INVALID_POINT_FORMAT2"), messages.getString("POINT_A")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
|
|
// »ñÈ¡BµãÊý¾Ý
|
String[] pointB = pointBTextField.getText().split(",|£¬");
|
if (pointB.length < 4) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("INVALID_POINT_FORMAT3"), messages.getString("POINT_B")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
try {
|
// ½âÎöÊäÈëÊý¾Ý
|
double latA = Double.parseDouble(pointA[1]);
|
double lonA = Double.parseDouble(pointA[0]);
|
double localXA = Double.parseDouble(pointA[2]);
|
double localYA = Double.parseDouble(pointA[3]);
|
|
double latB = Double.parseDouble(pointB[1]);
|
double lonB = Double.parseDouble(pointB[0]);
|
double localXB = Double.parseDouble(pointB[2]);
|
double localYB = Double.parseDouble(pointB[3]);
|
|
// ¼ì²é¾Î³¶ÈÊÇ·ñΪÁã
|
if (latA == 0 || lonA == 0 || latB == 0 || lonB == 0) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("ZERO_LATLON"), messages.getString("POINT_A") + "/" + messages.getString("POINT_B")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
String[] xyParts = xy.split(",|£¬");
|
if (xyParts.length < 2) {
|
JOptionPane.showMessageDialog(this, messages.getString("XY_TO_LONLAT12"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
String localX = xyParts[0];
|
String localY = xyParts[1];
|
|
|
|
// µ÷ÓÃת»»·½·¨
|
String[] result = XyToLatLngConverter.convertLocalToGlobalCoordinates(
|
localX, localY,
|
latA, lonA, latB, lonB,
|
localXA, localYA, localXB, localYB
|
);
|
|
// ÏÔʾת»»½á¹û£¨Ê®½øÖƾγ¶È£©
|
result1TextField.setText(result[3] + "," + result[2]);
|
|
} catch (NumberFormatException e) {
|
JOptionPane.showMessageDialog(this, messages.getString("INVALID_NUMBER"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
} catch (Exception e) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("SAVE_FENCE_ERROR"), e.getMessage()),
|
messages.getString("ERROR"), JOptionPane.ERROR_MESSAGE);
|
}
|
}
|
|
// ¾Î³¶ÈתXY×ø±ê
|
private void convertLonLatToXY() {
|
String lonlat = lonLatToXYTextField.getText().trim(); // »ñÈ¡ÊäÈëÎı¾
|
if (lonlat.isEmpty()) { // ÑéÖ¤·Ç¿Õ
|
JOptionPane.showMessageDialog(this, messages.getString("FIELD_REQUIRED"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
try {
|
// ½âÎöµ±Ç°µãµÄ¾Î³¶È
|
String[] lonLatParts = lonlat.split("[,£¬]");
|
if (lonLatParts.length < 2) {
|
JOptionPane.showMessageDialog(this, messages.getString("INVALID_LONLAT_FORMAT"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
String jd1 = lonLatParts[0].trim(); // µ±Ç°¾¶È
|
String wd1 = lonLatParts[1].trim(); // µ±Ç°Î³¶È
|
|
// ½âÎöAµãÊý¾Ý
|
String[] pointA = pointATextField.getText().split("[,£¬]");
|
if (pointA.length < 4) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("INVALID_POINT_FORMAT"), messages.getString("POINT_A")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
double latA = Double.parseDouble(pointA[1].trim());
|
double lonA = Double.parseDouble(pointA[0].trim());
|
double localXA = Double.parseDouble(pointA[2].trim());
|
double localYA = Double.parseDouble(pointA[3].trim());
|
|
// ½âÎöBµãÊý¾Ý
|
String[] pointB = pointBTextField.getText().split("[,£¬]");
|
if (pointB.length < 4) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("INVALID_POINT_FORMAT"), messages.getString("POINT_B")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
double latB = Double.parseDouble(pointB[1].trim());
|
double lonB = Double.parseDouble(pointB[0].trim());
|
double localXB = Double.parseDouble(pointB[2].trim());
|
double localYB = Double.parseDouble(pointB[3].trim());
|
|
// ¼ì²é¾Î³¶ÈÊÇ·ñΪÁã
|
if (latA == 0 || lonA == 0 || latB == 0 || lonB == 0) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("ZERO_LATLON"), messages.getString("POINT_A") + "/" + messages.getString("POINT_B")),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
// µ÷ÓÃת»»·½·¨
|
int[] xyResult = CoordinateTranslator.gps_xy(
|
new String[]{String.valueOf(lonA), String.valueOf(latA), String.valueOf(localXA), String.valueOf(localYA)},
|
new String[]{String.valueOf(lonB), String.valueOf(latB), String.valueOf(localXB), String.valueOf(localYB)},
|
jd1,
|
wd1
|
);
|
|
// ÏÔʾת»»½á¹û (X, Y)
|
result2TextField.setText(xyResult[1] + ", " + xyResult[0]); // [X, Y] ¸ñʽ
|
|
} catch (NumberFormatException e) {
|
JOptionPane.showMessageDialog(this, messages.getString("INVALID_NUMBER"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
} catch (Exception e) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("CONVERSION_ERROR"), e.getMessage()),
|
messages.getString("ERROR"), JOptionPane.ERROR_MESSAGE);
|
}
|
}
|
|
// ¼ÆËãÁ½µã¼ä¾àÀë
|
private void calculateDistance() {
|
String point1 = point1RawTextField.getText(); // »ñÈ¡µã1ÔʼÊý¾Ý
|
String point2 = point2RawTextField.getText(); // »ñÈ¡µã2ÔʼÊý¾Ý
|
|
if (point1.isEmpty() || point2.isEmpty()) { // ÑéÖ¤·Ç¿Õ
|
JOptionPane.showMessageDialog(this, messages.getString("FIELD_REQUIRED"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
parseNMEAData(point1, 1); // ½âÎöµã1Êý¾Ýµ½±í¸ñ
|
parseNMEAData(point2, 2); // ½âÎöµã2Êý¾Ýµ½±í¸ñ
|
|
try {
|
// ½âÎöNMEAÊý¾Ý»ñÈ¡¾Î³¶È
|
String[] fields1 = point1.split(",");
|
String[] fields2 = point2.split(",");
|
|
// È·±£ÓÐ×ã¹»×Ö¶Î (γ¶ÈÔÚË÷Òý2£¬¾¶ÈÔÚË÷Òý4)
|
if (fields1.length < 6 || fields2.length < 6) {
|
JOptionPane.showMessageDialog(this, messages.getString("INVALID_NMEA_FORMAT"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
// ÌáÈ¡µã1µÄ¾Î³¶È
|
double lat1 = Double.parseDouble(fields1[2]);
|
double lon1 = Double.parseDouble(fields1[4]);
|
|
// ÌáÈ¡µã2µÄ¾Î³¶È
|
double lat2 = Double.parseDouble(fields2[2]);
|
double lon2 = Double.parseDouble(fields2[4]);
|
|
// ʹÓÃCoordinateTranslator¼ÆËã¾àÀë (ÀåÃ×)
|
int distanceCm = CoordinateTranslator.distance2(lon1, lat1, lon2, lat2);
|
|
// ת»»ÎªÃײ¢±£ÁôÁ½Î»Ð¡Êý
|
double distanceMeters = distanceCm / 100.0;
|
String formattedDistance = String.format(Locale.US, "%.2f %s", distanceMeters, messages.getString("METERS"));
|
|
// ÏÔʾ¼ÆËã½á¹û
|
distanceResultTextField.setText(formattedDistance);
|
|
} catch (NumberFormatException e) {
|
JOptionPane.showMessageDialog(this, messages.getString("INVALID_NUMBER"),
|
messages.getString("VALIDATION_ERROR"), JOptionPane.ERROR_MESSAGE);
|
} catch (Exception e) {
|
JOptionPane.showMessageDialog(this,
|
String.format(messages.getString("CALCULATION_ERROR"), e.getMessage()),
|
messages.getString("ERROR"), JOptionPane.ERROR_MESSAGE);
|
}
|
}
|
|
// ½âÎöNMEAÊý¾Ýµ½±í¸ñ
|
private void parseNMEAData(String nmea, int pointIndex) {
|
String[] fields = nmea.split(","); // ·Ö¸îNMEA×Ö·û´®
|
int column = pointIndex; // È·¶¨±í¸ñÁÐ(1=µã1, 2=µã2)
|
|
// Ìî³ä±í¸ñÊý¾Ý
|
for (int i = 0; i < Math.min(fields.length, tableModel.getRowCount()); i++) {
|
tableModel.setValueAt(fields[i], i, column); // ÉèÖõ¥Ôª¸ñÖµ
|
}
|
}
|
}
|