1

我有一个可调整背景的课程。在那个背景上有绘画(使用绘画方法和Java2D)。每次调整背景大小时,如何删除所有绘制的内容?(最终在正确的位置再次绘制)我可以对已经绘制的对象进行任何类型的转换(比如缩放以再次适合图像)?

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

1 回答 1

2

考虑:

  • 绘制paintComponent(...)覆盖,而不是paint(...)覆盖。
  • 保存List<Point>每个点被标准化的地方,比如 1000 x 1000 大小。
  • 然后在paintComponent方法中,在for循环中遍历每个Point,缩放到当前组件大小,然后绘制。
  • 您需要在 ComponentListener 中缩放在组件中绘制的任何图像,然后调用repaint().
  • 或者甚至更好,使用Graphics#drawImage(...)带宽度和高度参数的重载缩放绘制的图像。

例如,

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();
         }
      });
   }
}
于 2013-06-29T17:57:16.837 回答