制作可清洁绘图区域的最小方法 [英] Minimal way to make a cleanable drawing area

查看:85
本文介绍了制作可清洁绘图区域的最小方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我上了一堂可调整背景的课.在该背景上有绘画(使用绘画方法和Java2D). 每当背景调整大小时,如何删除绘制的所有内容? (以便最终在正确的位置再次绘制)我可以对已经绘制的对象进行任何形式的变换(例如缩放以再次适合图像)吗?

I got a class with a resizable background. There are paintings over that background(using a paint method and Java2D). How can i delete everything that was drawn every time that the background gets a resize? (To eventually draw again in the correct places) Is there any sort of transform i can do on the already-drawn objects(like scaling to fit the image again)?

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Background extends JLabel implements ChangeListener  {
    private ImageIcon background;
    private BufferedImage image;

    public Background(JPanel parent){
        super();
        parent.add(this);
        try {
            image = ImageIO.read(new File("/example/background"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.background = new ImageIcon(image);
        this.setIcon(background);
    }
    public void stateChanged(ChangeEvent e) {
        int value = ((JSlider) e.getSource()).getValue();
        double scale = value / 100.0;
        BufferedImage scaled = getScaledImage(scale);
        this.setIcon(new ImageIcon(scaled));
        this.revalidate();
    }
    private BufferedImage getScaledImage(double scale) {
        int w = (int) (scale * image.getWidth());
        int h = (int) (scale * image.getHeight());
        BufferedImage bi = new BufferedImage(w, h, image.getType());
        Graphics2D g2 = bi.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
        g2.drawRenderedImage(image, at);
        g2.dispose();
        return bi; 
    }
    @Override
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D graphObj = (Graphics2D) g;
        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);rh.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
        graphObj.setRenderingHints(rh);
        graphObj.fillOval(500, 500, 20, 20);
        graphObj.finalize();
    }
}

推荐答案

考虑:

  • 绘制paintComponent(...)替代,而不是paint(...)替代.
  • 保存一个List<Point>,其中每个Point都进行了归一化,比如说大小为1000 x 1000.
  • 然后在paintComponent方法中,遍历for循环中的每个Point,将其缩放为当前组件的大小,然后绘制它.
  • 您将希望在ComponentListener中缩放在组件中绘制的任何图像,然后调用repaint().
  • 也许更好,请缩放使用Graphics#drawImage(...)重载绘制的图像,该重载使用宽度和高度参数.
  • Drawing in a paintComponent(...) override, not a paint(...) override.
  • Save a List<Point> where each Point is normalized, say to a 1000 by 1000 size.
  • Then in the paintComponent method, iterate through each Point in a for loop, scaling it to the current component size, and drawing it.
  • You'll want to scale any image drawn in the component in a ComponentListener, and then call repaint().
  • Or perhaps even better, scale the image drawn using the Graphics#drawImage(...) overload that takes width and height parameters.

例如

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

public class MyBackground extends JPanel {
   private BufferedImage img;

   public MyBackground(BufferedImage img) {
      this.img = img;
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (img != null) {
         g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
      }
   }

   private static void createAndShowGui() {
      String comfyChair = "https://duke.kenai.com/comfyChair/ComfyChairRad.png";
      BufferedImage img;
      try {
         URL url = new URL(comfyChair);
         img = ImageIO.read(url);

         MyBackground mainPanel = new MyBackground(img);

         JFrame frame = new JFrame("MyBackground");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(mainPanel);
         frame.pack();
         frame.setLocationByPlatform(true);
         frame.setVisible(true);
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

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

示例2:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;

public class MyBackground extends JPanel {
   public static final double NORM_CONST = 1.0;
   private BufferedImage img;
   private List<List<Point2D>> normalizedPoints = new ArrayList<List<Point2D>>();
   private List<Point2D> pointSubList;

   public MyBackground(BufferedImage img) {
      this.img = img;
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (img != null) {
         g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
      }
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

      for (List<Point2D> pointList : normalizedPoints) {
         if (pointList.size() > 1) {
            for (int i = 1; i < pointList.size(); i++) {
               Point p1 = deNormalize(pointList.get(i - 1));
               Point p2 = deNormalize(pointList.get(i));
               g2.drawLine(p1.x, p1.y, p2.x, p2.y);
            }
         }
      }

      if (pointSubList != null && pointSubList.size() > 1) {
         for (int i = 1; i < pointSubList.size(); i++) {
            Point p1 = deNormalize(pointSubList.get(i - 1));
            Point p2 = deNormalize(pointSubList.get(i));
            g2.drawLine(p1.x, p1.y, p2.x, p2.y);
         }
      }
   }

   private Point deNormalize(Point2D p2d) {
      int x = (int) (p2d.getX() * getWidth() / NORM_CONST);
      int y = (int) (p2d.getY() * getHeight() / NORM_CONST);
      return new Point(x, y);
   }

   private class MyMouseAdapter extends MouseAdapter {

      @Override
      public void mousePressed(MouseEvent e) {
         Point2D p = normalizePoint(e.getPoint());
         pointSubList = new ArrayList<>();
         pointSubList.add(p);
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         Point2D p = normalizePoint(e.getPoint());
         pointSubList.add(p);
         normalizedPoints.add(pointSubList);
         pointSubList = null;
         repaint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         Point2D p = normalizePoint(e.getPoint());
         pointSubList.add(p);
         repaint();
      }

      private Point2D normalizePoint(Point point) {
         double x = (NORM_CONST * point.x) / getWidth();
         double y = (NORM_CONST * point.y) / getHeight();
         Point2D result = new Point2D.Double(x, y);
         return result;
      }


   }

   private static void createAndShowGui() {
      String comfyChair = "https://duke.kenai.com/comfyChair/ComfyChairRad.png";
      BufferedImage img;
      try {
         URL url = new URL(comfyChair);
         img = ImageIO.read(url);

         MyBackground mainPanel = new MyBackground(img);

         JFrame frame = new JFrame("MyBackground");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(mainPanel);
         frame.pack();
         frame.setLocationByPlatform(true);
         frame.setVisible(true);
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

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

这篇关于制作可清洁绘图区域的最小方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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