Search code examples
javaswingvariablespaintcomponent

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

I want to make this "face" that is created assigned to one single public value, and set it to x and y coordinates, so that when I'm creating methods for my movement class, I will be able to move the face around using loops.

I can't figure out a better way to do this, if someone is able to enlighten me on a different method, I'd be more than willing to find out on my own. Just looking for someone to point me in the right direction.


Solution

  • I want to make this "face" that is created assigned to one single public value

    The 'OO' way would be to design a Face class that understands how (and where) to draw a Face when requested to do so. The class might look like this:

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

    Then the FaceComponent class can be simplified to this:

    /*
     * 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);
        }
    }