SI321 Lab 2

Part 1: Warm Up.
Look in the Toolkit class (a class with a bunch of handy methods for graphical stuff) and write a program to determine the size of the screen on your computer. You should note that you don't make a new Toolkit, but rather you use the default Toolkit, obtained with the call, getDefaultToolkit(). Use the screen size information to open a window in the exact middle of the screen. You may want to look at setLocation() in JFrame.
Part 2: Some graphics
We need to know a few things about graphics before we can use them.

First, graphics are drawn on a container known as a panel. We create our JFrame as before, and then add to it a new JPanel.

Next, whenever a window is changed, a method in JPanel known as paintComponent() is called. So what you need to do, is extend JPanel, override paintComponent(), and then add a new instance of this class to your JPanel.

Consider:

      import javax.swing.*;
      import java.awt.*;
      public class Demo extends JFrame {
         public static void main (String [] args){
	   Demo d = new Demo();
	 }
	 Demo() {
	   super("DEMO");
	   MyPanel mp = new MyPanel();
	   add(mp);
	   setSize(300,300);
	   setVisible(true);
      }
      public class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
	  super.paintComponent(g);
	  g.drawString("This is a JPanel Graphics Demo",50,50);
	}
      }
      
Not bad, but not interesting.

Last, we note that paintComponent will be called with a Graphics object as an argument. Let's not fret about that, but note we want to make it a Graphics2D object:

      public class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
	  super.paintComponent(g);
	  g.drawString("This is a JPanel Graphics Demo",10,10);
	  Graphics2D g2 = (Graphics2D) g;
          //needs import java.awt.geom;
	  Rectangle2D r1 = new Rectangle2D.Double(10.0, 25.0, 22.5, 20.0);
	  Rectangle2D r2 = new Rectangle2D.Double(20.0, 22.0, 21.0, 18.0);
	  g2.draw(r1);
	  g2.fill(r2);
	}
      }
      
Using Rectangle2D and it friends: Arc2D, CubicCurve2D, Ellipse2D, Line2D, Point2D, QuadCurve2D, RoundRectangle2D, draw a face. Oh, to change colors, issue a: g2.setPaint(Color.RED); command.

Part 3: Using Images
You can load up an image like a .gif using the Image class: Image im = ImageIO.read(new File("foobar.gif")); or, even better: Image im = ImageIO.read(new URL("http://www.google.com/images/logo_sm.gif")); You can then add that to your JPanel with, g.drawImage(im, x,y,null); Make another face that is made up of images you found on the internet.

Part 4: Animating
The basic plan for animating something is to take our panel, draw to it differently, and then repaint:
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class Ani extends JFrame {
    public static void main (String [] args){
	new Ani();
    }
    double d= 10.0;
    Ani() {
	super("DEMO");
	MyPanel mp = new MyPanel();
	add(mp);
	setSize(1000,300);
	setVisible(true);
	while (true) {
	    try{
		Thread.sleep(50);
	    }catch(java.lang.InterruptedException e) {}
	    mp.repaint();
	}
    }

    public class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
	  super.paintComponent(g);
	  Graphics2D g2 = (Graphics2D) g;
	  Rectangle2D r1 = new Rectangle2D.Double(d, 25.0, 22.5, 20.0);
	  g2.fill(r1);
	  d=d+1;
	}
    }
}
Modify this code so that there are 30 rectangles of different colors moving in different directions.
Part 5: Refactoring
But this is terrible object oriented coding! All the updates of all these different objects are being done in that one paintComponent method. We want to break it out amongst objects that represent each square. The key is that after we show a panel, we can get the graphics object off of it:
	Panel mp = new Panel();
	add(mp);
	setSize(1000,1000);
	setVisible(true);
	Graphics g = mp.getGraphics();
	System.out.println(g);
	MyR a = new MyR(g);	
and in MyR, we can have a method in MyR that adds to the graphics object. Fix this so that each object adds to the graphics object with g.add(... What happens when you do this with your 30 rectangles? That flicker is a real problem, no? We'll solve that later.