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

时间:2012-04-18 13:30:02

标签: java swing jpanel

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

enter image description here

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

拖动鼠标时如何在Jpanel上绘制线条? 顺便说一句,由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);   

                         }
                });
   }   

}

2 个答案:

答案 0 :(得分:4)

  

..画2行

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

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

BTW - 我猜测你在测试时没有最小化并恢复你的窗口。你的线条(漂亮或丑陋)会消失!


  他们消失了。是什么原因?

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

保留这些行的选项包括:

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

  

..线不是直线。

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

答案 1 :(得分:1)

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

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