我想做的是画圆和直线。
第一次按下鼠标时,我画了一个小圆圈。 那我需要
画一条线将原始点连接到当前点
鼠标的位置。 释放鼠标时,该行
仍然存在,但是当我再次单击时,一切都消失了,我画了一个
再圈一圈。
这是我到目前为止的代码:
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);
}
}
然后,当然有一个主要方法可以创建类对象并将其添加到框架中。
我的两个具体问题是:
如何在拖动时画一条线? 我目前拥有的代码仅在鼠标释放的最后一点画了一条线。
我什么时候重新粉刷? 如果我使用drawCircle()方法重新绘制,则圆圈会闪烁进出,而不是在下次单击时消失。
1)"我的两个特定问题是:"每个SO问题线程都应该只有一个特定问题。 这可以帮助以后寻找解决方案的人,试图回答问题的人以及您。 2)"然后,当然有了主要方法",为了尽快获得更好的帮助,请张贴一个最小的可复制示例或简短,自包含,正确的示例。 有帮助的人不必编写主要方法即可将代码显示在屏幕上。 我们大多数人都有更好的事情要做,或者有帮助的人这样做很容易获得帮助。
如果要绘制圆和直线,则需要保留一个ArrayArray of Shapes进行绘制。您将为圆添加Ellipse2D.Double,为线添加Line2D.Double。
在mousePressed事件中,将Ellipse2D.Double对象添加到ArrayList,然后设置一个临时的Line2D.Double对象以包含您的行信息。
在mouseDragged事件中,使用新的端点更新Line2D.Double对象,然后调用repaint()。
在mouseReleased事件中,将Line2D.Double对象添加到ArrayList中,并清除引用Line2D.Double对象的变量。
然后在paintComponent()方法中将逻辑添加到:
遍历ArrayList以绘制每个Shape。
不为null时绘制Line2D.Double对象
查看"自定义绘画方法"中的Draw On Component示例。这将向您展示此方法的基本概念。
在示例中,ArrayList仅包含有关Rectangles的信息,因此您需要使其更通用以容纳Shape对象。 Ellispse2D.Double和Line2D.Double都实现Shape接口。
对于绘制线,我有这个。单击鼠标左键时保留一个点,单击鼠标左键将保留另一个点,使它们之间形成一条线,用鼠标右键单击时,您将在第一个点和最后一个点之间划一条线(可以删除此" isClosed)"(如果您不想要)
另一件事:这不是一个很好的精度,因为pointlocation返回一个double,而drawline需要一个整数,并且强制转换会失去精度。
public class PolygonOnClick extends JPanel implements MouseListener, MouseMotionListener {
ArrayList 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();
}