1

我正在构建一个可以识别用鼠标绘制的线条并创建音乐的应用程序。我是 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 对其进行了修改,它可以正常绘图,现在唯一不起作用的是 clear 方法,我尝试了不同的方法,但都没有奏效。我的新代码如下:

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

 }
4

1 回答 1

3

一些解决方案和建议:

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

例如,请在此处查看我的代码和答案。

于 2013-02-24T16:30:03.503 回答