| | |
| | | <attribute name="module" value="true"/> |
| | | </attributes> |
| | | </classpathentry> |
| | | <classpathentry kind="lib" path="lib/jSerialComm-2.10.4.jar"/> |
| | | <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jts-core-1.19.0.jar"/> |
| | | <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-api-1.7.30.jar"/> |
| | | <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-simple-1.7.30.jar"/> |
| | | <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/jSerialComm-2.10.4.jar"/> |
| | | <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/jts-core-1.19.0.jar"/> |
| | | <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/slf4j-api-1.7.30.jar"/> |
| | | <classpathentry kind="lib" path="D:/eclipseworkspace/GIT/GeCaoAPP/lib/slf4j-simple-1.7.30.jar"/> |
| | | <classpathentry kind="output" path="bin"/> |
| | | </classpath> |
| | |
| | | <natures> |
| | | <nature>org.eclipse.jdt.core.javanature</nature> |
| | | </natures> |
| | | <filteredResources> |
| | | <filter> |
| | | <id>1766205615208</id> |
| | | <name></name> |
| | | <type>30</type> |
| | | <matcher> |
| | | <id>org.eclipse.core.resources.regexFilterMatcher</id> |
| | | <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments> |
| | | </matcher> |
| | | </filter> |
| | | </filteredResources> |
| | | </projectDescription> |
| | |
| | | #Dikuai Properties |
| | | #Fri Dec 19 19:44:17 CST 2025 |
| | | LAND1.angleThreshold=-1 |
| | | #Sat Dec 20 14:47:09 GMT+08:00 2025 |
| | | LAND2.boundaryCoordinates=5.38,-6.41;-11.15,-8.94;-12.75,-4.68;-12.23,-3.28;-11.12,-3.17;-9.29,-3.53;-7.46,-3.89;-5.62,-4.25;-3.79,-4.61;-1.96,-4.97;-0.12,-5.33;1.71,-5.69;3.54,-6.05;5.38,-6.41 |
| | | LAND1.intelligentSceneAnalysis=-1 |
| | | LAND1.mowingSafetyDistance=-1 |
| | | LAND1.landArea=26.75 |
| | | LAND1.returnPointCoordinates=-1 |
| | | LAND1.landNumber=LAND1 |
| | | LAND2.landName=1452 |
| | | LAND2.userId=-1 |
| | | LAND2.intelligentSceneAnalysis=-1 |
| | | LAND2.mowingOverlapDistance=0.06 |
| | | LAND2.landArea=55.11 |
| | | LAND1.returnPathCoordinates=-1 |
| | | LAND1.mowingPattern=å¹³è¡çº¿ |
| | | LAND1.mowingOverlapDistance=0.06 |
| | | LAND2.updateTime=2025-12-20 14\:47\:09 |
| | | LAND2.createTime=2025-12-20 12\:24\:28 |
| | | LAND1.mowingWidth=34 |
| | | LAND2.returnPathCoordinates=-1 |
| | | LAND2.angleThreshold=-1 |
| | | LAND2.boundaryPointInterval=-1 |
| | | LAND2.mowingWidth=34 |
| | | LAND1.plannedPath=-5.830841,-2.644443;-12.323966,-4.153883;-12.276978,-4.492026;-6.161845,-3.070456;-6.492848,-3.496470;-12.229991,-4.830169;-12.183003,-5.168312;-6.823852,-3.922484;-7.154855,-4.348497;-12.136016,-5.506455;-12.089028,-5.844598;-7.487144,-4.774810;-7.821079,-5.201505;-12.042040,-6.182741;-11.995053,-6.520885;-8.155014,-5.628200;-8.700347,-6.104039;-11.948065,-6.859028;-11.901077,-7.197171;-10.070186,-6.771548;-11.440025,-7.439057;-11.854090,-7.535314 |
| | | LAND1.updateTime=2025-12-19 19\:44\:17 |
| | | LAND2.mowingSafetyDistance=0.50 |
| | | LAND2.plannedPath=-12.031,-3.808;-10.774,-3.615;-9.790,-3.809;-12.167,-4.172;-12.302,-4.537;-8.807,-4.002;-7.823,-4.196;-12.280,-4.878;-12.158,-5.203;-6.838,-4.389;-5.852,-4.582;-12.036,-5.528;-11.914,-5.854;-4.868,-4.775;-3.884,-4.969;-11.792,-6.179;-11.670,-6.504;-2.901,-5.162;-1.917,-5.355;-11.547,-6.829;-11.425,-7.155;-0.931,-5.548;0.055,-5.741;-11.303,-7.480;-11.181,-7.805;1.038,-5.935;2.022,-6.128;-11.059,-8.130;-10.937,-8.456;3.005,-6.322 |
| | | LAND1.baseStationCoordinates=3949.89151752,N,11616.79267501,E |
| | | LAND1.boundaryCoordinates=-10.36,-8.92;-12.10,-7.80;-12.66,-3.77;-4.96,-1.98;-6.04,-3.37;-7.12,-4.76;-8.20,-6.14;-9.28,-7.53;-10.36,-8.92 |
| | | LAND1.boundaryOriginalCoordinates=39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27;39.831498,116.279762,49.27;39.831500,116.279776,49.34;39.831502,116.279791,49.32;39.831504,116.279805,49.27;39.831507,116.279820,49.28 |
| | | LAND2.boundaryOriginalCoordinates=39.831468,116.279941,49.29;39.831465,116.279925,49.33;39.831463,116.279908,49.34;39.831462,116.279891,49.35;39.831461,116.279874,49.33;39.831458,116.279859,49.34;39.831456,116.279843,49.32;39.831454,116.279827,49.32;39.831452,116.279813,49.42;39.831450,116.279798,49.41;39.831448,116.279783,49.36;39.831447,116.279769,49.26;39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27 |
| | | LAND1.boundaryPointInterval=-1 |
| | | LAND1.createTime=2025-12-19 18\:31\:53 |
| | | LAND1.intelligentSceneAnalysis=-1 |
| | | LAND1.landArea=26.75 |
| | | LAND1.landName=21233 |
| | | LAND1.landNumber=LAND1 |
| | | LAND1.mowingBladeWidth=0.40 |
| | | LAND1.mowingOverlapDistance=0.06 |
| | | LAND1.mowingPattern=å¹³è¡çº¿ |
| | | LAND1.mowingTrack=-1 |
| | | LAND1.mowingWidth=34 |
| | | LAND1.plannedPath=-5.830841,-2.644443;-12.323966,-4.153883;-12.276978,-4.492026;-6.161845,-3.070456;-6.492848,-3.496470;-12.229991,-4.830169;-12.183003,-5.168312;-6.823852,-3.922484;-7.154855,-4.348497;-12.136016,-5.506455;-12.089028,-5.844598;-7.487144,-4.774810;-7.821079,-5.201505;-12.042040,-6.182741;-11.995053,-6.520885;-8.155014,-5.628200;-8.700347,-6.104039;-11.948065,-6.859028;-11.901077,-7.197171;-10.070186,-6.771548;-11.440025,-7.439057;-11.854090,-7.535314 |
| | | LAND1.returnPointCoordinates=-1 |
| | | LAND1.updateTime=2025-12-19 19\:44\:17 |
| | | LAND2.returnPointCoordinates=-1 |
| | | LAND2.mowingTrack=-1 |
| | | LAND1.userId=-1 |
| | | LAND1.angleThreshold=-1 |
| | | LAND2.mowingBladeWidth=0.40 |
| | | LAND1.landName=21233 |
| | | LAND1.mowingTrack=-1 |
| | | LAND2.baseStationCoordinates=3949.89151752,N,11616.79267501,E |
| | | LAND1.boundaryOriginalCoordinates=39.831445,116.279757,49.24;39.831445,116.279747,49.38;39.831448,116.279741,49.27;39.831455,116.279736,49.26;39.831463,116.279733,49.26;39.831473,116.279731,49.26;39.831483,116.279729,49.25;39.831491,116.279730,49.26;39.831496,116.279735,49.22;39.831497,116.279748,49.27;39.831498,116.279762,49.27;39.831500,116.279776,49.34;39.831502,116.279791,49.32;39.831504,116.279805,49.27;39.831507,116.279820,49.28 |
| | | LAND1.boundaryCoordinates=-10.36,-8.92;-12.10,-7.80;-12.66,-3.77;-4.96,-1.98;-6.04,-3.37;-7.12,-4.76;-8.20,-6.14;-9.28,-7.53;-10.36,-8.92 |
| | | LAND2.mowingPattern=å¹³è¡çº¿ |
| | | LAND2.landNumber=LAND2 |
| | | LAND1.mowingBladeWidth=0.40 |
| | |
| | | #Mower Configuration Properties - Updated |
| | | #Fri Dec 19 19:44:56 CST 2025 |
| | | #Current work land selection updated |
| | | #Sat Dec 20 15:10:30 GMT+08:00 2025 |
| | | appVersion=-1 |
| | | boundaryLengthVisible=false |
| | | currentWorkLandNumber=LAND1 |
| | | cuttingWidth=200 |
| | | firmwareVersion=-1 |
| | | handheldMarkerId=1872 |
| | | idleTrailDurationSeconds=60 |
| | | manualBoundaryDrawingMode=false |
| | | mapScale=41.56 |
| | | measurementModeEnabled=false |
| | | mowerId=860 |
| | | serialAutoConnect=true |
| | | serialBaudRate=115200 |
| | | serialPortName=COM15 |
| | | simCardNumber=-1 |
| | | viewCenterX=8.76 |
| | | viewCenterY=4.44 |
| | | currentWorkLandNumber=LAND2 |
| | | serialBaudRate=115200 |
| | | boundaryLengthVisible=false |
| | | idleTrailDurationSeconds=60 |
| | | handheldMarkerId=1872 |
| | | viewCenterX=5.62 |
| | | viewCenterY=6.22 |
| | | manualBoundaryDrawingMode=false |
| | | mowerId=860 |
| | | serialPortName=COM15 |
| | | serialAutoConnect=true |
| | | mapScale=13.68 |
| | | measurementModeEnabled=false |
| | | firmwareVersion=-1 |
| | | cuttingWidth=200 |
| | |
| | | private String plannedPath; |
| | | // è¿åç¹åæ |
| | | private String returnPointCoordinates; |
| | | // å¾è¿è·¯å¾åæ ï¼å²èæºå®æå²èä½ä¸è¿åçè·¯å¾åæ ï¼æ ¼å¼ï¼X1,Y1;X2,Y2;...;XN,YNï¼ |
| | | private String returnPathCoordinates; |
| | | // è¾¹çç¹é´é |
| | | private String boundaryPointInterval; |
| | | // è§åº¦éå¼ |
| | |
| | | private String mowingBladeWidth; |
| | | // å²èéå è·ç¦»ï¼ç±³ï¼ï¼é»è®¤0.06ç±³ |
| | | private String mowingOverlapDistance; |
| | | // å²èå®å
¨è·ç¦»ï¼ç±³ï¼ |
| | | private String mowingSafetyDistance; |
| | | |
| | | // åå¨å¤ä¸ªå°åçæ å°è¡¨ï¼é®ä¸ºå°åç¼å· |
| | | private static Map<String, Dikuai> dikuaiMap = new HashMap<>(); |
| | |
| | | dikuai.boundaryCoordinates = landProps.getProperty("boundaryCoordinates", "-1"); |
| | | dikuai.plannedPath = landProps.getProperty("plannedPath", "-1"); |
| | | dikuai.returnPointCoordinates = landProps.getProperty("returnPointCoordinates", "-1"); |
| | | dikuai.returnPathCoordinates = landProps.getProperty("returnPathCoordinates", "-1"); |
| | | dikuai.boundaryPointInterval = landProps.getProperty("boundaryPointInterval", "-1"); |
| | | dikuai.angleThreshold = landProps.getProperty("angleThreshold", "-1"); |
| | | dikuai.intelligentSceneAnalysis = landProps.getProperty("intelligentSceneAnalysis", "-1"); |
| | |
| | | dikuai.mowingTrack = landProps.getProperty("mowingTrack", "-1"); |
| | | dikuai.mowingBladeWidth = landProps.getProperty("mowingBladeWidth", "0.40"); |
| | | dikuai.mowingOverlapDistance = landProps.getProperty("mowingOverlapDistance", "0.06"); |
| | | dikuai.mowingSafetyDistance = landProps.getProperty("mowingSafetyDistance", "-1"); |
| | | |
| | | dikuaiMap.put(landNum, dikuai); |
| | | } |
| | |
| | | case "returnPointCoordinates": |
| | | this.returnPointCoordinates = value; |
| | | return true; |
| | | case "returnPathCoordinates": |
| | | this.returnPathCoordinates = value; |
| | | return true; |
| | | case "boundaryPointInterval": |
| | | this.boundaryPointInterval = value; |
| | | return true; |
| | |
| | | case "mowingOverlapDistance": |
| | | this.mowingOverlapDistance = value; |
| | | return true; |
| | | case "mowingSafetyDistance": |
| | | this.mowingSafetyDistance = value; |
| | | return true; |
| | | default: |
| | | System.err.println("æªç¥å段: " + fieldName); |
| | | return false; |
| | |
| | | if (dikuai.boundaryCoordinates != null) properties.setProperty(landNumber + ".boundaryCoordinates", dikuai.boundaryCoordinates); |
| | | if (dikuai.plannedPath != null) properties.setProperty(landNumber + ".plannedPath", dikuai.plannedPath); |
| | | if (dikuai.returnPointCoordinates != null) properties.setProperty(landNumber + ".returnPointCoordinates", dikuai.returnPointCoordinates); |
| | | if (dikuai.returnPathCoordinates != null) properties.setProperty(landNumber + ".returnPathCoordinates", dikuai.returnPathCoordinates); |
| | | if (dikuai.boundaryPointInterval != null) properties.setProperty(landNumber + ".boundaryPointInterval", dikuai.boundaryPointInterval); |
| | | if (dikuai.angleThreshold != null) properties.setProperty(landNumber + ".angleThreshold", dikuai.angleThreshold); |
| | | if (dikuai.intelligentSceneAnalysis != null) properties.setProperty(landNumber + ".intelligentSceneAnalysis", dikuai.intelligentSceneAnalysis); |
| | |
| | | if (dikuai.mowingTrack != null) properties.setProperty(landNumber + ".mowingTrack", dikuai.mowingTrack); |
| | | if (dikuai.mowingBladeWidth != null) properties.setProperty(landNumber + ".mowingBladeWidth", dikuai.mowingBladeWidth); |
| | | if (dikuai.mowingOverlapDistance != null) properties.setProperty(landNumber + ".mowingOverlapDistance", dikuai.mowingOverlapDistance); |
| | | if (dikuai.mowingSafetyDistance != null) properties.setProperty(landNumber + ".mowingSafetyDistance", dikuai.mowingSafetyDistance); |
| | | } |
| | | |
| | | try { |
| | |
| | | this.returnPointCoordinates = returnPointCoordinates; |
| | | } |
| | | |
| | | public String getReturnPathCoordinates() { |
| | | return returnPathCoordinates; |
| | | } |
| | | |
| | | public void setReturnPathCoordinates(String returnPathCoordinates) { |
| | | this.returnPathCoordinates = returnPathCoordinates; |
| | | } |
| | | |
| | | public String getBoundaryPointInterval() { |
| | | return boundaryPointInterval; |
| | | } |
| | |
| | | this.mowingOverlapDistance = mowingOverlapDistance; |
| | | } |
| | | |
| | | public String getMowingSafetyDistance() { |
| | | return mowingSafetyDistance; |
| | | } |
| | | |
| | | public void setMowingSafetyDistance(String mowingSafetyDistance) { |
| | | this.mowingSafetyDistance = mowingSafetyDistance; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "Dikuai{" + |
| | |
| | | ", boundaryCoordinates='" + boundaryCoordinates + '\'' + |
| | | ", plannedPath='" + plannedPath + '\'' + |
| | | ", returnPointCoordinates='" + returnPointCoordinates + '\'' + |
| | | ", returnPathCoordinates='" + returnPathCoordinates + '\'' + |
| | | ", boundaryPointInterval='" + boundaryPointInterval + '\'' + |
| | | ", angleThreshold='" + angleThreshold + '\'' + |
| | | ", intelligentSceneAnalysis='" + intelligentSceneAnalysis + '\'' + |
| | |
| | | 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 zhuye.MapRenderer; |
| | | import zhuye.Shouye; |
| | | import zhuye.Coordinate; |
| | | import zhuye.buttonset; |
| | | import zhuye.Fuzhibutton; |
| | | import zhuye.Lookbutton; |
| | | import gecaoji.Device; |
| | | |
| | | /** |
| | |
| | | |
| | | // å²èå®å
¨è·ç¦» |
| | | String displaySafetyDistance = "æªè®¾ç½®"; |
| | | Device device = Device.getActiveDevice(); |
| | | if (device != null) { |
| | | String safetyDistanceValue = device.getMowingSafetyDistance(); |
| | | if (safetyDistanceValue != null && !"-1".equals(safetyDistanceValue) && !safetyDistanceValue.trim().isEmpty()) { |
| | | try { |
| | | double distanceMeters = Double.parseDouble(safetyDistanceValue.trim()); |
| | | // 妿å¼å¤§äº100ï¼è®¤ä¸ºæ¯åç±³ï¼éè¦è½¬æ¢ä¸ºç±³ |
| | | if (distanceMeters > 100) { |
| | | distanceMeters = distanceMeters / 100.0; |
| | | } |
| | | displaySafetyDistance = String.format("%.2fç±³", distanceMeters); |
| | | } catch (NumberFormatException e) { |
| | | displaySafetyDistance = "æªè®¾ç½®"; |
| | | String safetyDistanceValue = dikuai.getMowingSafetyDistance(); |
| | | if (safetyDistanceValue != null && !"-1".equals(safetyDistanceValue) && !safetyDistanceValue.trim().isEmpty()) { |
| | | try { |
| | | double distanceMeters = Double.parseDouble(safetyDistanceValue.trim()); |
| | | // 妿å¼å¤§äº100ï¼è®¤ä¸ºæ¯åç±³ï¼éè¦è½¬æ¢ä¸ºç±³ |
| | | if (distanceMeters > 100) { |
| | | distanceMeters = distanceMeters / 100.0; |
| | | } |
| | | displaySafetyDistance = String.format("%.2fç±³", distanceMeters); |
| | | } catch (NumberFormatException e) { |
| | | displaySafetyDistance = "æªè®¾ç½®"; |
| | | } |
| | | } |
| | | JPanel mowingSafetyDistancePanel = createCardInfoItem("å²èå®å
¨è·ç¦»:", displaySafetyDistance); |
| | | contentPanel.add(mowingSafetyDistancePanel); |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | // è¿åç¹åæ ï¼å¸¦ä¿®æ¹æé®ï¼ |
| | | contentPanel.add(createCardInfoItemWithButton("è¿åç¹åæ :", |
| | | getDisplayValue(dikuai.getReturnPointCoordinates(), "æªè®¾ç½®"), |
| | | "ä¿®æ¹", e -> editReturnPoint(dikuai))); |
| | | // å¾è¿ç¹è·¯å¾ï¼å¸¦æ¥ç徿 æé®ï¼ |
| | | JPanel returnPathPanel = createCardInfoItemWithButton("å¾è¿ç¹è·¯å¾:", |
| | | getDisplayValue(dikuai.getReturnPathCoordinates(), "æªè®¾ç½®"), |
| | | 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()); |
| | |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | // è·¯å¾åæ ï¼å¸¦æ¥çæé®ï¼ |
| | | JPanel pathPanel = createCardInfoItemWithButtonOnly("è·¯å¾åæ :", |
| | | "æ¥ç", e -> editPlannedPath(dikuai)); |
| | | JPanel pathPanel = createCardInfoItemWithIconButton("è·¯å¾åæ :", |
| | | createViewButton(e -> editPlannedPath(dikuai))); |
| | | configureInteractiveLabel(getInfoItemTitleLabel(pathPanel), |
| | | () -> editPlannedPath(dikuai), |
| | | "ç¹å»æ¥ç/ç¼è¾è·¯å¾åæ "); |
| | | contentPanel.add(pathPanel); |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | JPanel baseStationPanel = createCardInfoItemWithButtonOnly("åºç«åæ :", |
| | | "æ¥ç", e -> editBaseStationCoordinates(dikuai)); |
| | | JPanel baseStationPanel = createCardInfoItemWithIconButton("åºç«åæ :", |
| | | createViewButton(e -> editBaseStationCoordinates(dikuai))); |
| | | configureInteractiveLabel(getInfoItemTitleLabel(baseStationPanel), |
| | | () -> editBaseStationCoordinates(dikuai), |
| | | "ç¹å»æ¥ç/ç¼è¾åºç«åæ "); |
| | | contentPanel.add(baseStationPanel); |
| | | contentPanel.add(Box.createRigidArea(new Dimension(0, 10))); |
| | | |
| | | JPanel boundaryOriginalPanel = createCardInfoItemWithButtonOnly("è¾¹çåå§åæ :", |
| | | "æ¥ç", e -> editBoundaryOriginalCoordinates(dikuai)); |
| | | JPanel boundaryOriginalPanel = createCardInfoItemWithIconButton("è¾¹çåå§åæ :", |
| | | createViewButton(e -> editBoundaryOriginalCoordinates(dikuai))); |
| | | configureInteractiveLabel(getInfoItemTitleLabel(boundaryOriginalPanel), |
| | | () -> editBoundaryOriginalCoordinates(dikuai), |
| | | "ç¹å»æ¥ç/ç¼è¾è¾¹çåå§åæ "); |
| | |
| | | |
| | | JPanel completedTrackPanel = createCardInfoItemWithButton("已宿å²èè·¯å¾:", |
| | | getTruncatedValue(dikuai.getMowingTrack(), 12, "æªè®°å½"), |
| | | "æ¥ç", e -> showCompletedMowingTrackDialog(dikuai)); |
| | | createViewButton(e -> showCompletedMowingTrackDialog(dikuai))); |
| | | setInfoItemTooltip(completedTrackPanel, dikuai.getMowingTrack()); |
| | | configureInteractiveLabel(getInfoItemTitleLabel(completedTrackPanel), |
| | | () -> showCompletedMowingTrackDialog(dikuai), |
| | |
| | | return itemPanel; |
| | | } |
| | | |
| | | private JPanel createCardInfoItemWithButton(String label, String value, JButton button) { |
| | | JPanel itemPanel = new JPanel(new BorderLayout()); |
| | | itemPanel.setBackground(CARD_BACKGROUND); |
| | | // å¢å é«åº¦ä»¥ç¡®ä¿æé®å®æ´æ¾ç¤ºï¼æé®é«åº¦çº¦24-28åç´ ï¼å ä¸ä¸ä¸è¾¹è·ï¼ |
| | | itemPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); |
| | | itemPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30)); |
| | | itemPanel.setMinimumSize(new Dimension(0, 28)); |
| | | |
| | | JLabel labelComp = new JLabel(label); |
| | | labelComp.setFont(new Font("微软é
é»", Font.PLAIN, 14)); |
| | | labelComp.setForeground(LIGHT_TEXT); |
| | | |
| | | JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); |
| | | rightPanel.setBackground(CARD_BACKGROUND); |
| | | // æ·»å åç´å
è¾¹è·ä»¥ç¡®ä¿æé®ä¸è¢«è£åª |
| | | rightPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); |
| | | |
| | | JLabel valueComp = new JLabel(value); |
| | | valueComp.setFont(new Font("微软é
é»", Font.PLAIN, 14)); |
| | | valueComp.setForeground(TEXT_COLOR); |
| | | |
| | | rightPanel.add(valueComp); |
| | | rightPanel.add(button); |
| | | |
| | | itemPanel.add(labelComp, BorderLayout.WEST); |
| | | itemPanel.add(rightPanel, BorderLayout.CENTER); |
| | | itemPanel.putClientProperty("valueLabel", valueComp); |
| | | itemPanel.putClientProperty("titleLabel", labelComp); |
| | | |
| | | return itemPanel; |
| | | } |
| | | |
| | | private JPanel createCardInfoItemWithButtonOnly(String label, String buttonText, ActionListener listener) { |
| | | JPanel itemPanel = new JPanel(new BorderLayout()); |
| | | itemPanel.setBackground(CARD_BACKGROUND); |
| | |
| | | return itemPanel; |
| | | } |
| | | |
| | | private JPanel createCardInfoItemWithIconButton(String label, JButton button) { |
| | | JPanel itemPanel = new JPanel(new BorderLayout()); |
| | | itemPanel.setBackground(CARD_BACKGROUND); |
| | | // å¢å é«åº¦ä»¥ç¡®ä¿æé®å®æ´æ¾ç¤ºï¼æé®é«åº¦çº¦24-28åç´ ï¼å ä¸ä¸ä¸è¾¹è·ï¼ |
| | | itemPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35)); |
| | | itemPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30)); |
| | | itemPanel.setMinimumSize(new Dimension(0, 28)); |
| | | |
| | | JLabel labelComp = new JLabel(label); |
| | | labelComp.setFont(new Font("微软é
é»", Font.PLAIN, 14)); |
| | | labelComp.setForeground(LIGHT_TEXT); |
| | | |
| | | JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0)); |
| | | rightPanel.setBackground(CARD_BACKGROUND); |
| | | // æ·»å åç´å
è¾¹è·ä»¥ç¡®ä¿æé®ä¸è¢«è£åª |
| | | rightPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); |
| | | |
| | | rightPanel.add(button); |
| | | |
| | | itemPanel.add(labelComp, BorderLayout.WEST); |
| | | itemPanel.add(rightPanel, BorderLayout.CENTER); |
| | | itemPanel.putClientProperty("titleLabel", labelComp); |
| | | |
| | | return itemPanel; |
| | | } |
| | | |
| | | private JPanel createBoundaryInfoItem(Dikuai dikuai) { |
| | | JPanel itemPanel = new JPanel(new BorderLayout()); |
| | | itemPanel.setBackground(CARD_BACKGROUND); |
| | |
| | | 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("å¤å¶"); |
| | | |
| | | // 夿æ¯å¦æ¯å¾è¿ç¹è·¯å¾å¯¹è¯æ¡ |
| | | boolean isReturnPathDialog = title != null && title.contains("å¾è¿ç¹è·¯å¾"); |
| | | JButton okButton; |
| | | JButton cancelButton; |
| | | JButton copyButton; |
| | | |
| | | 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 = Fuzhibutton.createCopyButton( |
| | | (java.util.function.Supplier<String>) () -> { |
| | | String text = textArea.getText(); |
| | | if (text == null) { |
| | | text = ""; |
| | | } |
| | | String trimmed = text.trim(); |
| | | if (trimmed.isEmpty() || "-1".equals(trimmed)) { |
| | | return null; // è¿ånullä¼è§¦å"æªè®¾ç½®è¦å¤å¶çå
容"æç¤º |
| | | } |
| | | return text; |
| | | }, |
| | | "å¤å¶" + title, |
| | | new Color(230, 250, 240) |
| | | ); |
| | | |
| | | } 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]; |
| | |
| | | |
| | | 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); |
| | |
| | | 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 createDeleteButton() { |
| | | JButton button = createStyledButton("å é¤", RED_COLOR, false); // è½®å»é£æ ¼ |
| | | ImageIcon deleteIcon = loadIcon("image/delete.png", 16, 16); |
| | | JButton button = new JButton(); |
| | | ImageIcon deleteIcon = loadIcon("image/delete.png", 25, 25); |
| | | if (deleteIcon != null) { |
| | | button.setIcon(deleteIcon); |
| | | button.setIconTextGap(6); |
| | | } else { |
| | | button.setText("å é¤"); |
| | | } |
| | | button.setFont(new Font("微软é
é»", Font.PLAIN, 11)); |
| | | button.setForeground(RED_COLOR); |
| | | button.setBorder(BorderFactory.createEmptyBorder()); |
| | | button.setContentAreaFilled(false); |
| | | button.setFocusPainted(false); |
| | | button.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | button.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { button.setOpaque(true); button.setBackground(new Color(255, 240, 240)); } |
| | | public void mouseExited(MouseEvent e) { button.setOpaque(false); } |
| | | }); |
| | | return button; |
| | | } |
| | | |
| | | private JButton createViewButton(ActionListener listener) { |
| | | // ä½¿ç¨ Lookbutton ç±»å建æ¥çæé® |
| | | return Lookbutton.createViewButton(listener, new Color(230, 250, 240)); |
| | | } |
| | | |
| | | private JButton createPrimaryFooterButton(String text) { |
| | | return createStyledButton(text, PRIMARY_COLOR, true); // å®å¿é£æ ¼ |
| | | } |
| | |
| | | }); |
| | | } |
| | | |
| | | 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()); |
| | | if (edited == null) { |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | if (!configMap.isEmpty()) { |
| | | List<ExistingObstacle> remaining = new ArrayList<>(configMap.values()); |
| | | remaining.sort(Comparator.comparing(ExistingObstacle::getName, String.CASE_INSENSITIVE_ORDER)); |
| | | remaining.sort((a, b) -> String.CASE_INSENSITIVE_ORDER.compare(a.getName(), b.getName())); |
| | | result.addAll(remaining); |
| | | } |
| | | if (result.isEmpty()) { |
| | |
| | | import javax.swing.*; |
| | | import javax.swing.SwingUtilities; |
| | | import java.awt.*; |
| | | import java.awt.datatransfer.Clipboard; |
| | | import java.awt.datatransfer.StringSelection; |
| | | import java.awt.event.ActionEvent; |
| | | import java.awt.event.ActionListener; |
| | | import java.math.BigDecimal; |
| | |
| | | import org.locationtech.jts.geom.Coordinate; |
| | | import gecaoji.Device; |
| | | import java.util.Locale; |
| | | import zhuye.Fuzhibutton; |
| | | |
| | | /** |
| | | * çæå²èè·¯å¾é¡µé¢ |
| | |
| | | titleLabel.setForeground(TEXT_COLOR); |
| | | titlePanel.add(titleLabel, BorderLayout.WEST); |
| | | |
| | | // å建å¤å¶æé® |
| | | JButton copyButton = createCopyButton(title, () -> { |
| | | String text = textArea.getText(); |
| | | if (text == null || text.trim().isEmpty()) { |
| | | JOptionPane.showMessageDialog(this, title + " æªè®¾ç½®", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | copyToClipboard(text, title); |
| | | }); |
| | | // å建å¤å¶æé®ï¼ä½¿ç¨ Fuzhibuttonï¼ |
| | | JButton copyButton = Fuzhibutton.createCopyButton( |
| | | () -> { |
| | | String text = textArea.getText(); |
| | | if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) { |
| | | return null; // è¿ånullä¼è§¦å"æªè®¾ç½®"æç¤º |
| | | } |
| | | return text; |
| | | }, |
| | | "å¤å¶" + title, |
| | | new Color(230, 250, 240) |
| | | ); |
| | | titlePanel.add(copyButton, BorderLayout.EAST); |
| | | |
| | | section.add(titlePanel, BorderLayout.NORTH); |
| | |
| | | titleLabel.setForeground(TEXT_COLOR); |
| | | titlePanel.add(titleLabel, BorderLayout.WEST); |
| | | |
| | | // å建å¤å¶æé® |
| | | JButton copyButton = createCopyButton(title, () -> { |
| | | String text = textField.getText(); |
| | | if (text == null || text.trim().isEmpty()) { |
| | | JOptionPane.showMessageDialog(this, title + " æªè®¾ç½®", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | copyToClipboard(text, title); |
| | | }); |
| | | // å建å¤å¶æé®ï¼ä½¿ç¨ Fuzhibuttonï¼ |
| | | JButton copyButton = Fuzhibutton.createCopyButton( |
| | | () -> { |
| | | String text = textField.getText(); |
| | | if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) { |
| | | return null; // è¿ånullä¼è§¦å"æªè®¾ç½®"æç¤º |
| | | } |
| | | return text; |
| | | }, |
| | | "å¤å¶" + title, |
| | | new Color(230, 250, 240) |
| | | ); |
| | | titlePanel.add(copyButton, BorderLayout.EAST); |
| | | |
| | | section.add(titlePanel, BorderLayout.NORTH); |
| | |
| | | return "parallel"; |
| | | } |
| | | |
| | | /** |
| | | * å建å¤å¶æé® |
| | | */ |
| | | private JButton createCopyButton(String title, Runnable copyAction) { |
| | | JButton copyButton = new JButton(); |
| | | Font titleFont = new Font("微软é
é»", Font.BOLD, 14); |
| | | FontMetrics metrics = getFontMetrics(titleFont); |
| | | int iconSize = metrics.getHeight(); // ä½¿ç¨æ é¢åä½é«åº¦ä½ä¸ºå¾æ å¤§å° |
| | | |
| | | // å è½½å¤å¶å¾æ |
| | | ImageIcon copyIcon = null; |
| | | ImageIcon successIcon = null; |
| | | try { |
| | | ImageIcon originalCopyIcon = new ImageIcon("image/fuzhi.png"); |
| | | Image scaledCopyImage = originalCopyIcon.getImage().getScaledInstance(iconSize, iconSize, Image.SCALE_SMOOTH); |
| | | copyIcon = new ImageIcon(scaledCopyImage); |
| | | |
| | | // å è½½æå徿 |
| | | ImageIcon originalSuccessIcon = new ImageIcon("image/fuzhisucc.png"); |
| | | Image scaledSuccessImage = originalSuccessIcon.getImage().getScaledInstance(iconSize, iconSize, Image.SCALE_SMOOTH); |
| | | successIcon = new ImageIcon(scaledSuccessImage); |
| | | } catch (Exception e) { |
| | | // 妿å¾çå 载失败ï¼ä½¿ç¨ææ¬ |
| | | copyButton.setText("å¤å¶"); |
| | | copyButton.setFont(new Font("微软é
é»", Font.PLAIN, 12)); |
| | | System.err.println("æ æ³å è½½å¤å¶å¾æ : " + e.getMessage()); |
| | | } |
| | | |
| | | final ImageIcon finalCopyIcon = copyIcon; |
| | | final ImageIcon finalSuccessIcon = successIcon; |
| | | |
| | | copyButton.setIcon(finalCopyIcon); |
| | | copyButton.setContentAreaFilled(false); |
| | | copyButton.setBorder(null); |
| | | copyButton.setFocusPainted(false); |
| | | copyButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | copyButton.setToolTipText("å¤å¶" + title); |
| | | |
| | | // æ·»å ç¹å»äºä»¶ |
| | | copyButton.addActionListener(e -> { |
| | | copyAction.run(); |
| | | // å¤å¶æåå忢徿 |
| | | if (finalSuccessIcon != null) { |
| | | copyButton.setIcon(finalSuccessIcon); |
| | | // 1ç§åæ¢å¤å徿 |
| | | Timer timer = new Timer(1000, evt -> { |
| | | copyButton.setIcon(finalCopyIcon); |
| | | }); |
| | | timer.setRepeats(false); |
| | | timer.start(); |
| | | } |
| | | }); |
| | | |
| | | return copyButton; |
| | | } |
| | | |
| | | /** |
| | | * å¤å¶ææ¬å°åªè´´æ¿ |
| | | */ |
| | | private void copyToClipboard(String text, String title) { |
| | | if (text == null || text.trim().isEmpty()) { |
| | | JOptionPane.showMessageDialog(this, title + " æªè®¾ç½®", "æç¤º", JOptionPane.INFORMATION_MESSAGE); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | StringSelection selection = new StringSelection(text); |
| | | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); |
| | | clipboard.setContents(selection, selection); |
| | | // 廿æåæç¤ºå¼¹çª |
| | | } catch (Exception ex) { |
| | | JOptionPane.showMessageDialog(this, "å¤å¶å¤±è´¥: " + ex.getMessage(), "é误", JOptionPane.ERROR_MESSAGE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | if (isMeaningfulValue(plannedPath)) { |
| | | dikuai.setPlannedPath(plannedPath); |
| | | } |
| | | |
| | | // ä¿åå²èå®å
¨è·ç¦»ï¼ä¼å
ä»dikuaiDataè·åï¼å¦åä»TextFieldè·åï¼ |
| | | if (dikuaiData.containsKey("mowingSafetyDistance")) { |
| | | dikuai.setMowingSafetyDistance(dikuaiData.get("mowingSafetyDistance")); |
| | | } else if (mowingSafetyDistanceField != null) { |
| | | String safetyDistanceText = mowingSafetyDistanceField.getText().trim(); |
| | | if (!safetyDistanceText.isEmpty()) { |
| | | try { |
| | | double safetyDistanceMeters = Double.parseDouble(safetyDistanceText); |
| | | dikuai.setMowingSafetyDistance(String.format(Locale.US, "%.2f", safetyDistanceMeters)); |
| | | } catch (NumberFormatException e) { |
| | | dikuai.setMowingSafetyDistance(safetyDistanceText); |
| | | } |
| | | } |
| | | } |
| | | |
| | | Dikuai.putDikuai(landNumber, dikuai); |
| | | Dikuai.saveToProperties(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package zhuye; |
| | | |
| | | import javax.swing.*; |
| | | import java.awt.*; |
| | | import java.awt.datatransfer.Clipboard; |
| | | import java.awt.datatransfer.StringSelection; |
| | | import java.awt.event.ActionEvent; |
| | | import java.awt.event.ActionListener; |
| | | import java.awt.event.MouseAdapter; |
| | | import java.awt.event.MouseEvent; |
| | | |
| | | /** |
| | | * å¤å¶æé®å·¥å
·ç±» |
| | | * æä¾ç»ä¸çå¤å¶æé®åå»ºæ¹æ³ï¼é»è®¤æ¾ç¤ºå¤å¶å¾æ ï¼å¤å¶æååæ¾ç¤ºæå徿 |
| | | */ |
| | | public final class Fuzhibutton { |
| | | |
| | | // é»è®¤å¾æ å¤§å° |
| | | private static final int DEFAULT_ICON_SIZE = 18; |
| | | // æå徿 æ¾ç¤ºæ¶é¿ï¼æ¯«ç§ï¼ |
| | | private static final int SUCCESS_ICON_DURATION = 1500; |
| | | |
| | | private Fuzhibutton() { |
| | | // å·¥å
·ç±»ä¸éè¦å®ä¾å |
| | | } |
| | | |
| | | /** |
| | | * å建å¤å¶æé® |
| | | * é»è®¤æ¾ç¤º image/fuzhi.png 徿 ï¼å¤å¶æååæ¾ç¤º image/fuzhisucc.png 徿 |
| | | * |
| | | * @param textToCopy è¦å¤å¶çææ¬å
容ï¼å¦æä¸ºnullï¼åéè¦å¨ç¹å»æ¶éè¿åè°æä¾ï¼ |
| | | * @param tooltip æé®æç¤ºææ¬ |
| | | * @param hoverColor é¼ æ æ¬åæ¶çèæ¯é¢è²ï¼å¦æä¸ºnullï¼ä½¿ç¨é»è®¤é¢è²ï¼ |
| | | * @return é
置好çå¤å¶æé® |
| | | */ |
| | | public static JButton createCopyButton(String textToCopy, String tooltip, Color hoverColor) { |
| | | JButton copyButton = new JButton(); |
| | | |
| | | // å è½½å¾æ |
| | | ImageIcon copyIcon = loadIcon("image/fuzhi.png", DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); |
| | | ImageIcon successIcon = loadIcon("image/fuzhisucc.png", DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); |
| | | |
| | | final ImageIcon finalCopyIcon = copyIcon; |
| | | final ImageIcon finalSuccessIcon = successIcon; |
| | | |
| | | // 设置æé®å¾æ |
| | | if (copyIcon != null) { |
| | | copyButton.setIcon(copyIcon); |
| | | } else { |
| | | copyButton.setText("å¤å¶"); |
| | | } |
| | | |
| | | // 设置æé®æ ·å¼ |
| | | copyButton.setFont(new Font("微软é
é»", Font.PLAIN, 11)); |
| | | copyButton.setForeground(new Color(46, 139, 87)); // PRIMARY_COLOR |
| | | copyButton.setBorder(BorderFactory.createEmptyBorder()); |
| | | copyButton.setContentAreaFilled(false); |
| | | copyButton.setFocusPainted(false); |
| | | copyButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | |
| | | // 设置æç¤ºææ¬ä¸º"å¤å¶ä¿¡æ¯" |
| | | copyButton.setToolTipText("å¤å¶ä¿¡æ¯"); |
| | | |
| | | // 设置æ¬åææ |
| | | final Color finalHoverColor = hoverColor != null ? hoverColor : new Color(230, 250, 240); |
| | | copyButton.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { |
| | | copyButton.setOpaque(true); |
| | | copyButton.setBackground(finalHoverColor); |
| | | } |
| | | |
| | | public void mouseExited(MouseEvent e) { |
| | | copyButton.setOpaque(false); |
| | | } |
| | | }); |
| | | |
| | | // æ·»å å¤å¶åè½ |
| | | copyButton.addActionListener(new ActionListener() { |
| | | @Override |
| | | public void actionPerformed(ActionEvent e) { |
| | | String text = textToCopy; |
| | | |
| | | // 妿 textToCopy 为 nullï¼å°è¯ä»ç¶ç»ä»¶è·åææ¬ï¼å¦ JTextAreaï¼ |
| | | if (text == null) { |
| | | // å°è¯ä»ç¶ç»ä»¶ä¸æ¥æ¾ JTextArea |
| | | Container parent = copyButton.getParent(); |
| | | while (parent != null) { |
| | | if (parent instanceof JDialog) { |
| | | Component[] components = ((JDialog) parent).getContentPane().getComponents(); |
| | | text = findTextFromComponents(components); |
| | | break; |
| | | } else if (parent instanceof JFrame) { |
| | | Component[] components = ((JFrame) parent).getContentPane().getComponents(); |
| | | text = findTextFromComponents(components); |
| | | break; |
| | | } |
| | | parent = parent.getParent(); |
| | | } |
| | | } |
| | | |
| | | // å¦ææ²¡æéè¦å¤å¶çå
容ï¼ç´æ¥è¿åï¼ä¸æ¾ç¤ºå¼¹çªæç¤º |
| | | if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) { |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | StringSelection selection = new StringSelection(text); |
| | | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); |
| | | clipboard.setContents(selection, selection); |
| | | |
| | | // å¤å¶æåååæ¢ä¸ºæå徿 |
| | | if (finalSuccessIcon != null) { |
| | | copyButton.setIcon(finalSuccessIcon); |
| | | // 1.5ç§åæ¢å¤ä¸ºåå§å¾æ |
| | | Timer timer = new Timer(SUCCESS_ICON_DURATION, evt -> { |
| | | if (finalCopyIcon != null) { |
| | | copyButton.setIcon(finalCopyIcon); |
| | | } |
| | | }); |
| | | timer.setRepeats(false); |
| | | timer.start(); |
| | | } |
| | | } catch (Exception ex) { |
| | | JOptionPane.showMessageDialog( |
| | | SwingUtilities.getWindowAncestor(copyButton), |
| | | "å¤å¶å¤±è´¥: " + ex.getMessage(), |
| | | "é误", |
| | | JOptionPane.ERROR_MESSAGE |
| | | ); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | return copyButton; |
| | | } |
| | | |
| | | /** |
| | | * å建å¤å¶æé®ï¼ä½¿ç¨åè°å½æ°æä¾è¦å¤å¶çææ¬ï¼ |
| | | * |
| | | * @param copyAction å¤å¶å¨ä½åè°ï¼è¿åè¦å¤å¶çææ¬ |
| | | * @param tooltip æé®æç¤ºææ¬ |
| | | * @param hoverColor é¼ æ æ¬åæ¶çèæ¯é¢è²ï¼å¦æä¸ºnullï¼ä½¿ç¨é»è®¤é¢è²ï¼ |
| | | * @return é
置好çå¤å¶æé® |
| | | */ |
| | | public static JButton createCopyButton(java.util.function.Supplier<String> copyAction, String tooltip, Color hoverColor) { |
| | | JButton copyButton = new JButton(); |
| | | |
| | | // å è½½å¾æ |
| | | ImageIcon copyIcon = loadIcon("image/fuzhi.png", DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); |
| | | ImageIcon successIcon = loadIcon("image/fuzhisucc.png", DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); |
| | | |
| | | final ImageIcon finalCopyIcon = copyIcon; |
| | | final ImageIcon finalSuccessIcon = successIcon; |
| | | |
| | | // 设置æé®å¾æ |
| | | if (copyIcon != null) { |
| | | copyButton.setIcon(copyIcon); |
| | | } else { |
| | | copyButton.setText("å¤å¶"); |
| | | } |
| | | |
| | | // 设置æé®æ ·å¼ |
| | | copyButton.setFont(new Font("微软é
é»", Font.PLAIN, 11)); |
| | | copyButton.setForeground(new Color(46, 139, 87)); // PRIMARY_COLOR |
| | | copyButton.setBorder(BorderFactory.createEmptyBorder()); |
| | | copyButton.setContentAreaFilled(false); |
| | | copyButton.setFocusPainted(false); |
| | | copyButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | |
| | | // 设置æç¤ºææ¬ä¸º"å¤å¶ä¿¡æ¯" |
| | | copyButton.setToolTipText("å¤å¶ä¿¡æ¯"); |
| | | |
| | | // 设置æ¬åææ |
| | | final Color finalHoverColor = hoverColor != null ? hoverColor : new Color(230, 250, 240); |
| | | copyButton.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { |
| | | copyButton.setOpaque(true); |
| | | copyButton.setBackground(finalHoverColor); |
| | | } |
| | | |
| | | public void mouseExited(MouseEvent e) { |
| | | copyButton.setOpaque(false); |
| | | } |
| | | }); |
| | | |
| | | // æ·»å å¤å¶åè½ |
| | | copyButton.addActionListener(new ActionListener() { |
| | | @Override |
| | | public void actionPerformed(ActionEvent e) { |
| | | String text = copyAction != null ? copyAction.get() : null; |
| | | |
| | | // å¦ææ²¡æéè¦å¤å¶çå
容ï¼ç´æ¥è¿åï¼ä¸æ¾ç¤ºå¼¹çªæç¤º |
| | | if (text == null || text.trim().isEmpty() || "-1".equals(text.trim())) { |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | StringSelection selection = new StringSelection(text); |
| | | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); |
| | | clipboard.setContents(selection, selection); |
| | | |
| | | // å¤å¶æåååæ¢ä¸ºæå徿 |
| | | if (finalSuccessIcon != null) { |
| | | copyButton.setIcon(finalSuccessIcon); |
| | | // 1.5ç§åæ¢å¤ä¸ºåå§å¾æ |
| | | Timer timer = new Timer(SUCCESS_ICON_DURATION, evt -> { |
| | | if (finalCopyIcon != null) { |
| | | copyButton.setIcon(finalCopyIcon); |
| | | } |
| | | }); |
| | | timer.setRepeats(false); |
| | | timer.start(); |
| | | } |
| | | } catch (Exception ex) { |
| | | JOptionPane.showMessageDialog( |
| | | SwingUtilities.getWindowAncestor(copyButton), |
| | | "å¤å¶å¤±è´¥: " + ex.getMessage(), |
| | | "é误", |
| | | JOptionPane.ERROR_MESSAGE |
| | | ); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | return copyButton; |
| | | } |
| | | |
| | | /** |
| | | * å è½½å¾æ å¹¶è°æ´å¤§å° |
| | | * |
| | | * @param path 徿 è·¯å¾ |
| | | * @param width ç®æ 宽度 |
| | | * @param height ç®æ é«åº¦ |
| | | * @return è°æ´å¤§å°åç徿 ï¼å¦æå 载失败è¿ånull |
| | | */ |
| | | private static ImageIcon loadIcon(String path, int width, int height) { |
| | | try { |
| | | ImageIcon rawIcon = new ImageIcon(path); |
| | | if (rawIcon.getIconWidth() <= 0 || rawIcon.getIconHeight() <= 0) { |
| | | return null; |
| | | } |
| | | Image scaled = rawIcon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH); |
| | | return new ImageIcon(scaled); |
| | | } catch (Exception ex) { |
| | | System.err.println("æ æ³å è½½å¾æ : " + path + " - " + ex.getMessage()); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä»ç»ä»¶æ 䏿¥æ¾ JTextArea å¹¶è·åå
¶ææ¬ |
| | | * |
| | | * @param components ç»ä»¶æ°ç» |
| | | * @return æ¾å°çææ¬ï¼å¦ææªæ¾å°è¿ånull |
| | | */ |
| | | private static String findTextFromComponents(Component[] components) { |
| | | for (Component comp : components) { |
| | | if (comp instanceof JTextArea) { |
| | | return ((JTextArea) comp).getText(); |
| | | } else if (comp instanceof Container) { |
| | | String text = findTextFromComponents(((Container) comp).getComponents()); |
| | | if (text != null) { |
| | | return text; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package zhuye; |
| | | |
| | | import javax.swing.*; |
| | | import java.awt.*; |
| | | import java.awt.event.ActionListener; |
| | | import java.awt.event.MouseAdapter; |
| | | import java.awt.event.MouseEvent; |
| | | |
| | | /** |
| | | * æ¥çæé®å·¥å
·ç±» |
| | | * æä¾ç»ä¸çæ¥çæé®åå»ºæ¹æ³ï¼é»è®¤æ¾ç¤ºæ¥ç徿 ï¼ç¹å»æé®æ§è¡å¯¹åºçæä½ |
| | | */ |
| | | public final class Lookbutton { |
| | | |
| | | // é»è®¤å¾æ å¤§å° |
| | | private static final int DEFAULT_ICON_SIZE =25; |
| | | |
| | | private Lookbutton() { |
| | | // å·¥å
·ç±»ä¸éè¦å®ä¾å |
| | | } |
| | | |
| | | /** |
| | | * å建æ¥çæé® |
| | | * é»è®¤æ¾ç¤º image/look.png 徿 ï¼ç¹å»æé®æ§è¡ä¼ å
¥çæä½ |
| | | * |
| | | * @param listener æé®ç¹å»äºä»¶çå¬å¨ï¼å½æé®è¢«ç¹å»æ¶æ§è¡ |
| | | * @param hoverColor é¼ æ æ¬åæ¶çèæ¯é¢è²ï¼å¦æä¸ºnullï¼ä½¿ç¨é»è®¤é¢è²ï¼ |
| | | * @return é
ç½®å¥½çæ¥çæé® |
| | | */ |
| | | public static JButton createViewButton(ActionListener listener, Color hoverColor) { |
| | | JButton viewButton = new JButton(); |
| | | |
| | | // å è½½å¾æ |
| | | ImageIcon lookIcon = loadIcon("image/look.png", DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); |
| | | |
| | | // 设置æé®å¾æ |
| | | if (lookIcon != null) { |
| | | viewButton.setIcon(lookIcon); |
| | | } else { |
| | | viewButton.setText("æ¥ç"); |
| | | } |
| | | |
| | | // 设置æé®æ ·å¼ |
| | | viewButton.setFont(new Font("微软é
é»", Font.PLAIN, 11)); |
| | | viewButton.setForeground(new Color(46, 139, 87)); // PRIMARY_COLOR |
| | | viewButton.setBorder(BorderFactory.createEmptyBorder()); |
| | | viewButton.setContentAreaFilled(false); |
| | | viewButton.setFocusPainted(false); |
| | | viewButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
| | | |
| | | // 设置æç¤ºææ¬ä¸º"ç¹å»æ¥ç" |
| | | viewButton.setToolTipText("ç¹å»æ¥ç"); |
| | | |
| | | // 设置æ¬åææ |
| | | final Color finalHoverColor = hoverColor != null ? hoverColor : new Color(230, 250, 240); |
| | | viewButton.addMouseListener(new MouseAdapter() { |
| | | public void mouseEntered(MouseEvent e) { |
| | | viewButton.setOpaque(true); |
| | | viewButton.setBackground(finalHoverColor); |
| | | } |
| | | |
| | | public void mouseExited(MouseEvent e) { |
| | | viewButton.setOpaque(false); |
| | | } |
| | | }); |
| | | |
| | | // æ·»å ç¹å»äºä»¶ |
| | | if (listener != null) { |
| | | viewButton.addActionListener(listener); |
| | | } |
| | | |
| | | return viewButton; |
| | | } |
| | | |
| | | /** |
| | | * å建æ¥çæé®ï¼ä½¿ç¨é»è®¤æ¬åé¢è²ï¼ |
| | | * |
| | | * @param listener æé®ç¹å»äºä»¶çå¬å¨ï¼å½æé®è¢«ç¹å»æ¶æ§è¡ |
| | | * @return é
ç½®å¥½çæ¥çæé® |
| | | */ |
| | | public static JButton createViewButton(ActionListener listener) { |
| | | return createViewButton(listener, null); |
| | | } |
| | | |
| | | /** |
| | | * å è½½å¾æ å¹¶è°æ´å¤§å° |
| | | * |
| | | * @param path 徿 è·¯å¾ |
| | | * @param width ç®æ 宽度 |
| | | * @param height ç®æ é«åº¦ |
| | | * @return è°æ´å¤§å°åç徿 ï¼å¦æå 载失败è¿ånull |
| | | */ |
| | | private static ImageIcon loadIcon(String path, int width, int height) { |
| | | try { |
| | | ImageIcon rawIcon = new ImageIcon(path); |
| | | if (rawIcon.getIconWidth() <= 0 || rawIcon.getIconHeight() <= 0) { |
| | | return null; |
| | | } |
| | | Image scaled = rawIcon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH); |
| | | return new ImageIcon(scaled); |
| | | } catch (Exception ex) { |
| | | System.err.println("æ æ³å è½½å¾æ : " + path + " - " + ex.getMessage()); |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | package zhuye; |
| | | |
| | | import java.awt.BasicStroke; |
| | | import java.awt.Color; |
| | | import java.awt.Cursor; |
| | | import java.awt.Dimension; |