From 1cf1ecbc75c6d14b40efb3161e7db0b8b64f7de2 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期三, 17 十二月 2025 12:05:27 +0800
Subject: [PATCH] 新增有障碍物的路径规划算法和优化没有障碍物的路径算法
---
src/dikuai/Dikuaiguanli.java | 462 ++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 275 insertions(+), 187 deletions(-)
diff --git a/src/dikuai/Dikuaiguanli.java b/src/dikuai/Dikuaiguanli.java
index 3d01450..5f0218e 100644
--- a/src/dikuai/Dikuaiguanli.java
+++ b/src/dikuai/Dikuaiguanli.java
@@ -6,6 +6,9 @@
import java.awt.datatransfer.*;
import java.awt.datatransfer.StringSelection;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import ui.UIConfig;
@@ -17,8 +20,11 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Objects;
+import java.util.Properties;
import lujing.Lunjingguihua;
+import lujing.MowingPathGenerationPage;
import zhangaiwu.AddDikuai;
import zhangaiwu.Obstacledge;
import zhuye.MapRenderer;
@@ -58,6 +64,8 @@
private JButton addLandBtn;
private static String currentWorkLandNumber;
+ private static final String WORK_LAND_KEY = "currentWorkLandNumber";
+ private static final String PROPERTIES_FILE = "set.properties";
private static final Map<String, Boolean> boundaryPointVisibility = new HashMap<>();
private ImageIcon workSelectedIcon;
private ImageIcon workUnselectedIcon;
@@ -327,8 +335,8 @@
JButton deleteBtn = createDeleteButton();
deleteBtn.addActionListener(e -> deleteDikuai(dikuai));
- JButton generatePathBtn = createPrimaryFooterButton("鐢熸垚鍓茶崏璺緞");
- generatePathBtn.addActionListener(e -> generateMowingPath(dikuai));
+ JButton generatePathBtn = createPrimaryFooterButton("璺緞瑙勫垝");
+ generatePathBtn.addActionListener(e -> showPathPlanningPage(dikuai));
JPanel footerPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
footerPanel.setBackground(CARD_BACKGROUND);
@@ -504,6 +512,7 @@
boolean isCurrent = currentWorkLandNumber != null && currentWorkLandNumber.equals(landNumber);
if (isCurrent) {
renderer.setBoundaryPointsVisible(desiredState);
+ renderer.setBoundaryPointSizeScale(desiredState ? 0.5d : 1.0d);
}
}
}
@@ -583,17 +592,69 @@
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(360, 240));
- int option = JOptionPane.showConfirmDialog(
- this,
- scrollPane,
- title,
- JOptionPane.OK_CANCEL_OPTION,
- JOptionPane.PLAIN_MESSAGE);
-
- if (option == JOptionPane.OK_OPTION) {
- return textArea.getText();
+ Window owner = SwingUtilities.getWindowAncestor(this);
+ JDialog dialog;
+ if (owner instanceof Frame) {
+ dialog = new JDialog((Frame) owner, title, true);
+ } else if (owner instanceof Dialog) {
+ dialog = new JDialog((Dialog) owner, title, true);
+ } else {
+ dialog = new JDialog((Frame) null, title, true);
}
- return null;
+ dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+
+ JPanel contentPanel = new JPanel(new BorderLayout());
+ contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ 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("澶嶅埗");
+
+ final boolean[] confirmed = new boolean[] {false};
+ final String[] resultHolder = new String[1];
+
+ okButton.addActionListener(e -> {
+ 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);
+
+ contentPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.setContentPane(contentPanel);
+ dialog.getRootPane().setDefaultButton(okButton);
+ dialog.pack();
+ dialog.setLocationRelativeTo(this);
+ dialog.setVisible(true);
+
+ return confirmed[0] ? resultHolder[0] : null;
}
private boolean saveFieldAndRefresh(Dikuai dikuai, String fieldName, String value) {
@@ -733,10 +794,26 @@
switch (trimmed) {
case "1":
case "spiral":
+ case "铻烘棆":
+ case "铻烘棆妯″紡":
return "spiral";
case "0":
case "parallel":
+ case "骞宠":
+ case "骞宠妯″紡":
default:
+ if (trimmed.contains("铻烘棆")) {
+ return "spiral";
+ }
+ if (trimmed.contains("spiral")) {
+ return "spiral";
+ }
+ if (trimmed.contains("parallel")) {
+ return "parallel";
+ }
+ if (trimmed.contains("骞宠")) {
+ return "parallel";
+ }
return "parallel";
}
}
@@ -752,6 +829,77 @@
return trimmed;
}
+ /**
+ * 鏄剧ず璺緞瑙勫垝椤甸潰
+ */
+ private void showPathPlanningPage(Dikuai dikuai) {
+ if (dikuai == null) {
+ return;
+ }
+
+ Window owner = SwingUtilities.getWindowAncestor(this);
+
+ // 鑾峰彇鍦板潡鍩烘湰鏁版嵁
+ String baseStationValue = prepareCoordinateForEditor(dikuai.getBaseStationCoordinates());
+ String boundaryValue = prepareCoordinateForEditor(dikuai.getBoundaryCoordinates());
+ List<Obstacledge.Obstacle> configuredObstacles = getConfiguredObstacles(dikuai);
+ String obstacleValue = determineInitialObstacleValue(dikuai, configuredObstacles);
+ String widthValue = sanitizeWidthString(dikuai.getMowingWidth());
+ if (widthValue != null) {
+ try {
+ double widthCm = Double.parseDouble(widthValue);
+ widthValue = formatWidthForStorage(widthCm);
+ } catch (NumberFormatException ignored) {
+ // 淇濇寔鍘熷瀛楃涓诧紝绋嶅悗鏍¢獙鎻愮ず
+ }
+ }
+ String modeValue = sanitizeValueOrNull(dikuai.getMowingPattern());
+ String existingPath = prepareCoordinateForEditor(dikuai.getPlannedPath());
+
+ // 鍒涘缓淇濆瓨鍥炶皟鎺ュ彛瀹炵幇
+ MowingPathGenerationPage.PathSaveCallback callback = new MowingPathGenerationPage.PathSaveCallback() {
+ @Override
+ public boolean saveBaseStationCoordinates(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "baseStationCoordinates", value);
+ }
+
+ @Override
+ public boolean saveBoundaryCoordinates(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "boundaryCoordinates", value);
+ }
+
+ @Override
+ public boolean saveObstacleCoordinates(Dikuai dikuai, String baseStationValue, String obstacleValue) {
+ return persistObstaclesForLand(dikuai, baseStationValue, obstacleValue);
+ }
+
+ @Override
+ public boolean saveMowingWidth(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "mowingWidth", value);
+ }
+
+ @Override
+ public boolean savePlannedPath(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "plannedPath", value);
+ }
+ };
+
+ // 鏄剧ず璺緞瑙勫垝椤甸潰
+ MowingPathGenerationPage dialog = new MowingPathGenerationPage(
+ owner,
+ dikuai,
+ baseStationValue,
+ boundaryValue,
+ obstacleValue,
+ widthValue,
+ modeValue,
+ existingPath,
+ callback
+ );
+
+ dialog.setVisible(true);
+ }
+
private void generateMowingPath(Dikuai dikuai) {
if (dikuai == null) {
return;
@@ -790,178 +938,48 @@
String modeValue,
String initialGeneratedPath) {
Window owner = SwingUtilities.getWindowAncestor(this);
- JDialog dialog = new JDialog(owner, "鐢熸垚鍓茶崏璺緞", Dialog.ModalityType.APPLICATION_MODAL);
- dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- dialog.getContentPane().setLayout(new BorderLayout());
- dialog.getContentPane().setBackground(BACKGROUND_COLOR);
-
- JPanel contentPanel = new JPanel();
- contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
- contentPanel.setBackground(BACKGROUND_COLOR);
- contentPanel.setBorder(BorderFactory.createEmptyBorder(12, 16, 12, 16));
-
- String landName = getDisplayValue(dikuai.getLandName(), "鏈煡鍦板潡");
- String landNumber = getDisplayValue(dikuai.getLandNumber(), "鏈煡缂栧彿");
- JLabel headerLabel = new JLabel(landName + " / " + landNumber);
- headerLabel.setFont(new Font("寰蒋闆呴粦", Font.BOLD, 16));
- headerLabel.setForeground(TEXT_COLOR);
- headerLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
- contentPanel.add(headerLabel);
- contentPanel.add(Box.createVerticalStrut(12));
-
- JTextField baseStationField = createInfoTextField(baseStationValue != null ? baseStationValue : "", true);
- contentPanel.add(createTextFieldSection("鍩虹珯鍧愭爣", baseStationField));
-
- JTextArea boundaryArea = createInfoTextArea(boundaryValue != null ? boundaryValue : "", true, 6);
- contentPanel.add(createTextAreaSection("鍦板潡杈圭晫", boundaryArea));
-
- JTextArea obstacleArea = createInfoTextArea(obstacleValue != null ? obstacleValue : "", true, 6);
- contentPanel.add(createTextAreaSection("闅滅鐗╁潗鏍�", obstacleArea));
-
- JTextField widthField = createInfoTextField(widthValue != null ? widthValue : "", true);
- contentPanel.add(createTextFieldSection("鍓茶崏瀹藉害 (鍘樼背)", widthField));
- contentPanel.add(createInfoValueSection("鍓茶崏妯″紡", formatMowingPatternForDialog(modeValue)));
-
- String existingPath = prepareCoordinateForEditor(dikuai.getPlannedPath());
- String pathSeed = initialGeneratedPath != null ? initialGeneratedPath : existingPath;
- JTextArea pathArea = createInfoTextArea(pathSeed != null ? pathSeed : "", true, 10);
- contentPanel.add(createTextAreaSection("鍓茶崏璺緞鍧愭爣", pathArea));
-
- JScrollPane dialogScrollPane = new JScrollPane(contentPanel);
- dialogScrollPane.setBorder(BorderFactory.createEmptyBorder());
- dialogScrollPane.getVerticalScrollBar().setUnitIncrement(16);
- dialog.add(dialogScrollPane, BorderLayout.CENTER);
-
- JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 12, 12));
- buttonPanel.setBackground(BACKGROUND_COLOR);
-
- JButton generateBtn = createPrimaryFooterButton("鐢熸垚鍓茶崏璺緞");
- JButton saveBtn = createPrimaryFooterButton("淇濆瓨璺緞");
- JButton cancelBtn = createPrimaryFooterButton("鍙栨秷");
-
- generateBtn.addActionListener(e -> {
- String sanitizedWidth = sanitizeWidthString(widthField.getText());
- if (sanitizedWidth != null) {
- try {
- double widthCm = Double.parseDouble(sanitizedWidth);
- widthField.setText(formatWidthForStorage(widthCm));
- sanitizedWidth = formatWidthForStorage(widthCm);
- } catch (NumberFormatException ex) {
- widthField.setText(sanitizedWidth);
- }
+
+ // 鍒涘缓淇濆瓨鍥炶皟鎺ュ彛瀹炵幇
+ MowingPathGenerationPage.PathSaveCallback callback = new MowingPathGenerationPage.PathSaveCallback() {
+ @Override
+ public boolean saveBaseStationCoordinates(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "baseStationCoordinates", value);
}
- String generated = attemptMowingPathPreview(
- boundaryArea.getText(),
- obstacleArea.getText(),
- sanitizedWidth,
- modeValue,
- dialog,
- true
- );
- if (generated != null) {
- pathArea.setText(generated);
- pathArea.setCaretPosition(0);
+
+ @Override
+ public boolean saveBoundaryCoordinates(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "boundaryCoordinates", value);
}
- });
-
- saveBtn.addActionListener(e -> {
- String baseStationNormalized = normalizeCoordinateInput(baseStationField.getText());
- String boundaryNormalized = normalizeCoordinateInput(boundaryArea.getText());
- if (!"-1".equals(boundaryNormalized)) {
- boundaryNormalized = boundaryNormalized
- .replace("\r\n", ";")
- .replace('\r', ';')
- .replace('\n', ';')
- .replaceAll(";+", ";")
- .replaceAll("\\s*;\\s*", ";")
- .trim();
- if (boundaryNormalized.isEmpty()) {
- boundaryNormalized = "-1";
- }
+
+ @Override
+ public boolean saveObstacleCoordinates(Dikuai dikuai, String baseStationValue, String obstacleValue) {
+ return persistObstaclesForLand(dikuai, baseStationValue, obstacleValue);
}
- String obstacleNormalized = normalizeCoordinateInput(obstacleArea.getText());
- if (!"-1".equals(obstacleNormalized)) {
- obstacleNormalized = obstacleNormalized
- .replace("\r\n", " ")
- .replace('\r', ' ')
- .replace('\n', ' ')
- .replaceAll("\\s{2,}", " ")
- .trim();
- if (obstacleNormalized.isEmpty()) {
- obstacleNormalized = "-1";
- }
+
+ @Override
+ public boolean saveMowingWidth(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "mowingWidth", value);
}
- String rawWidthInput = widthField.getText() != null ? widthField.getText().trim() : "";
- String widthSanitized = sanitizeWidthString(widthField.getText());
- if (widthSanitized == null) {
- String message = rawWidthInput.isEmpty() ? "璇峰厛璁剧疆鍓茶崏瀹藉害(鍘樼背)" : "鍓茶崏瀹藉害鏍煎紡涓嶆纭�";
- JOptionPane.showMessageDialog(dialog, message, "鎻愮ず", JOptionPane.WARNING_MESSAGE);
- return;
+
+ @Override
+ public boolean savePlannedPath(Dikuai dikuai, String value) {
+ return saveFieldAndRefresh(dikuai, "plannedPath", value);
}
- double widthCm;
- try {
- widthCm = Double.parseDouble(widthSanitized);
- } catch (NumberFormatException ex) {
- JOptionPane.showMessageDialog(dialog, "鍓茶崏瀹藉害鏍煎紡涓嶆纭�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
- return;
- }
- if (widthCm <= 0) {
- JOptionPane.showMessageDialog(dialog, "鍓茶崏瀹藉害蹇呴』澶т簬0", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
- return;
- }
- String widthNormalized = formatWidthForStorage(widthCm);
- widthField.setText(widthNormalized);
- String pathNormalized = normalizeCoordinateInput(pathArea.getText());
- if (!"-1".equals(pathNormalized)) {
- pathNormalized = pathNormalized
- .replace("\r\n", ";")
- .replace('\r', ';')
- .replace('\n', ';')
- .replaceAll(";+", ";")
- .replaceAll("\\s*;\\s*", ";")
- .trim();
- if (pathNormalized.isEmpty()) {
- pathNormalized = "-1";
- }
- }
- if ("-1".equals(pathNormalized)) {
- JOptionPane.showMessageDialog(dialog, "璇峰厛鐢熸垚鍓茶崏璺緞", "鎻愮ず", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
- if (!saveFieldAndRefresh(dikuai, "baseStationCoordinates", baseStationNormalized)) {
- JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍩虹珯鍧愭爣", "閿欒", JOptionPane.ERROR_MESSAGE);
- return;
- }
- if (!saveFieldAndRefresh(dikuai, "boundaryCoordinates", boundaryNormalized)) {
- JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍦板潡杈圭晫", "閿欒", JOptionPane.ERROR_MESSAGE);
- return;
- }
- if (!persistObstaclesForLand(dikuai, baseStationNormalized, obstacleNormalized)) {
- JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨闅滅鐗╁潗鏍�", "閿欒", JOptionPane.ERROR_MESSAGE);
- return;
- }
- if (!saveFieldAndRefresh(dikuai, "mowingWidth", widthNormalized)) {
- JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍓茶崏瀹藉害", "閿欒", JOptionPane.ERROR_MESSAGE);
- return;
- }
- if (!saveFieldAndRefresh(dikuai, "plannedPath", pathNormalized)) {
- JOptionPane.showMessageDialog(dialog, "鏃犳硶淇濆瓨鍓茶崏璺緞", "閿欒", JOptionPane.ERROR_MESSAGE);
- return;
- }
- JOptionPane.showMessageDialog(dialog, "鍓茶崏璺緞宸蹭繚瀛�", "鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
- dialog.dispose();
- });
-
- cancelBtn.addActionListener(e -> dialog.dispose());
-
- buttonPanel.add(generateBtn);
- buttonPanel.add(saveBtn);
- buttonPanel.add(cancelBtn);
- dialog.add(buttonPanel, BorderLayout.SOUTH);
-
- dialog.pack();
- dialog.setSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
- dialog.setLocationRelativeTo(owner);
+ };
+
+ // 浣跨敤鏂扮殑鐙珛椤甸潰绫�
+ MowingPathGenerationPage dialog = new MowingPathGenerationPage(
+ owner,
+ dikuai,
+ baseStationValue,
+ boundaryValue,
+ obstacleValue,
+ widthValue,
+ modeValue,
+ initialGeneratedPath,
+ callback
+ );
+
dialog.setVisible(true);
}
@@ -1446,10 +1464,19 @@
}
public static void setCurrentWorkLand(String landNumber, String landName) {
- currentWorkLandNumber = landNumber;
+ String sanitizedLandNumber = sanitizeLandNumber(landNumber);
+ boolean changed = !Objects.equals(currentWorkLandNumber, sanitizedLandNumber);
+ if (!changed) {
+ String persisted = readPersistedWorkLandNumber();
+ if (!Objects.equals(persisted, sanitizedLandNumber)) {
+ changed = true;
+ }
+ }
+ currentWorkLandNumber = sanitizedLandNumber;
+
Dikuai dikuai = null;
- if (landNumber != null) {
- dikuai = Dikuai.getDikuai(landNumber);
+ if (sanitizedLandNumber != null) {
+ dikuai = Dikuai.getDikuai(sanitizedLandNumber);
if (dikuai != null && (landName == null || "-1".equals(landName) || landName.trim().isEmpty())) {
landName = dikuai.getLandName();
}
@@ -1460,7 +1487,7 @@
Shouye shouye = Shouye.getInstance();
if (shouye != null) {
- if (landNumber == null) {
+ if (sanitizedLandNumber == null) {
shouye.updateCurrentAreaName(null);
} else {
shouye.updateCurrentAreaName(landName);
@@ -1470,24 +1497,85 @@
renderer.applyLandMetadata(dikuai);
String boundary = (dikuai != null) ? dikuai.getBoundaryCoordinates() : null;
String plannedPath = (dikuai != null) ? dikuai.getPlannedPath() : null;
- List<Obstacledge.Obstacle> configuredObstacles = (landNumber != null) ? loadObstaclesFromConfig(landNumber) : Collections.emptyList();
+ List<Obstacledge.Obstacle> configuredObstacles = (sanitizedLandNumber != null) ? loadObstaclesFromConfig(sanitizedLandNumber) : Collections.emptyList();
if (configuredObstacles == null) {
configuredObstacles = Collections.emptyList();
}
- renderer.setCurrentBoundary(boundary, landNumber, landNumber == null ? null : landName);
+ renderer.setCurrentBoundary(boundary, sanitizedLandNumber, sanitizedLandNumber == null ? null : landName);
renderer.setCurrentPlannedPath(plannedPath);
- renderer.setCurrentObstacles(configuredObstacles, landNumber);
- boolean showBoundaryPoints = landNumber != null && boundaryPointVisibility.getOrDefault(landNumber, false);
+ renderer.setCurrentObstacles(configuredObstacles, sanitizedLandNumber);
+ boolean showBoundaryPoints = sanitizedLandNumber != null && boundaryPointVisibility.getOrDefault(sanitizedLandNumber, false);
renderer.setBoundaryPointsVisible(showBoundaryPoints);
+ renderer.setBoundaryPointSizeScale(showBoundaryPoints ? 0.5d : 1.0d);
}
shouye.refreshMowingIndicators();
}
+
+ if (changed) {
+ persistCurrentWorkLand(sanitizedLandNumber);
+ }
}
public static String getCurrentWorkLandNumber() {
return currentWorkLandNumber;
}
+ public static String getPersistedWorkLandNumber() {
+ return readPersistedWorkLandNumber();
+ }
+
+ private static String sanitizeLandNumber(String landNumber) {
+ if (landNumber == null) {
+ return null;
+ }
+ String trimmed = landNumber.trim();
+ if (trimmed.isEmpty() || "-1".equals(trimmed)) {
+ return null;
+ }
+ return trimmed;
+ }
+
+ private static void persistCurrentWorkLand(String landNumber) {
+ synchronized (Dikuaiguanli.class) {
+ Properties props = new Properties();
+ try (FileInputStream in = new FileInputStream(PROPERTIES_FILE)) {
+ props.load(in);
+ } catch (IOException ignored) {
+ // Use empty defaults when the configuration file is missing.
+ }
+
+ if (landNumber == null) {
+ props.setProperty(WORK_LAND_KEY, "-1");
+ } else {
+ props.setProperty(WORK_LAND_KEY, landNumber);
+ }
+
+ try (FileOutputStream out = new FileOutputStream(PROPERTIES_FILE)) {
+ props.store(out, "Current work land selection updated");
+ } catch (IOException ex) {
+ System.err.println("鏃犳硶淇濆瓨褰撳墠浣滀笟鍦板潡: " + ex.getMessage());
+ }
+ }
+ }
+
+ private static String readPersistedWorkLandNumber() {
+ Properties props = new Properties();
+ try (FileInputStream in = new FileInputStream(PROPERTIES_FILE)) {
+ props.load(in);
+ String value = props.getProperty(WORK_LAND_KEY);
+ if (value == null) {
+ return null;
+ }
+ String trimmed = value.trim();
+ if (trimmed.isEmpty() || "-1".equals(trimmed)) {
+ return null;
+ }
+ return trimmed;
+ } catch (IOException ex) {
+ return null;
+ }
+ }
+
private ImageIcon loadIcon(String path, int width, int height) {
try {
ImageIcon rawIcon = new ImageIcon(path);
--
Gitblit v1.10.0