package dell_Fence; 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.Point; import java.awt.RenderingHints; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.geom.Point2D; import java.util.Vector; import javax.swing.ImageIcon; import javax.swing.JPanel; import targets.Mapdata; public class MapCanvas extends JPanel { private static final long serialVersionUID = 1L; private final FenceDrawerFrame parentFrame; private Mapdata mapData; private Image mapImage; private double scale = 1.0; private int offsetX = 0; private int offsetY = 0; private Point dragOrigin; private boolean isDrawingMode = false; private Point2D.Double currentMousePointInMap = new Point2D.Double(0, 0); private Point currentMouseScreenPoint = new Point(0, 0); private boolean isDragging = false; public MapCanvas(FenceDrawerFrame parentFrame, Mapdata mapData) { this.parentFrame = parentFrame; this.mapData = mapData; loadMapImage(); setPreferredSize(new Dimension(800, 500)); initEventHandlers(); } private void initEventHandlers() { addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { handleMousePress(e); } @Override public void mouseReleased(MouseEvent e) { isDragging = false; } // Ìí¼ÓË«»÷ʼþ´¦Àí @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { // Ë«»÷ʼþ handleDoubleClick(e); } } }); addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { handleMouseDrag(e); } @Override public void mouseMoved(MouseEvent e) { handleMouseMove(e); } }); addMouseWheelListener(this::handleMouseWheel); addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { centerMap(); } }); } // ´¦ÀíË«»÷ʼþ private void handleDoubleClick(MouseEvent e) { if (isDrawingMode && parentFrame.isDrawing) { int currentShape = parentFrame.currentShape; Vector drawingPoints = parentFrame.drawingPoints; // ¶à±ßÐλò¶à¶ÎÏßË«»÷Íê³É»æÖÆ if (currentShape == 0 || currentShape == 1) { // ¶à±ßÐÎÐèÒªÖÁÉÙ3¸öµã£¬¶à¶ÎÏßÖÁÉÙ2¸öµã if ((currentShape == 0 && drawingPoints.size() >= 3) || (currentShape == 1 && drawingPoints.size() >= 2)) { // ´¥·¢Íê³É»æÖÆ parentFrame.finishDrawing(); } } } } private void handleMousePress(MouseEvent e) { if (isDrawingMode && parentFrame.isDrawing) { int currentShape = parentFrame.currentShape; Vector drawingPoints = parentFrame.drawingPoints; // ¾ØÐÎ/Ô²ÐÎÌØÊâ´¦Àí£¨Ö»ÐèÒª2¸öµã£© if (currentShape == 2 || currentShape == 3) { if (drawingPoints.size() == 0) { Point2D.Double mapPoint = screenToMap(e.getPoint()); drawingPoints.add(mapPoint); repaint(); return; } else if (drawingPoints.size() == 1) { Point2D.Double mapPoint = screenToMap(e.getPoint()); drawingPoints.add(mapPoint); repaint(); parentFrame.finishDrawing(); return; } } // ¶à±ßÐκͶà¶ÎÏß´¦Àí£¨Ìí¼Óµã£© if (currentShape == 0 || currentShape == 1) { Point2D.Double mapPoint = screenToMap(e.getPoint()); drawingPoints.add(mapPoint); repaint(); } } else { dragOrigin = e.getPoint(); isDragging = true; } } private void handleMouseDrag(MouseEvent e) { if (isDragging && !isDrawingMode) { Point current = e.getPoint(); offsetX += current.x - dragOrigin.x; offsetY += current.y - dragOrigin.y; dragOrigin = current; repaint(); } } private void handleMouseMove(MouseEvent e) { currentMouseScreenPoint = e.getPoint(); currentMousePointInMap = screenToMap(currentMouseScreenPoint); updateCoordLabel(); repaint(); } private void handleMouseWheel(MouseWheelEvent e) { int rotation = e.getWheelRotation(); double zoomFactor = 1.1; double mapX = (e.getX() - offsetX) / scale; double mapY = (e.getY() - offsetY) / scale; if (rotation < 0 && scale < 5.0) { scale *= zoomFactor; } else if (rotation > 0 && scale > 0.2) { scale /= zoomFactor; } else { return; } offsetX = (int) (e.getX() - mapX * scale); offsetY = (int) (e.getY() - mapY * scale); repaint(); } // ¾ÓÖеØÍ¼ private void centerMap() { if (mapImage == null) return; int panelWidth = getWidth(); int panelHeight = getHeight(); int imgWidth = (int)(mapImage.getWidth(null) * scale); int imgHeight = (int)(mapImage.getHeight(null) * scale); offsetX = (panelWidth - imgWidth) / 2; offsetY = (panelHeight - imgHeight) / 2; repaint(); } // ÆÁÄ»×ø±êתµØÍ¼×ø±ê private Point2D.Double screenToMap(Point screenPoint) { return new Point2D.Double( (screenPoint.x - offsetX) / scale, (screenPoint.y - offsetY) / scale ); } // µØÍ¼×ø±êתÆÁÄ»×ø±ê private Point mapToScreen(Point2D.Double mapPoint) { return new Point( (int) (mapPoint.x * scale + offsetX), (int) (mapPoint.y * scale + offsetY) ); } private void loadMapImage() { String imagePath = "systemfile/imagemap/" + mapData.getMapNameDetaile(); mapImage = new ImageIcon(imagePath).getImage(); } public void setDrawingMode(boolean drawingMode) { isDrawingMode = drawingMode; } public void setDrawingPoints(Vector points) { // ÉèÖûæÖƵ㼯ºÏ } private void updateCoordLabel() { parentFrame.getCoordLabel().setText(String.format("X: %.2f, Y: %.2f", currentMousePointInMap.x, currentMousePointInMap.y)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // »æÖƵØÍ¼ if (mapImage != null) { int width = (int) (mapImage.getWidth(null) * scale); int height = (int) (mapImage.getHeight(null) * scale); g2d.drawImage(mapImage, offsetX, offsetY, width, height, this); } // »æÖÆÐÎ×´ drawShapes(g2d); // »æÖÆ×´Ì¬ÐÅÏ¢ drawStatusInfo(g2d); } private void drawShapes(Graphics2D g2d) { Vector drawingPoints = parentFrame.drawingPoints; int currentShape = parentFrame.currentShape; boolean isDrawing = parentFrame.isDrawing; // »æÖÆÒѱ£´æµÄµã if (!drawingPoints.isEmpty()) { g2d.setColor(Color.RED); for (Point2D.Double mapPoint : drawingPoints) { Point screenPoint = mapToScreen(mapPoint); g2d.fillOval(screenPoint.x - 5, screenPoint.y - 5, 10, 10); // ÔÚµãÅÔ±ßÏÔÊ¾×ø±ê (X, Y) String coordText = String.format("(%.0f, %.0f)", mapPoint.x, mapPoint.y); g2d.setColor(Color.BLACK); g2d.drawString(coordText, screenPoint.x + 8, screenPoint.y - 8); g2d.setColor(Color.RED); } if (currentShape == 0) { // ¶à±ßÐÎ if (drawingPoints.size() > 1) { Point prev = mapToScreen(drawingPoints.get(0)); for (int i = 1; i < drawingPoints.size(); i++) { Point current = mapToScreen(drawingPoints.get(i)); g2d.drawLine(prev.x, prev.y, current.x, current.y); prev = current; } // ¶à±ßÐÎ±ÕºÏ if (drawingPoints.size() > 2) { Point first = mapToScreen(drawingPoints.get(0)); Point last = mapToScreen(drawingPoints.get(drawingPoints.size()-1)); g2d.drawLine(last.x, last.y, first.x, first.y); } } } // ÐÂÔö£º¶à¶ÎÏß»æÖÆÂß¼­ else if (currentShape == 1) { if (drawingPoints.size() > 1) { Point prev = mapToScreen(drawingPoints.get(0)); for (int i = 1; i < drawingPoints.size(); i++) { Point current = mapToScreen(drawingPoints.get(i)); g2d.drawLine(prev.x, prev.y, current.x, current.y); prev = current; } } } else if (currentShape == 2 && drawingPoints.size() == 2) { // ¾ØÐÎ Point p1 = mapToScreen(drawingPoints.get(0)); Point p2 = mapToScreen(drawingPoints.get(1)); int x = Math.min(p1.x, p2.x); int y = Math.min(p1.y, p2.y); int width = Math.abs(p1.x - p2.x); int height = Math.abs(p1.y - p2.y); g2d.drawRect(x, y, width, height); } else if (currentShape == 3 && drawingPoints.size() == 2) { // Ô²ÐÎ Point center = mapToScreen(drawingPoints.get(0)); Point edge = mapToScreen(drawingPoints.get(1)); int radius = (int) center.distance(edge); g2d.drawOval(center.x - radius, center.y - radius, 2 * radius, 2 * radius); } } // »æÖƶ¯Ì¬¸¨ÖúÏß if (isDrawing && isDrawingMode) { g2d.setColor(Color.BLUE); if (currentShape == 0) { // ¶à±ßÐθ¨ÖúÏß if (!drawingPoints.isEmpty()) { Point lastPoint = mapToScreen(drawingPoints.lastElement()); g2d.drawLine(lastPoint.x, lastPoint.y, currentMouseScreenPoint.x, currentMouseScreenPoint.y); } } // ÐÂÔö£º¶à¶ÎÏ߸¨ÖúÏß else if (currentShape == 1) { if (!drawingPoints.isEmpty()) { Point lastPoint = mapToScreen(drawingPoints.lastElement()); g2d.drawLine(lastPoint.x, lastPoint.y, currentMouseScreenPoint.x, currentMouseScreenPoint.y); } } else if (currentShape == 2) { // ¾ØÐθ¨ÖúÏß if (!drawingPoints.isEmpty()) { Point startPoint = mapToScreen(drawingPoints.get(0)); int x = Math.min(startPoint.x, currentMouseScreenPoint.x); int y = Math.min(startPoint.y, currentMouseScreenPoint.y); int width = Math.abs(startPoint.x - currentMouseScreenPoint.x); int height = Math.abs(startPoint.y - currentMouseScreenPoint.y); g2d.drawRect(x, y, width, height); g2d.setColor(new Color(0, 255, 0, 150)); g2d.drawLine(startPoint.x, startPoint.y, currentMouseScreenPoint.x, currentMouseScreenPoint.y); } } else if (currentShape == 3) { // Ô²Ðθ¨ÖúÏß if (!drawingPoints.isEmpty()) { Point startPoint = mapToScreen(drawingPoints.get(0)); double dx = startPoint.x - currentMouseScreenPoint.x; double dy = startPoint.y - currentMouseScreenPoint.y; int radius = (int) Math.sqrt(dx * dx + dy * dy); g2d.drawOval(startPoint.x - radius, startPoint.y - radius, 2 * radius, 2 * radius); g2d.setColor(new Color(0, 255, 0, 150)); g2d.drawLine(startPoint.x, startPoint.y, currentMouseScreenPoint.x, currentMouseScreenPoint.y); } } } } private void drawStatusInfo(Graphics2D g2d) { int panelHeight = getHeight(); g2d.setColor(Color.BLACK); g2d.setFont(new Font("Arial", Font.BOLD, 14)); // »æÖƱÈÀý³ß String scaleText = String.format(parentFrame.getMessage("SCALE") + ": %.1f", scale); g2d.drawString(scaleText, 20, panelHeight - 20); // »æÖÆ»æÖÆ×´Ì¬ if (isDrawingMode) { g2d.setColor(Color.BLUE); g2d.drawString(parentFrame.getMessage("DRAWING_STATUS"), 20, panelHeight - 40); // ÐÂÔö£ºÏÔʾ˫»÷Íê³ÉÌáʾ int currentShape = parentFrame.currentShape; if (parentFrame.isDrawing && (currentShape == 0 || currentShape == 1)) { g2d.drawString(parentFrame.getMessage("DOUBLE_CLICK_TO_FINISH"), 20, panelHeight - 60); } } } }