2013-10-03 33 views
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; 
    } 
} 
} 

The Straight lines is what I don't want.

回答

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

嵌套列表完美,谢客。但是JPanel的可定位实现是做什么的? – Frizinator