当前位置: 首页 > 知识库问答 >
问题:

如何在JComponent上永久绘制

韦胜泫
2023-03-14
    null
    null

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

例如,自定义画笔。

  • 在画布上拖动画笔时,我必须向ArrayList添加一个类型为“CustomBrush extends Shape”的新形状
  • 所以只需一次划动,我就可以在ArrayList中得到数百个形状

问题是:

  • 如何将100个形状对象“打包”成一个,使一次笔触成为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 );
        }
  }
}

共有1个答案

印成天
2023-03-14

将背景绘制为BufferedImage,然后使用G.DrawImage(...)将BufferedImage绘制为PaintComponent(...)方法中的GrahpicPanel。通过调用getgraphics()creategraphics()(对于Graphics2D对象)来获取BufferedImage的图形上下文。不要忘记处理以这种方式获得的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();
         }
      });
   }
}
 类似资料:
  • 我的最后一个想法,我还没有尝试实现,是将鼠标触摸过的像素附加到一个列表中,并从这个列表中绘制每一帧。但对我来说,这似乎相当复杂,因为它可能会导致超长的数组需要在原始图像的顶部进行处理。所以,我希望还有别的办法! 编辑:我的目标是创建一个涂抹画笔,因此画笔是一种复制区域从一个部分的图像到其他部分。

  • 问题内容: 我正在尝试构建 Paint 应用程序,并且在DrawingArea类中做错了什么。问题是当我尝试绘制第二个形状时,第一个形状或图形是自动删除的,因此我需要一些解决方法的想法。所有答案都可以接受。感谢帮助。 有部分 DrawingArea.class 代码: 问题答案: 您需要: 将要绘制的形状存储在列表中,然后在paintComponent()方法中绘制列表中的所有形状,或者 将形状绘

  • 问题内容: 我试图将目录添加到我的路径,以便它始终位于我的Linux路径中。我试过了: 这可行,但是每次我退出终端并启动新的终端实例时,此路径都会丢失,因此我需要再次运行export命令。 我该如何做才能将其永久设置? 问题答案: 有多种方法可以做到这一点。实际解决方案取决于目的。 变量值通常存储在分配列表或在系统或用户会话开始时运行的Shell脚本中。如果使用Shell脚本,则必须使用特定的Sh

  • 问题内容: 我想将“:/ home / me / play /”值添加到PATH ,以安装Play!框架。 所以我运行了这个命令: 有效。但是在我下次检查时,该值又变回了原来的值。 所以我想我没有“保存”新值,对吗? 你是怎样做的? 问题答案: 加 给你并执行 为了立即反映对您当前终端实例的更改。

  • 我有一个扩展JComponent的自定义组件,它覆盖了方法paintComponent(Graphics g),但当我尝试将其添加到我的JPanel时,它就是不起作用,什么都没有绘制。这是我的代码:

  • 问题内容: 我正在运行RHEL6,并且已经导出了如下环境变量: 当终端关闭时,该变量丢失。如何永久添加此变量,以便特定用户始终可以使用此变量值? 问题答案: 您可以将其添加到您的Shell配置文件中,例如,或在全局中添加。添加这些行之后,更改将不会立即反映在基于GUI的系统中,您必须退出终端或创建一个新终端,然后在服务器中注销会话并登录以反映这些更改。