如何在 JComponent 上永久绘画

How to paint permanently on JComponent

我正在尝试在 Java 中创建绘图应用程序。

paintComponent() 方法内部:

问题是在 ArrayList 中有相当多的形状后,paintComponent() 方法的执行变慢了。

例如自定义画笔。

问题是:

谢谢!

这是一个示例代码:

public class GraphicPanel extends JComponent{
  private ArrayList<Shape> shapeBuffer;

  public void paintComponent( Graphics gPlain ){
       Graphics2D g = (Graphics2D)gPlain;
       for( Shape s : shapeBuffer ){
        if( filled.next() ){
            g.fill( s );
        }
        else{
            g.draw( s );
        }
  }
}

将背景绘制到 BufferedImage,然后使用 g.drawImage(...)paintComponent(...) 方法中将 BufferedImage 绘制到您的 GrahpicPanel。您可以通过调用 getGraphics()createGraphics()(对于 Graphics2D 对象)获取 BufferedImage 的 Graphics 上下文。不要忘记处置以这种方式获得的 Graphics 对象(但永远不要处置 JVM 给你的 Graphics 对象)。

此外,不要忘记在覆盖中调用 super.paintComponent(g)

例如:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.*;

public class MyPaint extends JComponent {
   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   private static final Stroke STROKE = new BasicStroke(4f);
   private static final Color[] COLORS = { Color.RED, Color.GREEN,
         Color.yellow, Color.orange, Color.blue, Color.cyan };
   private BufferedImage img = new BufferedImage(PREF_W, PREF_H,
         BufferedImage.TYPE_INT_ARGB);
   private Rectangle rect = null;

   public MyPaint() {
      MyMouse myMouse = new MyMouse();
      addMouseListener(myMouse);
      addMouseMotionListener(myMouse);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (img != null) {
         g.drawImage(img, 0, 0, null);
      }
      if (rect != null) {
         g.setColor(Color.LIGHT_GRAY);
         ((Graphics2D) g).draw(rect);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class MyMouse extends MouseAdapter {
      private Random random = new Random();
      private Point p;

      @Override
      public void mousePressed(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }
         p = e.getPoint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (p != null) {
            Rectangle rect2 = createRect(e.getPoint());
            Graphics2D g2 = img.createGraphics();
            g2.setStroke(STROKE);
            Color c = COLORS[random.nextInt(COLORS.length)];
            g2.setColor(c);
            g2.fill(rect2);
            g2.setColor(c.darker());
            g2.draw(rect2);
            g2.dispose();
         }

         p = null;
         rect = null;
         repaint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         rect = createRect(e.getPoint());
         repaint();
      }

      private Rectangle createRect(Point p2) {
         int x = Math.min(p.x, p2.x);
         int y = Math.min(p.y, p2.y);
         int width = Math.abs(p.x - p2.x);
         int height = Math.abs(p.y - p2.y);
         Rectangle rect2 = new Rectangle(x, y, width, height);
         return rect2;
      }

   }

   private static void createAndShowGui() {
      MyPaint mainPanel = new MyPaint();

      JFrame frame = new JFrame("MyPaint");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

笔触和颜色是形状的属性。您可以像这样定义自己的形状 class。这样,您就可以维护列表中的形状。

package com.ggl.testing;

import java.awt.Color;
import java.awt.Shape;

public class MyShape {

    private int brushSize;

    private Color interiorColor;

    private Shape shape;

    public MyShape() {
        this.brushSize = 1;
        this.interiorColor = Color.blue;
    }

    public MyShape(int brushSize, Color interiorColor, Shape shape) {
        this.brushSize = brushSize;
        this.interiorColor = interiorColor;
        this.shape = shape;
    }

    public int getBrushSize() {
        return brushSize;
    }

    public void setBrushSize(int brushSize) {
        this.brushSize = brushSize;
    }

    public Color getInteriorColor() {
        return interiorColor;
    }

    public void setInteriorColor(Color interiorColor) {
        this.interiorColor = interiorColor;
    }

    public Shape getShape() {
        return shape;
    }

    public void setShape(Shape shape) {
        this.shape = shape;
    }

}

如果我遗漏了任何属性,请随时将它们添加到您的形状中 class。