在重绘图形绘制随机线 [英] Graphics in repaint draws random lines

查看:142
本文介绍了在重绘图形绘制随机线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我创建一个免费的手绘的JPanel,该反应鼠标移动和绘制线条。我除了一个臭虫,它会随机画线之间的直线它主要的工作。这种随机的直线是不是故意的,什么绘制的缓冲图像上应该是严格的用户绘制的。这些随机绘制线不是由用户完成的,它的混乱。下面是我的code,任何人都可以看看?图像包括给你它是做什么的可视化再presentation。

So I'm creating a free hand drawing JPanel, that reacts to mouse movements and draws lines. I got it mostly working except for a bug where it'll randomly draw a straight line between lines. That random straight line isn't intentional, what's drawn on the buffered image is supposed to be strictly what the user draws. These random drawn lines are not done by the user and it's confusing. Below is my code, can anyone take a look? The image included gives you a visual representation of what it is doing.

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

推荐答案

您可能会想窝列出来实现自己的目标:

You will likely want to nest Lists to achieve your goal:

List<List<Point>>

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

This way, when the mouse is pressed, start an ArrayList, and when released, finish it. Then you can use nested for loops to draw all the curves.

例如(从$ P $矿pvious回答):

For example (from a previous answer of mine):

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

这篇关于在重绘图形绘制随机线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆