因此,我正在创建一个免费的手绘图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; } } }
您可能希望嵌套列表以实现您的目标:
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); }