【问题标题】:Draw Line While Dragging The Mouse拖动鼠标时画线
【发布时间】:2019-04-06 19:43:55
【问题描述】:

我想做的是画圆和线。

当第一次按下鼠标时,我画了一个小圆圈。那么,我需要 画一条线将原点连接到当前点 鼠标的位置。松开鼠标时,线条 仍然存在,但是当我再次单击时,一切都消失了,我画了一个 又是一圈又是一条线。

这是我目前的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;    

public class Canvas4 extends JComponent implements MouseListener, MouseMotionListener {

    //constructor
    public Canvas4() {
        super();
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    //some variables I may or may not use
        int pressedX;
        int pressedY;
        int currentX;
        int currentY;
        int startDragX;
        int startDragY;
        int endDragX;
        int endDragY;
        int mouseReleasedX;
        int mouseReleasedY;



    //mouse events
    public void mouseClicked(MouseEvent event)  {  }

    public void mouseEntered(MouseEvent event)  {  }

    public void mouseExited(MouseEvent event)   {  }

    public void mousePressed(MouseEvent event)  {  
        pressedX = event.getX();
        pressedY = event.getY(); 
        drawCircle();

        startDragX = pressedX;
        startDragY = pressedY;
    }

    public void mouseReleased(MouseEvent event) {  
        mouseReleasedX = event.getX();
        mouseReleasedY = event.getY();
        //repaint() here maybe???
    }



    //mouse motion events
    public void mouseDragged(MouseEvent event) {
        System.out.println("You dragged the mouse.");
        endDragX = event.getX();
        endDragY = event.getY();
        drawLine();

    }

    public void mouseMoved(MouseEvent event) {  }



    //draw circle when mouse pressed
    //this method works fine
    public void drawCircle()    {
        Graphics g1 = this.getGraphics();
        g1.setColor(Color.CYAN);
        g1.fillOval(pressedX, pressedY, 10, 10);    
    }

    //draw line when mouse dragged
    //this is where I need help
    public void drawLine()  {
        Graphics g2 = this.getGraphics();
        g2.setColor(Color.RED);
        g2.drawLine(pressedX, pressedY, mouseReleasedX, mouseReleasedY);
    }
}

当然,还有一个创建类对象并将其添加到框架之类的 main 方法。

我的两个具体问题是:

  1. 如何在拖动时画一条线?我目前的代码只画了一条线到鼠标释放的最后一点。
  2. 何时重绘?如果我在 drawCircle() 方法中重新绘制,圆圈会闪烁,而不是在下次单击时消失。

【问题讨论】:

  • 1) “我的两个具体问题是:” 每个 SO 问题线程都应该有确切的 一个 个具体问题。这有助于人们稍后寻找解决方案,帮助人们尝试回答问题和您。 2)“那当然有main方法”为了尽快获得更好的帮助,请发帖minimal reproducible example或Short, Self Contained, Correct Example。可能会提供帮助的人不必编写 main 方法来将代码显示在屏幕上。我们大多数人都有更好的事情要做,或者有人可以帮助他们这样做,因为这样做很容易帮助。

标签: java swing graphics mouselistener mousemotionlistener


【解决方案1】:

如果你想画圆和线,那么你需要保持一个 ArrayList 的 Shapes 来绘制。您可以为圆圈添加Ellipse2D.Double,为线条添加Line2D.Double。

在mousePressed 事件中,您将Ellipse2D.Double 对象添加到ArrayList,然后设置一个临时Line2D.Double 对象来包含您的行信息。

在mouseDragged 事件中,您使用新的端点更新Line2D.Double 对象,然后调用repaint()。

在mouseReleased 事件中,将Line2D.Double 对象添加到ArrayList 并清除引用Line2D.Double 对象的变量。

然后在 paintComponent() 方法中添加逻辑:

  1. 遍历ArrayList 以绘制每个Shape。
  2. 在不为空时绘制Line2D.Double 对象

查看Custom Painting Approaches 中的Draw On Component 示例。这将向您展示这种方法的基本概念。

在示例中,ArrayList 仅包含有关 Rectangles 的信息,因此您需要使其更通用以保存 Shape 对象。 Ellispse2D.Double 和 Line2D.Double 都实现了 Shape 接口。

【讨论】:

    【解决方案2】:

    画线我有这个。当你点击鼠标向左你会保留一个点下次点击会保留另一个点 在它们之间画一条线,然后用鼠标右键在first点和之间画一条线 strong>最后点(如果你不想要,你可以删除这个“if (isClosed)”)

    另一件事:它不是一个很好的精度,因为点定位返回一个双精度值,而绘制线需要一个整数,而 cast 会失去精度。

    public class PolygonOnClick extends JPanel implements MouseListener, MouseMotionListener {
    ArrayList<Point> points = new ArrayList<>();
    static boolean isClosed = false;
    
    PolygonOnClick() {
        JFrame frame = new JFrame("Polygon ON CLICK");
        frame.addMouseListener(this);
        frame.setLocation(80, 50);
        frame.setSize(1000, 700);
        frame.add(this);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
    
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        graphics.drawString("Click stanga pentru a incepe a desena , click dreapta pentru a inchide poligonul ", 15, 15);
    
        for (int i = 1; i < points.size(); i++) {
            graphics.drawLine((int) points.get(i - 1).getX(), (int) points.get(i - 1).getY(), (int) points.get(i).getX(), (int) points.get(i).getY());
        }
        if (isClosed) {
            graphics.drawLine((int) points.get(points.size() - 1).getX(), (int) points.get(points.size() - 1).getY(), (int) points.get(0).getX(), (int) points.get(0).getY());
        }
    }
    
    @Override
    public void mousePressed(MouseEvent e) {
        if (!isClosed) {
            if (e.getButton() == MouseEvent.BUTTON1) {
                points.add(e.getPoint().getLocation());
            }
        }
        if (e.getButton() == MouseEvent.BUTTON3) {
            isClosed = true;
        }
        repaint();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 2011-01-18
      相关资源
      最近更新 更多