| CSCI A201/A597Lab Notes Fourteen Second Summer 2000 |
import javax.swing.*;
import java.awt.event.*;
class Picture extends JFrame implements WindowListener {
public Picture() {
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
addWindowListener(this);
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
System.exit(0);
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
}
class One {
public static void main(String[] args) {
Picture f = new Picture();
f.setTitle("Picture.");
f.show();
}
}
This shows how you can use the same component as a listener. It needs to
implement the appropriate interface for a window listener and therefore it
must provide implementations (be them empty) for all the methods listed by
the interface. Let's augment this program with the ability to receive mouse input. Instead of drawing circles we will draw rectangles.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Picture extends JFrame implements WindowListener, MouseListener {
boolean rectangle = false;
int xBox, yBox;
public Picture() {
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
addMouseListener(this);
addWindowListener(this);
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
System.exit(0);
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
public void mouseClicked (MouseEvent e) {
this.rectangle = true;
this.xBox = e.getX() - 30;
this.yBox = e.getY() - 20;
this.drawRectangle(this.getGraphics());
}
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void drawRectangle(Graphics g) {
g.setColor(Color.white);
g.drawRect(this.xBox, this.yBox, 60, 40);
}
public void paint(Graphics g) {
if (rectangle)
this.drawRectangle(g);
}
}
class One {
public static void main(String[] args) {
Picture f = new Picture();
f.setTitle("Picture.");
f.show();
}
}
There's one minor flaw in this program: while the rectangle is moved by the mouse
click (and there is only one rectangle at any given time, except in the beginning,
when there is no rectangle yet) all previous rectangles are going to be shown until
the paint method kicks in. Let's not worry too much about that just now
and move to the next stage.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Picture extends JFrame implements WindowListener, MouseListener {
boolean rectangle = false;
int xBox, yBox;
int[][] pic;
final int COLORS = 16;
Color[] colors = new Color[COLORS];
public Picture() {
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
pic = new int[DEFAULT_WIDTH][DEFAULT_HEIGHT];
for (int i = 0; i < COLORS; i++) {
float red = (float)( i / 15.0 );
float green = (float)( 1.0 - i / 15.0 );
float blue = (float)( (8.0 + 7.0 * (i / 15.0)) / 15.0);
colors[i] = new Color(red, green, blue);
}
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++)
pic[x][y] = this.compute(x, y);
addMouseListener(this);
addWindowListener(this);
}
public int compute(int x, int y) {
return x % 16;
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
System.exit(0);
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
public void mouseClicked (MouseEvent e) {
this.rectangle = true;
this.xBox = e.getX() - 30;
this.yBox = e.getY() - 20;
this.drawRectangle(this.getGraphics());
}
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void drawRectangle(Graphics g) {
g.setColor(Color.white);
g.drawRect(this.xBox, this.yBox, 60, 40);
}
public void paint(Graphics g) {
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++) {
int colorIndex = pic[x][y];
g.setColor(colors[colorIndex]);
g.drawLine(x, y, x, y);
}
if (rectangle)
this.drawRectangle(g);
}
}
class One {
public static void main(String[] args) {
Picture f = new Picture();
f.setTitle("Picture.");
f.show();
}
}
We added a two-dimensional array (called pic) as an instance variable. It's as wide and tall as the frame. There's
a value in it for each pixel on the frame.
We also added an array of colors which has sixteen COLORS in
it. The constructor initializes these colors in a particular way and it might be a good exercise to both figure out what values the
red, green and blue components have as a function of the index i, as well as to
describe the initialization of the color map by eliminating magic numbers altogether.
Now we encourage you to practice with various compute functions. Once you're done experimenting plug in the version that
the next stage of the program contains:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Picture extends JFrame implements WindowListener, MouseListener {
boolean rectangle = false;
int xBox, yBox;
int[][] pic;
final int COLORS = 16;
Color[] colors = new Color[COLORS];
public Picture(double xmin, double ymin, double xmax, double ymax) {
this.xmin = xmin; this.xmax = xmax;
this.ymin = ymin; this.ymax = ymax;
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
this.xgap = (this.xmax - this.xmin) / DEFAULT_WIDTH;
this.ygap = (this.ymax - this.ymin) / DEFAULT_HEIGHT;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
pic = new int[DEFAULT_WIDTH][DEFAULT_HEIGHT];
for (int i = 0; i < COLORS; i++) {
float red = (float)( i / 15.0 );
float green = (float)( 1.0 - i / 15.0 );
float blue = (float)( (8.0 + 7.0 * (i / 15.0)) / 15.0);
colors[i] = new Color(red, green, blue);
}
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++)
pic[x][y] = this.compute(x, y);
addMouseListener(this);
addWindowListener(this);
}
double xmin, xmax, ymin, ymax, xgap, ygap;
public int compute(int x, int y) {
// return x % COLORS;
// return y % COLORS;
// return (x + y) % COLORS;
// return Math.max(x, y) % COLORS;
double real = xmin + x * xgap;
double imag = ymin + y * ygap;
int count;
double a = 0, b = 0;
double newA, newB;
for (count = 0; count < 1000 && (a * a + b * b < 4); count++) {
newA = (a * a - b * b) + real;
newB = 2 * a * b + imag;
a = newA;
b = newB;
}
return (count % COLORS);
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
System.exit(0);
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
public void mouseClicked (MouseEvent e) {
this.rectangle = true;
this.xBox = e.getX() - 30;
this.yBox = e.getY() - 20;
this.drawRectangle(this.getGraphics());
}
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void drawRectangle(Graphics g) {
g.setColor(Color.white);
g.drawRect(this.xBox, this.yBox, 60, 40);
}
public void paint(Graphics g) {
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++) {
int colorIndex = pic[x][y];
g.setColor(colors[colorIndex]);
g.drawLine(x, y, x, y);
}
if (rectangle)
this.drawRectangle(g);
}
}
class One {
public static void main(String[] args) {
Picture f = new Picture(-2.0, -1.2, 1.2, 1.2);
f.setTitle("Picture.");
f.show();
}
}
Now we're mapping the (complex) plane onto the screen. So we need some
real world coordinates to be mapped to the screen coordinates. That's why
the constructor receives these values, and stores them in instance variables
(through which it will communicate them to compute).
As always, between the two points in the real world represented as two
adjacent pixels on the screen there will always be a distance, stored by
the two instance variables xgap and ygap.
We now start using the mouse input, and the rectangle that was introduced in the very beginning.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Picture extends JFrame implements WindowListener, MouseListener {
boolean rectangle = false;
int xBox, yBox;
int[][] pic;
final int COLORS = 16;
Color[] colors = new Color[COLORS];
public Picture(double xmin, double ymin, double xmax, double ymax) {
this.xmin = xmin; this.xmax = xmax;
this.ymin = ymin; this.ymax = ymax;
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
this.xgap = (this.xmax - this.xmin) / DEFAULT_WIDTH;
this.ygap = (this.ymax - this.ymin) / DEFAULT_HEIGHT;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
pic = new int[DEFAULT_WIDTH][DEFAULT_HEIGHT];
for (int i = 0; i < COLORS; i++) {
float red = (float)( i / 15.0 );
float green = (float)( 1.0 - i / 15.0 );
float blue = (float)( (8.0 + 7.0 * (i / 15.0)) / 15.0);
colors[i] = new Color(red, green, blue);
}
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++)
pic[x][y] = this.compute(x, y);
addMouseListener(this);
addWindowListener(this);
}
double xmin, xmax, ymin, ymax, xgap, ygap;
public int compute(int x, int y) {
double real = xmin + x * xgap;
double imag = ymin + y * ygap;
int count;
double a = 0, b = 0;
double newA, newB;
for (count = 0; count < 1000 && (a * a + b * b < 4); count++) {
newA = (a * a - b * b) + real;
newB = 2 * a * b + imag;
a = newA;
b = newB;
}
return (count % COLORS);
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
// System.exit(0);
this.dispose();
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
Picture blowup;
int count;
public void mouseClicked (MouseEvent e) {
this.rectangle = true;
this.xBox = e.getX() - 30;
this.yBox = e.getY() - 20;
this.drawRectangle(this.getGraphics());
blowup = new Picture(xmin + this.xBox * this.xgap,
ymin + this.yBox * this.ygap,
xmin + (this.xBox + 60) * this.xgap,
ymin + (this.yBox + 40) * this.ygap);
this.count += 1;
blowup.setTitle("Magnification" + this.count);
blowup.show();
}
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void drawRectangle(Graphics g) {
g.setColor(Color.white);
g.drawRect(this.xBox, this.yBox, 60, 40);
}
public void paint(Graphics g) {
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++) {
int colorIndex = pic[x][y];
g.setColor(colors[colorIndex]);
g.drawLine(x, y, x, y);
}
if (rectangle)
this.drawRectangle(g);
}
}
class One {
public static void main(String[] args) {
Picture f = new Picture(-2.0, -1.2, 1.2, 1.2);
f.setTitle("Picture.");
f.show();
}
}
Last thing is a minor modification to make sure we dispose of all frames except the root one: for that one we
exit the entire program. This is an exercise in instance variables.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Picture extends JFrame implements WindowListener, MouseListener {
boolean rectangle = false;
int xBox, yBox;
int[][] pic;
final int COLORS = 16;
Color[] colors = new Color[COLORS];
public Picture(double xmin, double ymin, double xmax, double ymax, int count) {
this.count = count;
this.xmin = xmin; this.xmax = xmax;
this.ymin = ymin; this.ymax = ymax;
final int DEFAULT_WIDTH = 300;
final int DEFAULT_HEIGHT = 200;
this.xgap = (this.xmax - this.xmin) / DEFAULT_WIDTH;
this.ygap = (this.ymax - this.ymin) / DEFAULT_HEIGHT;
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
pic = new int[DEFAULT_WIDTH][DEFAULT_HEIGHT];
for (int i = 0; i < COLORS; i++) {
float red = (float)( i / 15.0 );
float green = (float)( 1.0 - i / 15.0 );
float blue = (float)( (8.0 + 7.0 * (i / 15.0)) / 15.0);
colors[i] = new Color(red, green, blue);
}
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++)
pic[x][y] = this.compute(x, y);
addMouseListener(this);
addWindowListener(this);
}
double xmin, xmax, ymin, ymax, xgap, ygap;
public int compute(int x, int y) {
double real = xmin + x * xgap;
double imag = ymin + y * ygap;
int count;
double a = 0, b = 0;
double newA, newB;
for (count = 0; count < 1000 && (a * a + b * b < 4); count++) {
newA = (a * a - b * b) + real;
newB = 2 * a * b + imag;
a = newA;
b = newB;
}
return (count % COLORS);
}
public void windowActivated (WindowEvent e) { }
public void windowClosed (WindowEvent e) { }
public void windowClosing (WindowEvent e) {
if (this.count == 0) {
System.exit(0);
} else {
this.dispose();
}
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified (WindowEvent e) { }
public void windowOpened (WindowEvent e) { }
Picture blowup;
int count;
public void mouseClicked (MouseEvent e) {
this.rectangle = true;
this.xBox = e.getX() - 30;
this.yBox = e.getY() - 20;
this.drawRectangle(this.getGraphics());
blowup = new Picture(xmin + this.xBox * this.xgap,
ymin + this.yBox * this.ygap,
xmin + (this.xBox + 60) * this.xgap,
ymin + (this.yBox + 40) * this.ygap,
this.count + 1);
blowup.setTitle("Magnification level " + (this.count + 1));
blowup.show();
}
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mousePressed (MouseEvent e) { }
public void mouseReleased (MouseEvent e) { }
public void drawRectangle(Graphics g) {
g.setColor(Color.white);
g.drawRect(this.xBox, this.yBox, 60, 40);
}
public void paint(Graphics g) {
for (int x = 0; x < pic.length; x++)
for (int y = 0; y < pic[0].length; y++) {
int colorIndex = pic[x][y];
g.setColor(colors[colorIndex]);
g.drawLine(x, y, x, y);
}
if (rectangle)
this.drawRectangle(g);
}
}
class One {
public static void main(String[] args) {
Picture f = new Picture(-2.0, -1.2, 1.2, 1.2, 0);
f.setTitle("Picture.");
f.show();
}
}
Hope you enjoyed this lab. The original picture is a picture of the Mandelbrot set.