/* ******************************************************************************** * Kelli Wiseth * kelli@alameda-tech-lab.com * CIS 255AX * Program name: ScreenSaver.java * Program Description: Application that simulates a ScreenSaver by 'taking over' * the full screensize of the display, and instantiating dynamically created * shapes (MyLine, MyTriangle, MySphere) in a variety of randomly generated * sizes and colors. * * Assignment #6 * 26 April 2005 ******************************************************************************** */ import java.awt.*; import java.awt.event.*; //ActionEvent, ActionListener import java.awt.geom.*; import javax.swing.*; public class ScreenSaver extends JFrame implements ActionListener { private Timer timer; private MyShape shape; private int width; private int height; private int dpi; private Point deadCenter; // Midpoint on this display private int minY, maxY, minX, maxX; // Base x, y coordinates on the display // set window's title bar String and dimensions public ScreenSaver() { super( "Kelli Wiseth ScreenSaver" ); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); dpi = Toolkit.getDefaultToolkit().getScreenResolution(); width = screenSize.width; height = screenSize.height; getContentPane().setBackground(Color.BLACK); setSize( width, height); setVisible( true ); deadCenter = new Point (width/2, height/2); minX = 2; // don't start at 0 so we can see it maxX = width-2; minY = 30; maxY = height-30; timer = new Timer (1000, this); timer.start(); } //end of the constructor // draw shapes with Java2D API public void paint( Graphics g ) { super.paint( g ); // call superclass's paint method Graphics2D g2d = ( Graphics2D ) g; // cast g to Graphics2D for (int ctr=0; ctr < 100; ctr++) { // Generate one of three different types of shapes int myShapeTypeNum = getRandomInt(1, 3); /************************************************************************ * Switch statement that instantiates appropriate shape objects based * on the randomly generated value of myShapeTypeNum. ************************************************************************* */ switch(myShapeTypeNum) { case 1: /************************************************************************ * Since we're using a line of randomly-generated thickness (stroke), I * want to take into account that stroke when placing the x, y coordinate * and also when generating the subsequent point for the line. I'm thinking * that some kind of recursive call might be good for this, but I can't * quite figure it out right now, so I'll use what seems a bit of a kludge * to try to accomplish the proper placement of MyLine within the screen size, * regardless of stroke value. ************************************************************************ */ float strokeValue = getRandomStroke(); int strokeValueInt = (int)(strokeValue+1); g2d.setStroke(new BasicStroke(strokeValue)); g2d.setColor(getRandomColor()); shape = new MyLine(getRandomStrokedX(strokeValueInt), getRandomStrokedY(strokeValueInt), getRandomStrokedX(strokeValueInt), getRandomStrokedY(strokeValueInt)); shape.draw(g2d); for (int delay = 0; delay <= 100000000; delay++); break; case 2: g2d.setColor(getRandomColor()); shape = new MyTriangle(getRandomX(), getRandomY(), getRandomX(), getRandomY(), getRandomX(), getRandomY()); shape.draw(g2d); for (int delay = 0; delay <= 100000000; delay++); break; case 3: /******************************************************************************* * The range of possible radius values depends on where the random X coordinate * and the random Y coordinates land on the screen--the relative position of x, y * must be taken into account before determing the range of possible radius values, * since we don't want the circle to go off the display. Rather than using completely * random values for all parameters to the GradientPaint method, I'm generating * random values for the second x, y coordinates based on the first, so that * we get something like a gradient each time. ******************************************************************************* */ int coordinateX = getRandomX(); int coordinateY = getRandomY(); int endGradientX = coordinateX + getRandomInt(1,90); int endGradientY = coordinateY + getRandomInt(1,90); int radius = getRandomRadius(coordinateX, coordinateY); g2d.setPaint( new GradientPaint(coordinateX, coordinateY, getRandomColor(), endGradientX, endGradientY, getRandomColor(), true ) ); MyShape shape = new MySphere(coordinateX, coordinateY, radius); shape.draw(g2d); for (int delay = 0; delay <= 100000000; delay++); break; default: System.err.println("Anomoly...should never see this line."); break; } // end switch statement } //inner for-loop } // end method paint /************************************************************************** * actionPerformed simply calls repaint ************************************************************************** */ public void actionPerformed(ActionEvent timer) { repaint(); } public int getRandomX() { return getRandomInt(minX, maxX); } public int getRandomY() { return getRandomInt(minY, maxY); } public int getRandomStrokedX(int stroke) { int coordinateX = getRandomX(); if (coordinateX > deadCenter.getX()) return coordinateX-stroke; else return coordinateX+stroke; } public int getRandomStrokedY(int stroke) { int coordinateY = getRandomY(); if (coordinateY > deadCenter.getY()) return coordinateY-stroke; else return coordinateY+stroke; } public int getRandomRadius(int xCoordinate, int yCoordinate) { int randomMaxX; int randomMaxY; if (xCoordinate < this.deadCenter.getX()) randomMaxX = this.deadCenter.getX()-xCoordinate; else randomMaxX = maxX-xCoordinate; if (yCoordinate < this.deadCenter.getY()) randomMaxY = this.deadCenter.getY()-yCoordinate; else randomMaxY = maxY-yCoordinate; int smallerValue = Math.min(randomMaxX, randomMaxY); smallerValue = smallerValue/2; int radius = getRandomInt(2, smallerValue); return radius; } /************************************************************************** * getRandomInt generates a random number given a shift value and * a scaling factor ************************************************************************** */ public int getRandomInt(int shiftValue, int scaleFactor ){ return shiftValue + (int)(Math.random() * scaleFactor); } /************************************************************************** * getRandomStroke generates a random float up to the value of the dots per * inch of the screenSize obtained from the Toolkit, so the range of possible * values will vary, depending on the system and the number obtained from Toolkit. ************************************************************************** */ public float getRandomStroke() { return (float)(1.0 + Math.random()*dpi); } /************************************************************************** * getRandomColor calls getRandomInt to create three different random * values in the range of 0 to 255, and then returns a Color object to the * the caller, initialized with those random RGB values. ************************************************************************** */ public Color getRandomColor() { int rVal = getRandomInt(0, 255); int gVal = getRandomInt(0, 255); int bVal = getRandomInt(0, 255); return new Color(rVal, gVal, bVal); } // execute application public static void main( String args[] ) { ScreenSaver application = new ScreenSaver(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class ScreenSaver