package home; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.io.File; import java.io.IOException; // ¿ÉÊÓ»¯Ãæ°åÀà class VisualizationPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; private int distance = 0; private int angle = 0; private AOAFollowSystem parentFrame; private String anchorid = "Anchor"; private String tagid = "Tag"; private double scaleFactor = 1.0; // Ëõ·ÅÒò×Ó private static final double MIN_SCALE = 0.2; // ×îСËõ·Å±¶Êý private static final double MAX_SCALE = 5.0; // ×î´óËõ·Å±¶Êý private int signalQuality = 0; // Ìí¼ÓÐźÅÖÊÁ¿±äÁ¿ // ʹÓÃÖ§³ÖÖÐÎĵÄ×ÖÌå private Font boldFont = new Font("Microsoft YaHei", Font.BOLD, 14); private Font normalFont = new Font("Microsoft YaHei", Font.PLAIN, 12); private Font titleFont = new Font("Microsoft YaHei", Font.BOLD, 12); private Image logoImage; // Ìí¼ÓͼƬ±äÁ¿ public VisualizationPanel(AOAFollowSystem parentFrame) { this.parentFrame = parentFrame; setPreferredSize(new Dimension(400, 400)); setBorder(BorderFactory.createTitledBorder(parentFrame.getString("visualization"))); // ¼ÓÔØÍ¼Æ¬ try { logoImage = ImageIO.read(new File("systemfile/1.png")); } catch (IOException e) { System.err.println("ÎÞ·¨¼ÓÔØÍ¼Æ¬: systemfile/1.png"); e.printStackTrace(); } // Ìí¼ÓÊó±ê¹öÂÖ¼àÌýÆ÷ addMouseWheelListener(new MouseWheelListener() { @Override public void mouseWheelMoved(MouseWheelEvent e) { int notches = e.getWheelRotation(); if (notches < 0) { // ÏòÉϹö¶¯£¬·Å´ó scaleFactor = Math.min(scaleFactor * 1.1, MAX_SCALE); } else { // ÏòϹö¶¯£¬ËõС scaleFactor = Math.max(scaleFactor / 1.1, MIN_SCALE); } repaint(); } }); } public void updatePosition(int distance, int angle,int signalQuality) { // ÓÅ»¯£ºÖ»ÓÐÊý¾Ý±ä»¯Ê±²ÅÖØ»æ if (this.distance != distance || this.angle != angle) { this.distance = distance; // Ö±½ÓʹÓÃԭʼ½Ç¶ÈÖµ£¬²»½øÐйéÒ»»¯´¦Àí this.angle = angle; this.signalQuality=signalQuality; repaint(); } } public void setAnchorId(String anchorid) { this.anchorid = anchorid; } public void setTagId(String tagid) { this.tagid = tagid; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // È·±£Ê¹ÓÃÖ§³ÖÖÐÎĵÄ×ÖÌå g2d.setFont(normalFont); int centerX = getWidth() / 2; int centerY = getHeight()/ 2 - 30; int baseRadius = Math.min(centerX, centerY) - 20; // »ù´¡°ë¾¶£¨²»Ëõ·Å£© int maxRadius = (int) (baseRadius * scaleFactor); // Ëõ·ÅºóµÄ°ë¾¶ // ÉèÖñ³¾°ÑÕÉ« g2d.setColor(new Color(240, 240, 240)); g2d.fillRect(0, 0, getWidth(), getHeight()); // ÔÚ×óϽǻæÖÆÍ¼Æ¬ if (logoImage != null) { int imgWidth = logoImage.getWidth(this); int imgHeight = logoImage.getHeight(this); // µ÷ÕûͼƬ´óС£¬Ê¹ÆäÊʺÏÃæ°å int scaledWidth =150; // ÉèÖÃͼƬ¿í¶È int scaledHeight = (int) (imgHeight * (scaledWidth * 1.0 / imgWidth)); // °´±ÈÀý¼ÆËã¸ß¶È g2d.drawImage(logoImage, 5, getHeight() - scaledHeight - 5, scaledWidth, scaledHeight, this); } // »æÖÆ×ø±êÖá g2d.setColor(Color.LIGHT_GRAY); g2d.drawLine(centerX, 0, centerX, getHeight()); g2d.drawLine(0, centerY, getWidth(), centerY); // »æÖƽǶȿ̶ÈÏß (-180¡ã µ½ 180¡ã) g2d.setColor(new Color(150, 150, 150)); for (int i = -180; i <= 180; i += 30) { // ת»»ÎªÊýÑ§×ø±êϵµÄ½Ç¶È£¨´ÓÕý¶«·½Ïò¿ªÊ¼£¬ÄæÊ±ÕëΪÕý£© double mathAngle = 90 - i; // µ¼º½½Ç¶Èת»»ÎªÊýѧ½Ç¶È if (mathAngle < 0) mathAngle += 360; double rad = Math.toRadians(mathAngle); int x1 = centerX + (int) (maxRadius * Math.cos(rad)); int y1 = centerY - (int) (maxRadius * Math.sin(rad)); g2d.setColor(new Color(100, 100, 100)); g2d.drawLine(centerX, centerY, x1, y1); // »æÖƽǶȱêÇ© if (i == -180) { continue; } int labelX = centerX + (int) ((maxRadius + 15) * Math.cos(rad)); int labelY = centerY - (int) ((maxRadius + 15) * Math.sin(rad)); g2d.setColor(Color.blue); g2d.drawString(i + "¡ã", labelX - 10, labelY + 5); } // »æÖƾàÀëԲȦºÍ±êÇ© g2d.setColor(new Color(100, 100, 100)); for (int i = 1; i <= 5; i++) { int radius = maxRadius * i / 5; g2d.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2); // Ð޸ģº¾àÀë±êÇ©²»ËæËõ·Å±ä»¯£¬±£³Öʵ¼Ê¾àÀë String distanceLabel = i * 200 + "cm"; int labelWidth = g2d.getFontMetrics().stringWidth(distanceLabel); g2d.drawString(distanceLabel, centerX - labelWidth / 2, centerY + radius + 15); } // »æÖÆAµã£¨Ãªµã£© g2d.setColor(Color.BLACK); g2d.fillOval(centerX - 5, centerY - 5, 10, 10); // AµãÕýÉÏ·½ÏÔʾÉ豸±àºÅ g2d.setFont(titleFont); g2d.drawString(anchorid, centerX - g2d.getFontMetrics().stringWidth(anchorid)/2, centerY - 15); g2d.setFont(normalFont); // »æÖÆBµã£¨±êÇ©µã£© if (distance > 0) { // ¸ù¾Ý¾àÀë¼ÆËãËõ·Å±ÈÀý£¨×î´ó1000ÀåÃ×£© double scaledDistance = Math.min(distance, 1000) * maxRadius / 1000.0; // ½«µ¼º½½Ç¶Èת»»ÎªÊýѧ½Ç¶È£¨´ÓÕý¶«·½Ïò¿ªÊ¼£¬ÄæÊ±ÕëΪÕý£© double mathAngle = 90 - angle; // µ¼º½½Ç¶Èת»»ÎªÊýѧ½Ç¶È if (mathAngle < 0) mathAngle += 360; double rad = Math.toRadians(mathAngle); int bX = centerX + (int) (scaledDistance * Math.cos(rad)); int bY = centerY - (int) (scaledDistance * Math.sin(rad)); // »æÖÆÁ¬½ÓÏß g2d.setColor(new Color(0, 100, 200, 150)); g2d.drawLine(centerX, centerY, bX, bY); // BµãÕýÏ·½ÏÔʾ¾àÀëºÍ½Ç¶ÈÐÅÏ¢ String distanceText = distance + "cm"; String angleText = angle + "¡ã"; // ÉèÖüӴÖ×ÖÌåºÍ¼Ó´ó×ֺŠg2d.setFont(boldFont); g2d.setColor(Color.RED); // ÔÚÃæ°åµ×²¿ÏÔʾ¾àÀëºÍ½Ç¶ÈÐÅÏ¢ - ʵʱ»ñÈ¡×Ö·û´®£¬²»Ê¹Óûº´æ g2d.setFont(boldFont); // Ö±½Ó´Ó¸¸¿ò¼Ü»ñÈ¡µ±Ç°ÓïÑÔµÄ×Ö·û´® g2d.drawString(parentFrame.getString("distance") + distance + "cm", 10, 40); g2d.drawString(parentFrame.getString("angle") + angle + "¡ã", 10, 70); // ÐÂÔö£ºÏÔʾÐźÅÖÊÁ¿ g2d.drawString(parentFrame.getString("signal") + signalQuality, 10, 100); g2d.setFont(normalFont); g2d.setColor(Color.BLUE); g2d.fillOval(bX -10, bY -10, 20, 20); // BµãÕýÉÏ·½ÏÔʾÉ豸±àºÅ g2d.setFont(titleFont); g2d.setColor(Color.BLUE); g2d.drawString(tagid, bX - g2d.getFontMetrics().stringWidth(tagid)/2, bY - 25); g2d.setFont(normalFont); // ¼ÆËãÎı¾Î»Öã¨BµãÕýÏ·½£© int textY = bY + 25; g2d.setColor(Color.BLUE); g2d.drawString(distanceText, bX - g2d.getFontMetrics().stringWidth(distanceText)/2, textY); g2d.drawString(angleText, bX - g2d.getFontMetrics().stringWidth(angleText)/2, textY + 20); g2d.setFont(normalFont); } // ÏÔʾµ±Ç°Ëõ·Å±ÈÀý g2d.setColor(Color.DARK_GRAY); g2d.drawString(String.format("%s: %.1fx", parentFrame.getString("scale"), scaleFactor), getWidth() - 80, 20); } public void updateLanguage() { setBorder(BorderFactory.createTitledBorder(parentFrame.getString("visualization"))); // ÒÆ³ý×Ö·û´®»º´æ£¬¸ÄΪÔÚpaintComponentÖÐʵʱ»ñÈ¡ repaint(); } }