【问题标题】:Draw the line on the JPanel when dragging the mouse拖动鼠标时在 JPanel 上画线
【发布时间】:2012-04-18 13:30:01
【问题描述】:

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

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

拖动鼠标时如何在面板上画线?

顺便说一句,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);   

                         }
                });
   }   
}

【问题讨论】:

    标签: java swing jpanel


    【解决方案1】:

    ..画两条线

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

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

    顺便说一句 - 我猜你在测试时没有最小化和恢复你的窗口。你的台词(美或丑)会消失!


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

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

    保留行的选项包括:

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

    ..这条线不是直线。

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

    【讨论】:

    • 谢谢。顺便说一句,paintComponent 绘制的线 - 有时它不是平滑线。我怎样才能摆脱它?
    • 我编辑了这个问题,所以你可以在图片中看到 - 这条线不是直线。我的意思是一些行,而不是所有行。
    • +1 代表RenderingHints ;另见LinePanel。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-04-06
      • 1970-01-01
      • 2015-09-22
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多