是否可以将在 paintComponent 中创建的多个对象设置为一个整体变量?即由矩形、直线和椭圆组成的脸
Is it possible to set multiple objects created in paintComponent to one whole variable? i.e. A face made up of a rectangle, line and ellipse
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
/*
* This component will draw an "Alien" face
*/
public class FaceComponent extends JComponent
{
//Create a constructor that will create a face and place it in a variable.
public void paintComponent(Graphics g)
{
//Recover Graphics2D
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//Construct the alien face
//Draw the head
Ellipse2D.Double head = new Ellipse2D.Double (5, 80, 100, 150);
g2.draw(head);
//Draw the set of eyes
g2.setColor(Color.GREEN);
Rectangle eye = new Rectangle(25, 140, 15, 15);
g2.fill(eye);
eye.translate(50, 0);
g2.fill(eye);
//Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 180, 80, 180);
g2.setColor(Color.RED);
g2.draw(mouth);
//Draw the greeting
g2.setColor(Color.BLUE);
g2.drawString("Hello, World!", 20, 245);
}
}
我想将创建的这个 "face" 分配给一个 public 值,并将其设置为 x 和 y 坐标,这样当我为我的移动创建方法时 class,我将能够使用循环移动脸部。
我想不出更好的方法来做到这一点,如果有人能够用不同的方法启发我,我会非常愿意自己找出答案。只是想找人给我指明正确的方向。
是的,很有可能将 Shape 对象组合成一个复合对象,例如 Path2D 对象,但是您会丢失颜色信息。最好将你的脸画到 BufferedImage 上,换句话说,用它制作一个 "sprite",然后你可以随意移动它。
例如,
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.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class FacePanel extends JPanel {
private static final int PREF_W = 1000;
private static final int PREF_H = 800;
private static final int BI_W = 200;
private static final int BI_H = 300;
private Ellipse2D.Double head = new Ellipse2D.Double(5, 5, 100, 150);
private Rectangle eye = new Rectangle(25, 65, 15, 15);
private BufferedImage faceSprite = null;
private int faceX = 0;
private int faceY = 0;
public FacePanel() {
faceSprite = createFaceSprite();
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
private BufferedImage createFaceSprite() {
BufferedImage img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw the head
g2.draw(head);
// Draw the set of eyes
g2.setColor(Color.GREEN);
g2.fill(eye);
eye.translate(50, 0);
g2.fill(eye);
// Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 105, 80, 105);
g2.setColor(Color.RED);
g2.draw(mouth);
// Draw the greeting
g2.setColor(Color.BLUE);
g2.drawString("Hello, World!", 20, 170);
g2.dispose();
return img;
}
// mouse listener and motion listener to allow us to move the face
private class MyMouse extends MouseAdapter {
private Point p0 = null; // location of initial mouse press
private Point img0 = null; // initial location of face
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
// if not the left mouse button, return
return;
}
p0 = e.getPoint();
Point p = new Point(p0.x - faceX, p0.y - faceY);
if (!head.contains(p)) {
// if not pressing inside of head, return
p0 = null;
return;
}
img0 = new Point(faceX, faceY);
}
@Override
public void mouseDragged(MouseEvent e) {
if (p0 != null && img0 != null) {
moveFace(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (p0 != null && img0 != null) {
moveFace(e);
}
p0 = null;
img0 = null;
}
private void moveFace(MouseEvent e) {
faceX = img0.x + e.getPoint().x - p0.x;
faceY = img0.y + e.getPoint().y - p0.y;
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (faceSprite != null) {
g.drawImage(faceSprite, faceX, faceY, this);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
FacePanel mainPanel = new FacePanel();
JFrame frame = new JFrame("FacePanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I want to make this "face" that is created assigned to one single public value
'OO' 方法是设计一个 Face
class 来理解如何(以及在何处)在被请求时绘制 Face
。 class 可能如下所示:
class Face {
private Point location;
Face(Point location) {
this.location = location;
}
/**
* @param location the location to set
*/
public void setLocation(Point location) {
this.location = location;
}
public void draw(Graphics2D g) {
/* save this to reset it after painting. */
AffineTransform transform = g.getTransform();
AffineTransform move = AffineTransform.getTranslateInstance(
location.getX(), location.getY());
g.setTransform(move);
//Construct the alien face
//Draw the head
g.setColor(Color.DARK_GRAY); // explicitly set a color
Ellipse2D.Double head = new Ellipse2D.Double(5, 80, 100, 150);
g.fill(head);
g.setColor(Color.LIGHT_GRAY);
g.draw(head);
//Draw the set of eyes
g.setColor(Color.GREEN);
Rectangle eye = new Rectangle(25, 140, 15, 15);
g.fill(eye);
eye.translate(50, 0);
g.fill(eye);
//Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 180, 80, 180);
g.setColor(Color.RED);
g.draw(mouth);
//Draw the greeting
g.setColor(Color.BLUE);
g.drawString("Hello, World!", 20, 245);
// reset the transform to the original (so later painting is not moved)
g.setTransform(transform);
}
}
那么FaceComponent
class可以简化为:
/*
* This component will draw "Alien" faces
*/
public class FaceComponent extends JComponent {
Face[] faces = new Face[3];
FaceComponent() {
Random r = new Random();
for (int ii=0; ii<faces.length; ii++) {
Point p = new Point(r.nextInt(200), r.nextInt(100));
faces[ii] = new Face(p);
}
}
//Create a constructor that will create a face and place it in a variable.
public void paintComponent(Graphics g) {
//Recover Graphics2D
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Face face : faces) {
face.draw(g2);
}
}
Dimension prefSize = new Dimension(180, 260);
@Override
public Dimension getPreferredSize() {
return prefSize;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(null, new FaceComponent());
}
};
SwingUtilities.invokeLater(r);
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;
/*
* This component will draw an "Alien" face
*/
public class FaceComponent extends JComponent
{
//Create a constructor that will create a face and place it in a variable.
public void paintComponent(Graphics g)
{
//Recover Graphics2D
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//Construct the alien face
//Draw the head
Ellipse2D.Double head = new Ellipse2D.Double (5, 80, 100, 150);
g2.draw(head);
//Draw the set of eyes
g2.setColor(Color.GREEN);
Rectangle eye = new Rectangle(25, 140, 15, 15);
g2.fill(eye);
eye.translate(50, 0);
g2.fill(eye);
//Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 180, 80, 180);
g2.setColor(Color.RED);
g2.draw(mouth);
//Draw the greeting
g2.setColor(Color.BLUE);
g2.drawString("Hello, World!", 20, 245);
}
}
我想将创建的这个 "face" 分配给一个 public 值,并将其设置为 x 和 y 坐标,这样当我为我的移动创建方法时 class,我将能够使用循环移动脸部。
我想不出更好的方法来做到这一点,如果有人能够用不同的方法启发我,我会非常愿意自己找出答案。只是想找人给我指明正确的方向。
是的,很有可能将 Shape 对象组合成一个复合对象,例如 Path2D 对象,但是您会丢失颜色信息。最好将你的脸画到 BufferedImage 上,换句话说,用它制作一个 "sprite",然后你可以随意移动它。
例如,
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.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class FacePanel extends JPanel {
private static final int PREF_W = 1000;
private static final int PREF_H = 800;
private static final int BI_W = 200;
private static final int BI_H = 300;
private Ellipse2D.Double head = new Ellipse2D.Double(5, 5, 100, 150);
private Rectangle eye = new Rectangle(25, 65, 15, 15);
private BufferedImage faceSprite = null;
private int faceX = 0;
private int faceY = 0;
public FacePanel() {
faceSprite = createFaceSprite();
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
private BufferedImage createFaceSprite() {
BufferedImage img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw the head
g2.draw(head);
// Draw the set of eyes
g2.setColor(Color.GREEN);
g2.fill(eye);
eye.translate(50, 0);
g2.fill(eye);
// Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 105, 80, 105);
g2.setColor(Color.RED);
g2.draw(mouth);
// Draw the greeting
g2.setColor(Color.BLUE);
g2.drawString("Hello, World!", 20, 170);
g2.dispose();
return img;
}
// mouse listener and motion listener to allow us to move the face
private class MyMouse extends MouseAdapter {
private Point p0 = null; // location of initial mouse press
private Point img0 = null; // initial location of face
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
// if not the left mouse button, return
return;
}
p0 = e.getPoint();
Point p = new Point(p0.x - faceX, p0.y - faceY);
if (!head.contains(p)) {
// if not pressing inside of head, return
p0 = null;
return;
}
img0 = new Point(faceX, faceY);
}
@Override
public void mouseDragged(MouseEvent e) {
if (p0 != null && img0 != null) {
moveFace(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (p0 != null && img0 != null) {
moveFace(e);
}
p0 = null;
img0 = null;
}
private void moveFace(MouseEvent e) {
faceX = img0.x + e.getPoint().x - p0.x;
faceY = img0.y + e.getPoint().y - p0.y;
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (faceSprite != null) {
g.drawImage(faceSprite, faceX, faceY, this);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
FacePanel mainPanel = new FacePanel();
JFrame frame = new JFrame("FacePanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I want to make this "face" that is created assigned to one single public value
'OO' 方法是设计一个 Face
class 来理解如何(以及在何处)在被请求时绘制 Face
。 class 可能如下所示:
class Face {
private Point location;
Face(Point location) {
this.location = location;
}
/**
* @param location the location to set
*/
public void setLocation(Point location) {
this.location = location;
}
public void draw(Graphics2D g) {
/* save this to reset it after painting. */
AffineTransform transform = g.getTransform();
AffineTransform move = AffineTransform.getTranslateInstance(
location.getX(), location.getY());
g.setTransform(move);
//Construct the alien face
//Draw the head
g.setColor(Color.DARK_GRAY); // explicitly set a color
Ellipse2D.Double head = new Ellipse2D.Double(5, 80, 100, 150);
g.fill(head);
g.setColor(Color.LIGHT_GRAY);
g.draw(head);
//Draw the set of eyes
g.setColor(Color.GREEN);
Rectangle eye = new Rectangle(25, 140, 15, 15);
g.fill(eye);
eye.translate(50, 0);
g.fill(eye);
//Draw the mouth
Line2D.Double mouth = new Line2D.Double(30, 180, 80, 180);
g.setColor(Color.RED);
g.draw(mouth);
//Draw the greeting
g.setColor(Color.BLUE);
g.drawString("Hello, World!", 20, 245);
// reset the transform to the original (so later painting is not moved)
g.setTransform(transform);
}
}
那么FaceComponent
class可以简化为:
/*
* This component will draw "Alien" faces
*/
public class FaceComponent extends JComponent {
Face[] faces = new Face[3];
FaceComponent() {
Random r = new Random();
for (int ii=0; ii<faces.length; ii++) {
Point p = new Point(r.nextInt(200), r.nextInt(100));
faces[ii] = new Face(p);
}
}
//Create a constructor that will create a face and place it in a variable.
public void paintComponent(Graphics g) {
//Recover Graphics2D
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Face face : faces) {
face.draw(g2);
}
}
Dimension prefSize = new Dimension(180, 260);
@Override
public Dimension getPreferredSize() {
return prefSize;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(null, new FaceComponent());
}
};
SwingUtilities.invokeLater(r);
}
}