package zhuye; import javax.swing.*; import java.awt.*; import java.awt.image.*; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** * 使用图片表示割草机卫星状态的小组件。 * 当定位状态为:0->image/gps0.png, 1->gps1.png, 2->gps2.png, 4->gps4.png, 5->gps5.png。 * 其他值使用 gps1.png。若图片未找到,回退为原有圆圈绘制。 */ public class gpszhuangtai extends JComponent { private static final long serialVersionUID = 1L; private static final int ICON_SIZE =16; private String currentCode; private Color currentColor = new Color(160, 160, 160); private final Color themeColor; // 图片缓存,key 为文件名(例如 "gps1.png") private final Map imageCache = new HashMap<>(); private Image currentImage; public gpszhuangtai(Color themeColor) { this.themeColor = themeColor != null ? themeColor : new Color(46, 139, 87); setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE)); setMinimumSize(new Dimension(ICON_SIZE, ICON_SIZE)); setMaximumSize(new Dimension(ICON_SIZE, ICON_SIZE)); setToolTipText("未知"); } public void setQuality(String code) { if (Objects.equals(currentCode, code)) { return; } currentCode = code; currentColor = resolveFixQualityColor(code); setToolTipText(resolveFixQualityDescription(code)); String filename = mapCodeToFilename(code); currentImage = loadImage(filename); // 始终使用默认图标尺寸,不根据图片原始大小改变组件首选尺寸 setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE)); repaint(); } private String mapCodeToFilename(String code) { if (code == null) { return "gps1.png"; } switch (code) { case "0": return "gps0.png"; case "1": return "gps1.png"; case "2": return "gps2.png"; case "4": return "gps4.png"; case "5": return "gps5.png"; default: return "gps1.png"; } } private Image loadImage(String filename) { if (filename == null) return null; if (imageCache.containsKey(filename)) { return imageCache.get(filename); } // 首先尝试从类路径加载(打包后可用) String path = "/image/" + filename; URL res = getClass().getResource(path); Image img = null; if (res != null) { img = new ImageIcon(res).getImage(); } else { // 回退到相对文件系统路径(开发环境下) try { img = new ImageIcon("image/" + filename).getImage(); } catch (Exception ignored) { img = null; } } imageCache.put(filename, img); return img; } private Color resolveFixQualityColor(String code) { if (code == null) { return new Color(160, 160, 160); } switch (code) { case "0": return new Color(160, 160, 160); case "1": return new Color(52, 152, 219); case "2": return new Color(26, 188, 156); case "3": return new Color(155, 89, 182); case "4": return themeColor; case "5": return new Color(241, 196, 15); case "6": return new Color(231, 76, 60); case "7": return new Color(230, 126, 34); default: return new Color(95, 95, 95); } } private String resolveFixQualityDescription(String code) { if (code == null) { return "未知"; } switch (code) { case "0": return "未定位"; case "1": return "单点定位"; case "2": return "码差分"; case "3": return "无效PPS"; case "4": return "固定解"; case "5": return "浮点解"; case "6": return "正在估算"; case "7": return "人工输入固定值"; default: return "其他"; } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); try { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int w = getWidth(); int h = getHeight(); if (currentImage != null) { // 强制以 ICON_SIZE x ICON_SIZE 绘制图标并居中 int drawW = ICON_SIZE; int drawH = ICON_SIZE; int x = (w - drawW) / 2; int y = (h - drawH) / 2; g2.drawImage(currentImage, x, y, drawW, drawH, null); } else { // 回退为圆圈绘制,保留原样风格 int diameter = Math.min(w, h) - 2; int x = (w - diameter) / 2; int y = (h - diameter) / 2; g2.setColor(currentColor); g2.fillOval(x, y, diameter, diameter); g2.setColor(new Color(255, 255, 255, 128)); g2.drawOval(x, y, diameter, diameter); } } finally { g2.dispose(); } } }