In this assignment, you are going to develop simulation of fish in a fish tank.
ID: 3599227 • Letter: I
Question
In this assignment, you are going to develop simulation of fish in a fish tank. The goal is to practice Object Oriented Concepts and Comparable, MouseListener and MouseMotionListener Interfaces.
The fish tank has 2 modes of status, fish manipulation and simulation.
In the fish manipulation status, the user can:
add new fish to the tank,
drag a fish to a different slot,
To implement these manipulation functionalities, you need to implement three functions: MouseClicked, MouseDragged and MouseReleased.
MouseClicked:
Verify that the application is in manipulation mode.
Construct a new fish object at the clicked point with a random colour
If the selected slot is not occupied by another fish, add the new fish to the tank
Paint
MouseDragged:
Verify that the application is in manipulation mode.
Set mouseDragged to true
Find out which fish is selected from the tank
MouseReleased:
Verify that mouseDragged is true
Verify that the selected slot is empty
Update the position of the selected fish by the selected slot
Paint
Do not forget to reset the selected fish index and mouseDragged flag
In the simulation mode, each fish independent of the other ones in the fish tank swim in random order.
They can move maximum one slot in each dimension at each fishTick trigger or they can stay in their current slot.
If there is another fish in the slot a fish decided to move, then the fish stays in its current slot.
To implement these simulation functionalities, you need to develop body of the following functions:
CompareTo function of the Fish class:
Compare with respect to mX values
If mX values are equal, compare with respect to mY values
You need to use CompareTo function in the Move, MouseDragged, MouseReleased and MouseClicked
Move function of the Fish class:
Randomly compute a move in x direction as -1, 0, 1
Randomly compute a move in y direction as -1, 0, 1
Compare the new slot of the fish with slots of the other fish in the tank:
If the new slot is occupied, stay in the old slot, and return
If the new slot is out of the tank, stay in the old slot, and return
Paint function of the Fish class:
Draw a filled circle in the center of the selected slot with the fish color
If your fish is drawn as a nice-looking fish as follows (in minimum), then you will get 1 point bonus. Use your creativity.
Please pay attention that I used the Singleton Design Pattern to allow usage of global variables. It is an often used and a very useful design pattern.
Please also pay attention to how we define the Fish class and how Fish class instances independent of each other behave in the Fish Tank.
fishtank.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package fishtank;
//Imports are listed in full to show what's being used
//could just import javax.swing.* and java.awt.* etc..
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JFrame;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.border.EtchedBorder;
class GlobalVariables {
public ArrayList<Fish> mFish;
public FishTank mFishTank;
private GlobalVariables() {
mFish = new ArrayList<Fish>();
mFishTank = new FishTank();
}
private static GlobalVariables instance;
public static GlobalVariables getInstance() {
if (instance == null){
instance = new GlobalVariables();
}
return instance;
}
}
class Fish implements Comparable<Fish>{
int mX;
int mY;
int mId;
Color mColor;
public Fish(int id, int x, int y, Color color){
mId = id;
mX = x;
mY = y;
mColor = color;
}
public void paint(Graphics g){
// Implement this function
}
public void move(){
// Implement this function
}
@Override
public int compareTo(Fish o) {
// Implement this function
return 0;
}
}
class FishTick extends TimerTask{
@Override
public void run() {
if (FishTank.mSimulateStatus){
for (int x=0;x<GlobalVariables.getInstance().mFish.size();x++){
Fish f = GlobalVariables.getInstance().mFish.get(x);
f.move();
GlobalVariables.getInstance().mFish.set(x, f);
}
GlobalVariables.getInstance().mFishTank.mDrawPanel.paint();
}
}
}
public class FishTank extends javax.swing.JFrame implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener{
private final int mNumRows = 20;
private final int mNumCols = 20;
private final int mGridSz = 30;
private int mSelectedFishIndex = -1;
private boolean mDragged = false;
private int mTopHeight;
JToolBar mToolbar;
JToggleButton mSimulationButton;
DrawPanel mDrawPanel;
private int mFishIndex = 0;
static public boolean mSimulateStatus = false;
public static void main(String[] args) {
GlobalVariables global = GlobalVariables.getInstance();
if (global == null){
System.out.println("Cannot initialize, exiting ....");
return;
}
}
private JToggleButton addButton(String title){
JToggleButton button = new JToggleButton(title);
button.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
mSimulateStatus = !mSimulateStatus;
}
});
this.mToolbar.add(button);
return (button);
}
public FishTank()
{
JFrame guiFrame = new JFrame();
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("MY FISH TANK");
// Create a toolbar and give it an etched border.
this.mToolbar = new JToolBar();
this.mToolbar.setBorder(new EtchedBorder());
mSimulationButton = addButton("Simulate");
this.mToolbar.add(mSimulationButton);
//This will center the JFrame in the middle of the screen
guiFrame.setLocationRelativeTo(null);
this.mDrawPanel = new DrawPanel(mNumRows, mNumCols, mGridSz);
this.mDrawPanel.setBackground(Color.cyan);
this.mDrawPanel.paint();
guiFrame.add(mDrawPanel);
guiFrame.add(this.mToolbar, BorderLayout.NORTH);
// Add the Exit Action
JButton button = new JButton("Quit");
button.setToolTipText("Quit the program");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
mToolbar.add(button);
guiFrame.addMouseListener(this);
guiFrame.addMouseMotionListener(this);
//make sure the JFrame is visible
guiFrame.setVisible(true);
mTopHeight = guiFrame.getInsets().top + mToolbar.getHeight();
guiFrame.setSize(mNumRows * mGridSz, mNumCols * mGridSz + mTopHeight);
Timer timer = new Timer("tick", true);
timer.scheduleAtFixedRate(new FishTick(), Calendar.getInstance().get(Calendar.MILLISECOND), 500);
}
@Override
public void mouseClicked(MouseEvent e) {
// Implement this function
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
// Implement this function
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
// Implement this function
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
class DrawPanel extends JPanel{
int mRows;
int mCols;
int mGridSz;
int maxGridSz;
ArrayList<Fish> mFish;
public DrawPanel(int numberOfRows, int numberOfCols, int gridSz){
mGridSz = gridSz;
mRows = numberOfRows;
mCols = numberOfCols;
maxGridSz = mGridSz * mRows;
}
private void paintBackground(Graphics g){
for (int i = 1; i < mRows; i++) {
g.drawLine(i * mGridSz, 0, i * mGridSz, maxGridSz);
}
for (int mAnimateStatus = 1; mAnimateStatus < mCols; mAnimateStatus++) {
g.drawLine(0, mAnimateStatus * mGridSz, maxGridSz, mAnimateStatus * mGridSz);
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
paintBackground(g);
for (Fish f:GlobalVariables.getInstance().mFish){
f.paint(g);
}
}
public void paint(){
repaint();
}
}
Explanation / Answer
import java.applet.*;
import java.awt.*;
//====================================================================
// Main Class for applet FishTank
//
//====================================================================
public class FishTank extends Applet implements Runnable
{
// THREAD SUPPORT:
// m_FishTank is the Thread object for the applet
//----------------------------------------------------------------
Thread m_FishTank = null;
static FishTankFrame frame;
// class "constants"
private final static int width = 400;
private final static int height = 400;
private final static int maxFish = 50;
private final static int maxBubbles = 100;
private final static int maxPlants = 20;
private static int maxDenizens;
static { maxDenizens = maxFish + maxBubbles + maxPlants; }
private static AquariumDenizen critters [] =
new AquariumDenizen[maxDenizens];
// offscreen image - used for double buffering
private Image buffer;
// default number of objects
private int num_fish = 20;
private int num_bubbles = 50;
private int num_plants = 16;
// accessor functions
int getFish () { return num_fish; }
int getBubbles () { return num_bubbles; }
int getPlants () { return num_plants; }
int getMaxFish () { return maxFish; }
int getMaxPlants () { return maxPlants; }
int getMaxBubbles () { return maxBubbles; }
int getMaxDenizens () { return maxDenizens; }
// mutator functions
void setFish (int new_fish) { num_fish = new_fish; }
void setBubbles (int new_bubbles) { num_bubbles = new_bubbles; }
void setPlants (int new_plants) { num_plants = new_plants; }
// STANDALONE APPLICATION SUPPORT
//----------------------------------------------------------------
public static void main(String args[])
{
// Create Toplevel Window to contain applet FishTank
//------------------------------------------------------------
frame = new FishTankFrame("FishTank");
// Must show Frame before we size it so insets() will return
// valid values
//------------------------------------------------------------
frame.show();
frame.hide();
frame.resize(frame.insets().left + frame.insets().right +
width, frame.insets().top + frame.insets().bottom +
height);
// The following code starts the applet running within the
// frame window.
//------------------------------------------------------------
FishTank applet_FishTank = new FishTank();
frame.add("Center", applet_FishTank);
applet_FishTank.init();
applet_FishTank.start();
frame.move(0,0);
frame.show();
}
// FishTank Class Constructor
//----------------------------------------------------------------
public FishTank()
{
super();
}
// init method
//----------------------------------------------------------------
public void init()
{
int newWidth, newHeight;
resize(width, height);
frame.register(this);
new ConfigureFrame ("Configure",this);
Panel p1 = new Panel();
p1.add(new Button("Configure"));
p1.add(new Button("Quit"));
frame.add("South", p1);
newWidth = size().width;
newHeight = size().height;
for (int i=0; i<maxFish; i+=4) {
critters[i] = (AquariumDenizen)
new Fish(newWidth, newHeight-31);
critters[i+1] = (AquariumDenizen)
new Shark(newWidth, newHeight-31);
critters[i+2] = (AquariumDenizen)
new JellyFish(newWidth, newHeight-31);
critters[i+3] = (AquariumDenizen)
new SeaHorse(newWidth, newHeight-31);
}
for (int i=maxFish; i<maxFish+maxBubbles; i++) {
critters[i] = (AquariumDenizen)
new Bubble(newWidth, newHeight-31);
}
for (int i=maxFish+maxBubbles; i<maxDenizens; i++) {
critters[i] = (AquariumDenizen)
new Plant(newWidth, newHeight-31);
}
buffer = createImage(newWidth, newHeight);
}
// destroy method - called when when applet is terminating
// and being unloaded.
//----------------------------------------------------------------
public void destroy()
{
frame.dispose();
System.exit(0);
}
// FishTank Update Handler
//----------------------------------------------------------------
public void update(Graphics g)
{
// method is overriden to get rid of flicker.
//redraw all objects into offscreen buffer
Graphics bufG = buffer.getGraphics();
paint(bufG);
//copy offscreen buffer to screen
g.drawImage(buffer, 0, 0, this);
bufG.dispose();
}
// FishTank Paint Handler
//----------------------------------------------------------------
public void paint(Graphics g)
{
g.setColor(new Color(0, 0, 160));
g.fillRect(0,0, size().width, size().height);
for (int i=maxFish+maxBubbles;
i<maxFish+maxBubbles+num_plants; i++) {
critters[i].paint(g);
}
for (int i=maxFish; i<maxFish+num_bubbles; i++) {
critters[i].paint(g);
}
for (int i=0; i<num_fish; i++) {
critters[i].paint(g);
}
}
// start method - starts the main thread for this application
//----------------------------------------------------------------
public void start()
{
if (m_FishTank == null)
{
m_FishTank = new Thread(this);
m_FishTank.start();
}
}
// stop method - stops the application's thread.
//----------------------------------------------------------------
public void stop()
{
if (m_FishTank != null)
{
m_FishTank.stop();
m_FishTank = null;
}
}
// THREAD SUPPORT
// The run() method is called when the applet's thread is started.
//----------------------------------------------------------------
public void run()
{
while (true) {
try {
// move all fish
for (int i=0; i<num_fish; i++) {
critters[i].move();
}
// move all bubbles
for (int i=maxFish; i<maxFish+num_bubbles; i++) {
critters[i].move();
}
// move all plants
for (int i=maxFish+maxBubbles;
i<maxFish+maxBubbles+num_plants; i++) {
critters[i].move();
}
// redraw the screen & wait 50 milliseconds
repaint((long)1);
Thread.sleep(50);
}
catch (InterruptedException e) {
stop();
}
}
}
}
//====================================================================
// AquariumDenizen class
//
//====================================================================
abstract class AquariumDenizen extends Canvas
{
private protected int x;
private protected int y;
private protected int size;
private protected int direction;
private protected Color color;
private protected int width;
private protected int height;
// AquariumDenizen Class Constructor
//----------------------------------------------------------------
public AquariumDenizen(int screenWidth, int screenHeight)
{
super();
width = screenWidth;
height = screenHeight;
size = ((int)(Math.random()*10000))%(3)+3;
x = ((int)(Math.random()*10000))%width;
y = ((int)(Math.random()*10000))%height;
direction = ((int)(Math.random()*1000))%2*2-1;
color = new Color(((int)(Math.random()*10000))%256,
((int)(Math.random()*10000))%256,
((int)(Math.random()*10000))%256);
}
// abstract move method
//----------------------------------------------------------------
abstract public void move ();
// abstract paint method
//----------------------------------------------------------------
abstract public void paint (Graphics g);
}
//====================================================================
// SwimmingAquariumDenizen class
//
//====================================================================
abstract class SwimmingAquariumDenizen extends AquariumDenizen
{
private protected int fishHeight, fishWidth;
private protected int pos;
// SwimmingAquariumDenizen Class Constructor
//----------------------------------------------------------------
public SwimmingAquariumDenizen(int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
fishHeight = 2*size;
fishWidth = 13*size;
pos = ((int)(Math.random()*2))%1;
}
// abstract paint method
//----------------------------------------------------------------
abstract public void paint (Graphics g);
// move method
//----------------------------------------------------------------
public void move ()
{
int delta_y =((int)(Math.random()*10000))%3;
if (2 == delta_y)
delta_y = -1;
x+=direction*(((int)(Math.random()*10000))%3);
y+=delta_y;
if ((x-fishWidth>width-1) || (x+fishWidth<1)) {
direction *= -1;
x+=2*direction;
}
if (y+2*fishHeight>height-1)
y -= 2;
if (y-2*fishHeight<1)
y += 2;
}
}
//====================================================================
// Fish class
//
//====================================================================
class Fish extends SwimmingAquariumDenizen
{
// Fish Class Constructor
//----------------------------------------------------------------
public Fish (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
pos = Math.abs(pos-1);
// the following are used at least twice, so they are only
// calculated once for efficiency
int k = size*direction;
int k3 = x-3*k;
int k7 = x-7*k;
int k8 = x-8*k;
int k9 = x-9*k;
int k10 = x-10*k;
// body
g.setColor(color);
int xpos[] = {x, k3, k8, k10-pos, k10-pos, k8, k3};
int ypos[] = {y, y+fishHeight, y, y-fishHeight-pos,
y+fishHeight-pos, y, y-fishHeight};
g.fillPolygon(xpos, ypos, 7);
g.drawPolygon(xpos, ypos, 7);
//eye
g.setColor(Color.white);
g.fillOval (k3, y-size, size/2+1,size/2+1);
// lines in tail
g.setColor(color.darker());
g.drawLine (k10-pos, y-size-pos, k9, y-size);
g.drawLine (k10-pos, y-pos, k9, y);
g.drawLine (k10-pos, y+size-pos, k9, y+size);
// gill slits
g.drawLine (x-2*k, y, k3, y+size);
g.drawLine (k3, y, x-4*k, y+size);
// fin
int x1pos[] = {x-5*k+1, k7-1, k7-1};
int y1pos[] = {y-1, y+size*3/2+1, y-1};
g.fillPolygon(x1pos, y1pos, 3);
}
}
//====================================================================
// Shark class
//
//====================================================================
class Shark extends SwimmingAquariumDenizen
{
// Shark Class Constructor
//----------------------------------------------------------------
public Shark (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
size++;
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
pos = Math.abs(pos-1);
// the following are used at least twice, so they are only
// calculated once for efficiency
int k = size*direction;
int k3 = x-3*k;
int k6 = x-6*k;
int k9 = x-9*k;
int fh4 = fishHeight/4;
int fh2 = fishHeight/2;
int fh23 = fishHeight*2/3;
//fins
int xpos1[] = {k3, k6, x-7*k};
int ypos1[] = {y, y-2*fishHeight, y+7/3*fishHeight};
g.setColor(color.darker());
g.fillPolygon(xpos1, ypos1, 3);
//body
g.setColor(color);
int xpos[] = {x, k3, k9, x-12*k-pos, x-10*k, x-11*k-pos,
k9, k3, x-k, x-2*k};
int ypos[] = {y, y-fh2, y, y-fishHeight-pos, y+fh2,
y+fh23-pos, y+fh2, y+fishHeight, y+fh23, y+fh2};
g.fillPolygon(xpos, ypos, 10);
g.drawPolygon(xpos, ypos, 10);
//eye
g.setColor(Color.white);
g.fillOval (k3, y-fh4, size/2,size/2);
//gills
g.setColor(Color.black);
for (int i = 3; i<6; i++) {
g.drawLine(x-i*k, y+fh4 ,x-(i+1)*k, y);
g.drawLine(x-i*k, y+fh4 ,x-(i+1)*k, y+fh2);
}
}
}
//====================================================================
// JellyFish class
//
//====================================================================
class JellyFish extends SwimmingAquariumDenizen
{
// JellyFish Class Constructor
//----------------------------------------------------------------
public JellyFish (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
size*=5;
fishHeight=size;
fishWidth=size*2;
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
g.setColor(color);
// body
g.fillOval(x-size, y-size/6, size*2+1, size/2-1);
g.fillRect(x-size, y+2, 2*size+1, size/6);
// tenticles
int oldx, i, j, newx;
for (i=x-size+7; i<x+size; i+=size/2) {
oldx = i;
for (j=y; j<y+size; j+=2) {
newx = ((int)(Math.random()*3))%3-1+oldx;
g.drawLine(oldx, j, newx, j+1);
oldx = newx;
}
}
}
}
//====================================================================
// SeaHorse class
//
//====================================================================
class SeaHorse extends SwimmingAquariumDenizen
{
// SeaHorse Class Constructor
//----------------------------------------------------------------
public SeaHorse (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
size-=2;
fishHeight=size*13;
fishWidth=size*6;
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
pos = Math.abs(pos-1);
int k = size*direction;
int k2 = 2*k;
int k3 = 3*k;
int k6 = 6*k;
int j2 = 2*size;
int j6 = 6*size;
int j7 = 7*size;
int j8 = 8*size;
int j9 = 9*size;
int j10 = 10*size;
g.setColor(color);
// body
int xpos[] = {x, x+k3, x+k3, x, x-k2, x-k3, x-k3, x-k2,
x-k2, x-(5+pos)*k, x-(5+pos)*k, x-k2, x-k2, x, x+k3,
x+k6, x+k6, x+k3, x+k2, x+5*k, x+k3, x };
int ypos[] = {y, y+size, y-size, y-size, y-j2, y-j2, y-size,
y, y+5*size, y+(4-pos)*size, y+(8-pos)*size, y+j7, y+j9,
y+j10, y+11*size, y+j10, y+j8, y+j7, y+j8, y+j9, y+j10,
y+j9 };
g.fillPolygon(xpos, ypos, 22);
// lines in fin
g.setColor(color.darker());
g.drawLine(x-k, y+j6, x-(5+pos)*k, y+(5-pos)*size);
g.drawLine(x-k, y+j6, x-(5+pos)*k, y+(6-pos)*size);
g.drawLine(x-k, y+j6, x-(5+pos)*k, y+(7-pos)*size);
// eye
g.setColor(Color.white);
g.fillOval(x-k, y-size, size, size);
}
}
//====================================================================
// Plant class
//
//====================================================================
class Plant extends AquariumDenizen
{
private protected int pos;
private protected Color myGreen = new Color (50, 200, 50);
private protected Color myDkGreen = myGreen.darker();
// Plant Class Constructor
//----------------------------------------------------------------
public Plant (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
// -3 to 3
pos = ((int)(Math.random()*1000))%7-3;
// either 30, 40 or 50
size = (((int)(Math.random()*10000))%3+3)*10;
}
// move method
//----------------------------------------------------------------
public void move ()
{
if (pos<=-3) {
direction =1;
} else if (pos>=3) {
direction = -1;
}
pos +=direction;
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
int xpos[] = {x, x-20+pos, x+pos, x, x+10+pos, x-10+pos, x};
int ypos[] = {height, height-size, height-size*2,
height-size*3, height-size*2, height-size, height};
g.setColor(myGreen);
g.fillPolygon(xpos, ypos, 7);
int xpos1[] = {x, x-10+pos, x+10+pos, x, x+20+pos, x+pos, x};
g.setColor(myDkGreen);
g.fillPolygon(xpos1, ypos, 7);
}
}
//====================================================================
// Bubble class
//
//====================================================================
class Bubble extends AquariumDenizen
{
private protected int speed;
// Bubble Class Constructor
//----------------------------------------------------------------
public Bubble (int screenWidth, int screenHeight)
{
super(screenWidth, screenHeight);
size ++;
speed = ((int)(Math.random()*10000))%4+1;
color = new Color(200, 200, 200);
}
// move method
//----------------------------------------------------------------
public void move ()
{
int delta_x =((int)(Math.random()*10000))%3;
if (2 == delta_x)
delta_x = -1;
y -= speed;
if (y<1)
y = height;
x += delta_x;
}
// paint method
//----------------------------------------------------------------
public void paint (Graphics g)
{
g.setColor(color.darker());
g.fillOval (x+1, y+1, size, size);
g.setColor(color);
g.drawOval (x, y, size, size);
}
}
//====================================================================
// FishTankFrame class
//
//====================================================================
class FishTankFrame extends Frame
{
private protected FishTank fishtank;
// FishTankFrame constructor
//----------------------------------------------------------------
public FishTankFrame(String str)
{
super (str);
}
// handleEvent method
//----------------------------------------------------------------
public boolean handleEvent(Event evt)
{
switch (evt.id) {
// Application shutdown (e.g. user chooses Close from the
// system menu).
//--------------------------------------------------------
case Event.WINDOW_DESTROY:
// let the FishTank class handle disposing frames
fishtank.destroy();
return true;
default:
return super.handleEvent(evt);
}
}
// action method - respond to buttons
//----------------------------------------------------------------
public boolean action (Event evt, Object arg)
{
if (arg.equals("Configure")) {
if (!ConfigureFrame.isActive())
new ConfigureFrame ("Configure",fishtank);
else
ConfigureFrame.moveToTop();
return true;
} else if (arg.equals("Quit")) {
// let the FishTank class handle disposing frames
fishtank.destroy();
}
return false;
}
void register (FishTank currentObject)
{
fishtank = currentObject;
}
}
//====================================================================
// ConfigureFrame class
//
//====================================================================
class ConfigureFrame extends Frame
{
TextField numFish, numBubbles, numPlants;
FishTank fishtank;
private protected static ConfigureFrame current;
private protected static boolean active = false;
private protected static final String buttonLables[] = {" << ",
" < ", " > ", " >> ", " << ", " < ", " > ", " >> ",
" << ", " < ", " > ", " >> "};
// isActive accessor - return true if there is an instance of this
// class or false if there is not
//----------------------------------------------------------------
public static boolean isActive() { return active; }
// ConfigureFrame constructor
//---------------------------------------------------------
public ConfigureFrame(String str, FishTank currentObject)
{
super (str);
fishtank = currentObject;
// only allow one instance of this class
if (active) {
//get rid of this instance if 2 or more were created
dispose();
} else {
active = true;
current = this;
}
setResizable(false);
GridBagLayout layout = new GridBagLayout();
setLayout (layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx=100;
gbc.weighty=100;
gbc.gridx=0;
gbc.gridy=0;
gbc.gridwidth=5;
gbc.gridheight=1;
Label l0 = new Label(" Number of fish to display (0 to " +
Integer.toString(fishtank.getMaxFish()) + ") ");
Label l1 = new Label(" Number of bubbles to display (0 to " +
Integer.toString(fishtank.getMaxBubbles()) + ") ");
Label l2 = new Label(" Number of plants to display (0 to " +
Integer.toString(fishtank.getMaxPlants()) + ") ");
numFish =
new TextField(Integer.toString(fishtank.getFish()),2);
numBubbles =
new TextField(Integer.toString(fishtank.getBubbles()),2);
numPlants =
new TextField(Integer.toString(fishtank.getPlants()),2);
Button b0 = new Button(buttonLables[0]);
Button b1 = new Button(buttonLables[1]);
Button b2 = new Button(buttonLables[2]);
Button b3 = new Button(buttonLables[3]);
Button b4 = new Button(buttonLables[4]);
Button b5 = new Button(buttonLables[5]);
Button b6 = new Button(buttonLables[6]);
Button b7 = new Button(buttonLables[7]);
Button b8 = new Button(buttonLables[8]);
Button b9 = new Button(buttonLables[9]);
Button b10 = new Button(buttonLables[10]);
Button b11 = new Button(buttonLables[11]);
Button b12 = new Button("Done");
layout.setConstraints(l0, gbc);
gbc.gridy=2;
layout.setConstraints(l1, gbc);
gbc.gridy=4;
layout.setConstraints(l2, gbc);
gbc.gridwidth=1;
gbc.gridy=1;
gbc.gridx=0;
layout.setConstraints(b0, gbc);
gbc.gridx=1;
layout.setConstraints(b1, gbc);
gbc.gridx=2;
layout.setConstraints(numFish, gbc);
gbc.gridx=3;
layout.setConstraints(b2, gbc);
gbc.gridx=4;
layout.setConstraints(b3, gbc);
gbc.gridy=3;
gbc.gridx=0;
layout.setConstraints(b4, gbc);
gbc.gridx=1;
layout.setConstraints(b5, gbc);
gbc.gridx=2;
layout.setConstraints(numBubbles, gbc);
gbc.gridx=3;
layout.setConstraints(b6, gbc);
gbc.gridx=4;
layout.setConstraints(b7, gbc);
gbc.gridy=5;
gbc.gridx=0;
layout.setConstraints(b8, gbc);
gbc.gridx=1;
layout.setConstraints(b9, gbc);
gbc.gridx=2;
layout.setConstraints(numPlants, gbc);
gbc.gridx=3;
layout.setConstraints(b10, gbc);
gbc.gridx=4;
layout.setConstraints(b11, gbc);
gbc.gridy=6;
gbc.gridx=2;
layout.setConstraints(b12, gbc);
add(l0);
add(b0);
add(b1);
add(numFish);
add(b2);
add(b3);
add(l1);
add(b4);
add(b5);
add(numBubbles);
add(b6);
add(b7);
add(l2);
add(b8);
add(b9);
add(numPlants);
add(b10);
add(b11);
add(b12);
pack();
move(410,100);
show();
}
// handleEvent method
//----------------------------------------------------------------
public boolean handleEvent(Event evt)
{
switch (evt.id) {
case Event.WINDOW_DESTROY:
dispose();
active=false;
return true;
default:
return super.handleEvent(evt);
}
}
// moveToTop method - move frame to the top
// it is a class method so you don't have to keep track of instances
// of the class to call this. Also there is only one instance of
// this class, so which instance to move to the top isn't a problem
//----------------------------------------------------------------
public static void moveToTop ()
{
current.hide();
current.show();
}
// action method - respond to buttons
//----------------------------------------------------------------
public boolean action (Event evt, Object arg)
{
if (arg.equals(buttonLables[0])) {
incrementFish(-4);
return true;
} else if (arg.equals(buttonLables[1])) {
incrementFish(-1);
return true;
} else if (arg.equals(buttonLables[2])) {
incrementFish(1);
return true;
} else if (arg.equals(buttonLables[3])) {
incrementFish(4);
return true;
} else if (arg.equals(buttonLables[4])) {
incrementBubbles(-10);
return true;
} else if (arg.equals(buttonLables[5])) {
incrementBubbles(-1);
return true;
} else if (arg.equals(buttonLables[6])) {
incrementBubbles(1);
return true;
} else if (arg.equals(buttonLables[7])) {
incrementBubbles(10);
return true;
} else if (arg.equals(buttonLables[8])) {
incrementPlants(-4);
return true;
} else if (arg.equals(buttonLables[9])) {
incrementPlants(-1);
return true;
} else if (arg.equals(buttonLables[10])) {
incrementPlants(1);
return true;
} else if (arg.equals(buttonLables[11])) {
incrementPlants(4);
return true;
} else if (arg.equals("Done")) {
dispose();
active=false;
return true;
}
return false;
}
// incrementFish mutator
//----------------------------------------------------------------
private void incrementFish (int x)
{
x+=fishtank.getFish();
if (x>fishtank.getMaxFish()) {
fishtank.setFish(fishtank.getMaxFish());
} else if (x <0) {
fishtank.setFish(0);
} else {
fishtank.setFish(x);
}
numFish.setText(Integer.toString(fishtank.getFish()));
}
// incrementBubbles mutator
//----------------------------------------------------------------
private void incrementBubbles (int x)
{
x+=fishtank.getBubbles();
if (x>fishtank.getMaxBubbles()) {
fishtank.setBubbles(fishtank.getMaxBubbles());
} else if (x<0) {
fishtank.setBubbles(0);
} else {
fishtank.setBubbles(x);
}
numBubbles.setText(Integer.toString(fishtank.getBubbles()));
}
// incrementPlants mutator
//----------------------------------------------------------------
private void incrementPlants (int x)
{
x+=fishtank.getPlants();
if (x>fishtank.getMaxPlants()) {
fishtank.setPlants(fishtank.getMaxPlants());
} else if (x<0) {
fishtank.setPlants(0);
} else {
fishtank.setPlants(x);
}
numPlants.setText(Integer.toString(fishtank.getPlants()));
}
}