拖动鼠标时在Jpanel上绘制线条

我想在鼠标拖动时在JPanel上绘制2行(或更多行)。 当我在我的代码中使用super.paintComponent(g)时,我无法在面板上绘制2条线,但是当我不使用super.paintComponent(g) ;时,结果很难看,如下图:

在此处输入图像描述

我理解为什么线条表现得那样。

拖动鼠标时如何在Jpanel上绘制线条? 顺便说一句, g2d.draw(line2d)绘制的线有时不是平滑线(下图)

在此处输入图像描述

我的代码到目前为止:

 import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Line2D; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; public class LineDrawing extends JPanel implements MouseMotionListener, MouseListener{ Point point1; Point point2; Line2D line2d; public LineDrawing(){ super(); addMouseListener(this); addMouseMotionListener(this); } @Override public void paintComponent(Graphics g){ //super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; if(point1!=null && point2!=null){ g2d.setPaint(Color.RED); g2d.setStroke(new BasicStroke(1.5f)); g2d.draw(line2d); } } @Override public void mouseDragged(MouseEvent e) { point2 = e.getPoint(); line2d = new Line2D.Double(point1, point2); repaint(); } @Override public void mouseMoved(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { point1 = e.getPoint(); } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } public static void main(String a[]){ EventQueue.invokeLater(new Runnable(){ @Override public void run() { JFrame frame = new JFrame(); LineDrawing linedraw= new LineDrawing(); frame.add(linedraw); frame.setSize(500,500); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } }); } 

}

..draw 2行

这似乎是这个问题的关键问题。

单击/拖动时,在可扩展列表(例如ArrayList )中保留一组行,向列表中添加一行并调用repaint() 。 在paintComponent(Graphics) ,迭代集合并绘制每一行。

顺便说一句 – 我猜你在测试时没有最小化并恢复你的窗口。 你的线条(美丽或丑陋)会消失!


他们消失了。 什么原因?

每当GUI需要重绘时,都会调用paint()paintComponent()方法。 在应用程序前面出现另一个窗口后,可能会调用它们,然后将它带回到前面。 另一个时间是从最小化恢复后。

保留这些行的选项包括:

  • 存储行的位置并在需要时重绘所有行(如上所述)。 这可以用于大多数目的。 即使有数百行,GUI也会在“眨眼间”重绘它们。
  • 将每一行绘制到BufferedImage并将图像放入(一个ImageIconJLabel 。 如果绘图区域具有固定大小且没有任何东西被移除,这种方法很有效,并且可以容纳数百万行,弧形,半透明区域,较小图像,文本。使用图像作为渲染表面,将不再需要ArrayList ,因为您所做的只是向图像添加一个新行,并重新绘制标签以查看新行和所有之前的行。

..线不是直线。

这是因为绘制线条时使用了“渲染提示”。 由对齐的像素行组成的屏幕只能完美地形成垂直或水平线。 为了给出任何其他角度的直线和连续线的“幻觉”,需要一种称为抖动的技术。 阅读Graphics2D的开头部分,了解RenderingHints更多说明和描述。

我不知道我得到你的问题,但如果你想画一条连续线。 拖动时你必须更新你的最后一个点。

 @Override public void mouseDragged(MouseEvent e) { point2 = e.getPoint(); line2d = new Line2D.Double(point1, point2); point1 = point2; // add this line repaint(); }