自由线绘图java2d应用程序连接每个新绘图的行

时间:2013-02-24 16:26:48

标签: java swing drawing graphics2d paintcomponent

我正在构建一个应用程序来识别用鼠标绘制的线条并创建音乐。我是java2d的新手,所以我遇到了问题:

  • 绘制然后再绘制另一个绘图时,上一个绘图的最后一个点连接到新绘图的第一个点。我还没弄清楚如何解决这个问题。以下是代码。

  • 另一个问题是:我想将绘图的每个笔画(从mousePressed到mouseReleased)存储到Shape类型的ArrayList中,我该如何进入?

我想指出正确的方向,因为我无法在线找到有用的信息。谢谢!

public class DrawBoard extends JPanel implements MouseListener,
        MouseMotionListener {

    public JLabel status;
    public Point pstart, pfinish;
    private Shape currentShape = null;
    private ArrayList<Point> points = new ArrayList<Point>();
    private ArrayList<Shape> lines = new ArrayList<Shape>();

    public DrawBoard() {

        Dimension size = getPreferredSize();
        size.setSize(1024, 800); // w, h
        setPreferredSize(size);
        setOpaque(false);
        status = new JLabel("default");
        add(status, BorderLayout.SOUTH);

        addMouseListener(this);
        addMouseMotionListener(this);

    }

    @Override
    public void mouseClicked(MouseEvent e) {
        status.setText(String.format("Clicked at %d,%d", e.getX(), e.getY()));
    }

    // Where the drawing happens
    @Override
    public void mousePressed(MouseEvent e) {
        status.setText("you pressed down the mouse");
        this.pstart = e.getPoint();

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        status.setText("you draged the mouse");
        points.add(e.getPoint());
        repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        status.setText("you release the mouse click");
        pfinish = e.getPoint();
    }

    // End of where the drawing happens

    @Override
    public void mouseEntered(MouseEvent e) {
        status.setText("you entered the area");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        status.setText("mouse exited the area");
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        // throw new UnsupportedOperationException("Not supported yet.");
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLACK);
        g2.setStroke(new BasicStroke(5));

        for (int i = 0; i < points.size() - 2; i++) {

            Point p1 = points.get(i);
            Point p2 = points.get(i + 1);

            g2.drawLine(p1.x, p1.y, p2.x, p2.y);
        }

    }
}

我使用BufferedImage对其进行了修改,它可以正常绘制,现在唯一可行的是清晰的方法,我尝试了不同的方法,但没有一个有效。我的新代码如下:

  public class DrawBoard extends JPanel implements MouseListener, MouseMotionListener{


public JLabel status;
private JLabel imgLabel;
public Point pstart, pfinish;
private Shape currentShape = null;
private List<Point> points = new ArrayList<Point>();
private List<BufferedImage> lines = new ArrayList<BufferedImage>();

private static final int BI_WIDTH = 1024;
private static final int BI_HEIGHT = 800;

private BufferedImage bImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
        BufferedImage.TYPE_INT_ARGB);

public DrawBoard(){  

   Graphics2D g2d = bImage.createGraphics();
   g2d.dispose();

    Dimension size = getPreferredSize();
    size.setSize(1024,800); //w, h
    setPreferredSize(size);
    status =  new JLabel("default");
    add(status, BorderLayout.SOUTH);
    addMouseListener(this);
    addMouseMotionListener(this);  


     imgLabel = new JLabel(new ImageIcon(bImage)) {
     @Override
     protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        paintInLabel(g);
     }
  };
     imgLabel.setOpaque(false);
     setOpaque(false);
      add(imgLabel, BorderLayout.CENTER);

}

private void paintInLabel(Graphics g) {
  Graphics2D g2d = (Graphics2D) g;
  g2d.setColor(Color.BLUE); // this colour is when mouse is pressed
  g2d.setStroke(new BasicStroke(5));
  if (points.size() < 2) {
     return;
  }
  for (int i = 1; i < points.size(); i++) {
     int x1 = points.get(i - 1).x;
     int y1 = points.get(i - 1).y;
     int x2 = points.get(i).x;
     int y2 = points.get(i).y;
     g2d.drawLine(x1, y1, x2, y2);
  }
 }



@Override
public void mouseClicked(MouseEvent e) {
    status.setText(String.format("Clicked at %d,%d", e.getX(), e.getY()));
}


// Where the drawing happens
@Override
public void mousePressed(MouseEvent e) {
    status.setText("you pressed down the mouse");
    this.pstart = e.getPoint();
    points.add(e.getPoint());

}

@Override
public void mouseDragged(MouseEvent e) {
  status.setText("you draged the mouse");
  points.add(e.getPoint());
  imgLabel.repaint();
}

@Override
public void mouseReleased(MouseEvent e) {
    status.setText("you release the mouse click");
    Graphics2D g2d = bImage.createGraphics();
    g2d.setColor(Color.blue); // this is the final colour
    g2d.setStroke(new BasicStroke(5));

     if (points.size() >= 2) {
        for (int i = 1; i < points.size(); i++) {
           int x1 = points.get(i - 1).x;
           int y1 = points.get(i - 1).y;
           int x2 = points.get(i).x;
           int y2 = points.get(i).y;
           g2d.drawLine(x1, y1, x2, y2);
        }
     }
     g2d.dispose();

     points.clear();
     imgLabel.repaint();

}
// End of where the drawing happens

@Override
public void mouseEntered(MouseEvent e) {
   status.setText("you entered the area");
}


@Override
public void mouseExited(MouseEvent e) {
   status.setText("mouse exited the area");
}

@Override
public void mouseMoved(MouseEvent e) {
    //throw new UnsupportedOperationException("Not supported yet.");
}

public void clearDrawBoard() {

    imgLabel.setIcon(null);
}

 }

1 个答案:

答案 0 :(得分:3)

一些解决方案和建议:

  • 不要从单个List<Point>中抽取,因为无法知道一行结束而另一行开始。
  • 考虑完成后将每一行绘制到BufferedImage,并在其paintComponent方法中在JComponent中显示BufferedImage。您可以将它放在mouseReleased(...)方法的BufferedImage中。
  • 或考虑创建List<List<Point>>,以便您可以根据需要迭代每一行。您可以使用List<Point>方法将新mouseReleased(...)添加到原始列表。
  • 考虑使用List<Shape>并将其填充为可绘制的Line2D对象。 Line2D将添加到List<Shape>方法中的mouseReleased(...)
  • 另外:你不应该覆盖paint(...)而是覆盖`paintComponent(...)。
  • 另外:不要忘记@Override注释以获得更安全的编码。

例如,请参阅我的代码并回答here