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 に答える