当前位置: 首页 > 面试题库 >

重绘中的图形绘制随机线

唐声
2023-03-14
问题内容

因此,我正在创建一个免费的手绘图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


问题答案:

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

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


 类似资料:
  • 我的迭代器 我的绘图方法

  • LCUI 实现了一些图形 API 用于解决组件的背景、边框和阴影的绘制问题。它们都依赖绘制上下文且都支持局部区域绘制,使得 LCUI 能够利用脏矩形机制和 OpenMP 并行渲染来提升渲染性能。 绘制背景 背景绘制参数被定义为LCUI_Background 结构体类型的对象,由 Background_Paint() 函数负责绘制。在下面的例子中,我们将画布中的区域 (200, 100, 400,

  • 绘制矩形 与其它图形库不同,LCUI 提供的图形 API 只支持矩形这一种形式的图形绘制,不支持基于路径来绘制复杂图形。因此,对于其它复杂的图形,你需要手动编写代码填充像素来绘制。 LCUI 提供了一种绘制矩形的方法: int Graph_FillRect(LCUI_Graph *graph, LCUI_Color color, LCUI_Rect *rec

  • 本节,我们通过绘制色彩缤纷的鲜花,来拥抱我们内心的嬉皮士。 图2-10 绘制开满鲜花的原野 绘制步骤 按照以下步骤,绘制随机的鲜花遍布整个画布: 1. 定义Flower对象的构造函数: //定义Flower对象的构造函数 function Flower(context, centerX, centerY, radius, numPetals, color){ this.context  =

  • 我试图用shap和我的数据作图,但弄错了,我真的不明白为什么。我还没发现这方面的任何东西。请解释如何避免此错误?

  • 各位程序员好, 我在代码中遇到了一个似乎无法破解的小问题。它与Java的Jframe;图形区域有关。我将在下面发布的代码是在一个绘图方法上。其目的是绘制ArrayList中的房间,该房间位于另一个类中,因此之前。这种偏离航线的情况不会发生,因此在这里发帖。 获取有关该项目的背景信息是ArrayList,其中包含各种不同大小和颜色的房间。房间本身就是物体。 首先是课程: 下面是用于创建房间的类。 我