2012-04-18 59 views
2

我想在鼠标拖动时在JPanel上绘制2(或更多)行。当我在我的代码使用super.paintComponent(g) ,我不能得出2号线在面板上,但是当我不使用super.paintComponent(g);,其结果是丑陋的,如下面的图:拖动鼠标时在Jpanel上绘制线条

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); 

         } 
       }); 
    } 

}

回答

4

..draw 2行

这似乎是这个问题的症结所在。

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

顺便说一句 - 我猜你没有最小化和恢复你的窗口,而测试这个。你的线条(美丽或丑陋)会消失!


..they消失。什么原因?

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

保留线的选项包括:

  • 商店的路线的位置和重新绘制它们全部每当问(如上所述)。这可以用于大多数目的。即使有数百行代码,GUI也会在“眨眼之间”重新绘制它们。
  • 将每一行绘制到BufferedImage,并将图像放在(ImageIcon)中的一个JLabel。如果绘图区域具有固定的大小,则此方法可以很好地工作。&任何东西都不会被移除,并且可以容纳数百万行,弧线,半透明区域,较小的图像,文本。使用图像作为渲染表面,您将不再需要ArrayList,因为您所做的只是为图像添加一条新线条,并重新绘制标签以查看新线条和所有以前的线条。

..the线不是直线。

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

+0

你说得对,他们消失了。什么原因? – 2012-04-18 13:43:32

+0

谢谢。顺便说一句,paintComponent绘制的线 - 有时不是平滑线。我怎样才能摆脱这一点? – 2012-04-18 14:24:25

+0

我编辑了这个问题,所以你可以在图片上看到 - 这条线不是直线。我的意思是一些线条,而不是全部线条。 – 2012-04-18 14:34:58

1

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

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

我不想绘制连续的线,我想要分离线。 – 2012-04-18 13:42:44