制作可清洁绘图区域的最小方法 [英] Minimal way to make a cleanable drawing area
本文介绍了制作可清洁绘图区域的最小方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我上了一堂可调整背景的课.在该背景上有绘画(使用绘画方法和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 apaint(...)
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屋!
查看全文