1

所以我正在创建一个自由手绘 JPanel,它对鼠标移动做出反应并绘制线条。我让它大部分工作除了一个错误,它会在线条之间随机画一条直线。这条随机直线不是故意的,在缓冲图像上绘制的内容应该是用户绘制的严格内容。这些随机绘制的线条不是由用户完成的,而且令人困惑。下面是我的代码,有人可以看看吗?包含的图像为您提供了它正在做什么的视觉表示。

public class NoteDocument extends JPanel implements MouseListener, MouseMotionListener {

private Frame commands;
private JDesktopPane desktop;
private JInternalFrame colorFrame;
private JPanel colorPanel;
private JColorChooser colorChooser;

private enum State { IDLING, DRAGGING };
private enum ButtonPosition { PRESSED, RELEASED };
private enum Shape { SQUARE, RECTANGLE, CIRCLE, OVAL, LINE };

private State state = State.IDLING;
private ButtonPosition position = ButtonPosition.RELEASED;
private Shape shape = null;

//private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Point> pressedPoints = new ArrayList<Point>();
private ArrayList<Point> draggedPoints = new ArrayList<Point>();
private ArrayList<Point> releasedPoints = new ArrayList<Point>();

private BufferedImage bufferedImage = null;

public NoteDocument(Frame commands) {
    this.commands = commands;

    setBackground(Color.WHITE);
    addMouseListener(this);
    addMouseMotionListener(this);

    createColorChooser();
}

private void createColorChooser() {
    for (int i = 0; i < commands.getLayeredPane().getComponentCount(); i++) {
        if (commands.getLayeredPane().getComponent(i) instanceof JDesktopPane) {
            desktop = (JDesktopPane) commands.getLayeredPane().getComponent(i);
        }
    }

    colorChooser = new JColorChooser();
    colorPanel = new JPanel();
    colorFrame = new JInternalFrame();

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(colorPanel);
    colorPanel.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 434, javax.swing.GroupLayout.PREFERRED_SIZE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 328, javax.swing.GroupLayout.PREFERRED_SIZE)
    );

    colorFrame.add(colorPanel);
    desktop.add(colorFrame);

    colorFrame.pack();
    colorFrame.setVisible(true);
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

     Graphics2D g2 = (Graphics2D) g;
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                          RenderingHints.VALUE_ANTIALIAS_ON);

      if(bufferedImage == null)
      {
          int panelHeight = this.getHeight();
          int panelWidth = this.getWidth();
          bufferedImage = (BufferedImage) this.createImage(panelHeight, panelWidth);
          Graphics2D gc = bufferedImage.createGraphics(); 
          gc.setColor(Color.WHITE);   
          gc.fillRect(0, 0, panelWidth, panelHeight);
          g2.drawImage(bufferedImage, null, 0, 0);
      }

      //draw pressed points
      for (int a = 0; a < pressedPoints.size(); a++) {        
          Point p1 = pressedPoints.get(a);
          g.drawLine(p1.x, p1.y, p1.x, p1.y);
      }

      //draw draggedPoints        
      for (int b = 0; b < draggedPoints.size() - 2; b++) {
          Point p1 = draggedPoints.get(b);
          Point p2 = draggedPoints.get(b + 1);

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

      //draw released points
      for (int c = 0; c < releasedPoints.size(); c++) {       
          Point p1 = releasedPoints.get(c);

          g.drawLine(p1.x, p1.y, p1.x, p1.y);
      }
}

@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}

@Override
public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        position = ButtonPosition.PRESSED;
        state = State.DRAGGING;
        pressedPoints.add(e.getPoint());
        this.repaint();     
    } else if (e.getButton() == MouseEvent.BUTTON2) {
        //TODO right click popup
    }
}

@Override
public void mouseReleased(MouseEvent e) {   
    if (state == State.DRAGGING) {
        releasedPoints.add(e.getPoint());
        position = ButtonPosition.RELEASED;
        state = State.IDLING;
        this.repaint();
    }
}

@Override
public void mouseDragged(MouseEvent e) {
    if ((state == State.DRAGGING) && (position == ButtonPosition.PRESSED)) {
        draggedPoints.add(e.getPoint());
        this.repaint();
    } else if ((state == State.IDLING) && (position == ButtonPosition.RELEASED)) {
        return;
    }
}

@Override
public void mouseMoved(MouseEvent e) {
    if ((state == State.DRAGGING) && (position == ButtonPosition.PRESSED)) {
        draggedPoints.add(e.getPoint());
        this.repaint();
    } else if ((state == State.IDLING) && (position == ButtonPosition.RELEASED)) {
        return;
    }
}
}

直线是我不想要的。

4

1 回答 1

4

您可能希望嵌套列表以实现您的目标:

List<List<Point>>

这样,当鼠标按下时,启动一个 ArrayList,当释放时,完成它。然后您可以使用嵌套的 for 循环来绘制所有曲线。

例如(来自我以前的答案):

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

public class LineDrawEg {

   private static void createAndShowGui() {
      JPanel mainPanel = new JPanel(new GridLayout(1, 0));
      mainPanel.setPreferredSize(new Dimension(800, 400));

      MyMouseAdapter mouseAdapter = new MyMouseAdapter();
      JPanel[] panels = {new Panel1(), new Panel2()};
      for (int i = 0; i < panels.length; i++) {
         String title = "Panel " + (i + 1);
         Border border = new TitledBorder(title);
         panels[i].setBorder(border);
         panels[i].addMouseListener(mouseAdapter);
         panels[i].addMouseMotionListener(mouseAdapter);
         mainPanel.add(panels[i]);
      }

      JFrame frame = new JFrame("Line Draw Eg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class Panel1 extends JPanel implements Positionable {
   private int xPos = 0;
   private int yPos = 0;

   @Override
   protected void paintComponent(Graphics g) {
      // super.paintComponent(g);
      g.setColor(Color.red);
      g.fillOval(xPos, yPos, 5, 5);
   }

   @Override
   public void mouseDragged(Point p) {
      xPos = p.x;
      yPos = p.y;
      repaint();
   }

   @Override
   public void mousePressed(Point p) {
      xPos = p.x;
      yPos = p.y;
      repaint();
   }

   @Override
   public void mouseReleased(Point p) {
      xPos = p.x;
      yPos = p.y;
      repaint();
   }

}

class Panel2 extends JPanel implements Positionable {
   private List<List<Point>> listOfLists = new ArrayList<List<Point>>();
   private List<Point> currentPoints;

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setStroke(new BasicStroke(5f));
      if (currentPoints != null && currentPoints.size() > 1) {
         g2.setColor(Color.blue);
         for (int i = 1; i < currentPoints.size(); i++) {
            int x1 = currentPoints.get(i - 1).x;
            int y1 = currentPoints.get(i - 1).y;
            int x2 = currentPoints.get(i).x;
            int y2 = currentPoints.get(i).y;
            g2.drawLine(x1, y1, x2, y2);
         }
      }
      g2.setColor(Color.red);
      for (List<Point> pointList : listOfLists) {
         if (pointList.size() > 1) {
            for (int i = 1; i < pointList.size(); i++) {
               int x1 = pointList.get(i - 1).x;
               int y1 = pointList.get(i - 1).y;
               int x2 = pointList.get(i).x;
               int y2 = pointList.get(i).y;
               g2.drawLine(x1, y1, x2, y2);
            }
         }
      }
   }

   @Override
   public void mousePressed(Point p) {
      currentPoints = new ArrayList<Point>();
      currentPoints.add(p);
      repaint();
   }

   @Override
   public void mouseDragged(Point p) {
      currentPoints.add(p);
      repaint();
   }

   @Override
   public void mouseReleased(Point p) {
      if (currentPoints != null) {
         currentPoints.add(p);
         listOfLists.add(currentPoints);
      }
      currentPoints = null;
      repaint();
   }

}

class MyMouseAdapter extends MouseAdapter {
   @Override
   public void mouseDragged(MouseEvent mEvt) {
      Positionable positionable = (Positionable) mEvt.getSource();
      positionable.mouseDragged(mEvt.getPoint());
   }

   @Override
   public void mousePressed(MouseEvent mEvt) {
      Positionable positionable = (Positionable) mEvt.getSource();
      positionable.mousePressed(mEvt.getPoint());
   }

   @Override
   public void mouseReleased(MouseEvent mEvt) {
      Positionable positionable = (Positionable) mEvt.getSource();
      positionable.mouseReleased(mEvt.getPoint());
   }
}

interface Positionable {
   void mouseDragged(Point p);

   void mousePressed(Point p);

   void mouseReleased(Point p);
}
于 2013-10-03T23:30:42.590 回答