java - 拖动鼠标在JPanel上画线

标签 java swing jpanel

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

enter image description here

我明白为什么这些线路会这样。

如何在面板上拖动鼠标时绘制线条?

顺便说一句,g2d.draw(line2d)绘制的线有时不是平滑的线(下图)

enter image description here

到目前为止我的代码:

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 lines

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

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

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

<小时/>

..they disappeared. What's the reason?

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

保留行的选项包括:

  • 存储线条的位置,并在需要时重新绘制所有线条(如上所述)。这适用于大多数目的。即使有数百条线,GUI 也会在“眨眼间”重新绘制它们。
  • 将每条线绘制到 BufferedImage 中,并将图像放入 JLabel(ImageIcon 中)中。如果绘图区域的大小固定并且没有任何内容被删除,并且可以容纳数百万条直线、弧线、半透明区域、较小的图像、文本,则这种方法效果很好。使用图像作为渲染表面,您可以将不再需要ArrayList,因为您所做的就是向图像添加新行,然后重新绘制标签以查看新行和所有先前的行。
<小时/>

..the line is not the straight line.

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

关于java - 拖动鼠标在JPanel上画线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10210437/

相关文章:

java - Eclipse热键-快捷方式修改?我的意思是实际的热键命令,而不是键绑定(bind)

java - 对于这个设计,哪个是更好的顶级容器,JFrame with Jpanels,或者 JDesktop with JInternalFrames

java - JFrame 和 JPanel 分离有问题吗?

java Swing : how to keep one component left aligned with another component centered with respect to parent

Java 第二个框架不显示

java - 在Java中发送TAB控制字符

Swing 框架上的 javafx 警报对话框

java - 这是在 Java 中错误使用内部条件队列吗?

Java Processing Scheduler Simulator 动画推荐?

java - JPanel 重新验证和重绘无法正常工作 (Java Swing)