Button5

File: java/Button5/Main.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Main program for Button5
 */
public class Main extends JFrame {
    public static void main (String [] args) {
	new Main ();
    }

    public Main () {
	// Window setup
	setSize (500, 500);
	Container content = getContentPane();
	content.setLayout (new BorderLayout());
	setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

	// Our canvas
	MyCanvas canvas = new MyCanvas ();
	content.add (canvas, BorderLayout.CENTER);
	
	// Application object, holds the "application" data
	Application application = new Application (5, canvas);

	// Didn't have this when we called MyCanvas constructor
	canvas.setApplication (application);

	// Grid container to hold our control panels
	JPanel controls = new JPanel ();
	controls.setLayout (new GridLayout(2, 1));
	controls.add (new ControlGlobal (application));
	controls.add (new ControlSingle (application));
	content.add (controls, BorderLayout.SOUTH);

	setVisible (true);
    }
}

File: java/Button5/MyCanvas.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class MyCanvas extends JComponent implements MouseListener {
    private Application application;

    MyCanvas () {
	setBorder (new LineBorder(Color.blue));
	addMouseListener (this);
    }

    /**
     * Couldn't pass application in constructor,
     * cause it doesn't exist yet
     */
    public void setApplication (Application application) {
	this.application = application;
    }

    /** Tell parent to do the job */
    public void paintComponent (Graphics g) {
	application.drawApplication (g);
    }

    /** MouseListener callbacks */
    public void mousePressed (MouseEvent event) {	
	// Tell parent to do the job
	application.doMouse (event.getPoint());
    }
    public void mouseClicked (MouseEvent event) {}
    public void mouseReleased (MouseEvent event) {}
    public void mouseEntered (MouseEvent event) {}
    public void mouseExited (MouseEvent event) {}
}

File: java/Button5/Application.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

/**
 * The "application" (vs. user interface) part of this program
 */
public class Application {
    /** Application data */
    private ArrayList<Square> squares = new ArrayList<Square> ();
    private boolean drawX = false;

    private MyCanvas canvas;
    private Square current;

    public Application (int n, MyCanvas canvas) {
	// Stash ivar
	this.canvas = canvas;

	// Create the n objects
	for (int i=0; i<n; i++) {
	    squares.add (new Square(canvas));
	}

	// Initialize to some arbitrary square so current is never null
	current = squares.get(0);
    }

    public void drawApplication (Graphics g) {
	// The background X
	if (drawX) {
	    Dimension size = canvas.getSize();
	    g.drawLine (0, 0, size.width, size.height);
	    g.drawLine (0, size.height, size.width, 0);
	}

	// Enumerate our list
	for (Square s: squares) {
	    // N.B. (s==current) is a boolean expr,
	    // evaluates to true or false
	    s.draw (g, s==current);
	}
    }

    public void setX (boolean newX) {
	drawX = newX;
	canvas.repaint();
    }

    Square getCurrent () {
	return current;
    }

    public void doMouse (Point p) {
	for (Square s: squares) {
	    if (s.isInside(p)) {
		current = s;
		break;
	    }
	}
	
	canvas.repaint();
    }
}

File: java/Button5/Square.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

/**
 * Holds part of the Application data
 */
public class Square {
    /** Classvar to generate unique positions for each instance */
    static private int squareCount = 0;

    private MyCanvas canvas;

    /** Info about the square */
    private Rectangle loc;

    public Square (MyCanvas canvas) {
	this.canvas = canvas;

	// Keep count
	squareCount++;

	// Initial values
	loc = new Rectangle (30*squareCount, 20*squareCount, 50, 50);
    }

    public void draw (Graphics g, boolean isCurrent) {
	Graphics2D g2 = (Graphics2D) g;

	if (isCurrent)g2.fill (loc);
	else g2.draw (loc);
    }

    public void left () {
	loc.x -= 10;
	canvas.repaint();
    }

    public void right () {
	loc.x += 10;
	canvas.repaint();
    }

    public void bigger () {
	loc.width += 10;
	loc.height += 10;
	canvas.repaint();
    }

    public void smaller () {
	loc.width -= 10;
	loc.height -= 10;
	canvas.repaint();
    }

    public boolean isInside (Point p) {
	return loc.contains (p);
    }
}

File: java/Button5/ControlPanel.java

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * Base class for our 2 control panels
 */
public abstract class ControlPanel extends JPanel {
    public ControlPanel () {
	// Settings
	setLayout (new FlowLayout());
	setBorder (new LineBorder(Color.blue));
    }
}
    

File: java/Button5/ControlGlobal.java

import java.awt.*;
import javax.swing.*;

/**
 * The control panel for global commands 
 */
public class ControlGlobal extends ControlPanel {
    ControlGlobal (Application application) {
	// Create our buttons by instantiating their OBJECTS
	// turns out we don't need to remember them,
	// just to add() them to our panel layout
	// Nor do we need to save application, just pass it in
	add (new ButtonX (application));
    }
}

File: java/Button5/ControlSingle.java

import java.awt.*;
import javax.swing.*;

/**
 * The control panel for commands that control a single square
 */
public class ControlSingle extends ControlPanel {
    ControlSingle (Application application) {
	add (new ButtonLeft (application));
	add (new ButtonRight (application));
	add (new ButtonBigger (application));
	add (new ButtonSmaller (application));
    }
}

File: java/Button5/MyButton.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Base class for all our buttons
 */
public abstract class MyButton extends JButton implements ActionListener {
	protected Application application;

	public MyButton (Application application) {
		this.application = application;
		addActionListener (this);
	}
}

File: java/Button5/ArrowButton.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Base class for our buttons that have an arrow on them
 */
public abstract class ArrowButton extends MyButton {
    /** public constants */
    public static final int LEFT = 1;
    public static final int RIGHT = 2;

    public ArrowButton (Application application, int direction) {
	super (application);
	if (direction==LEFT) setIcon (new ImageIcon ("leftArrow.gif"));
	else if (direction==RIGHT) setIcon (new ImageIcon ("rightArrow.gif"));
    }
}

File: java/Button5/TextButton.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Base class for our buttons that have text labels
 */
public abstract class TextButton extends MyButton {
    public TextButton (Application application, String label) {
	super (application);
	setText (label);
    }
}

File: java/Button5/ButtonX.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonX extends TextButton {
    private boolean buttonState = false;
    
    ButtonX (Application application) {
	super (application, "X");
    }
    
    public void actionPerformed (ActionEvent e) {
	buttonState = ! buttonState;
	application.setX (buttonState);
    }
}

File: java/Button5/ButtonLeft.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonLeft extends ArrowButton {
    ButtonLeft (Application application) {
	super (application, LEFT);
    }

    public void actionPerformed(ActionEvent e) {
	application.getCurrent().left();
    }
}

File: java/Button5/ButtonRight.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonRight extends ArrowButton {
    ButtonRight (Application application) {
	super (application, RIGHT);
    }
    
    public void actionPerformed(ActionEvent e) {
	application.getCurrent().right();
    }
}

File: java/Button5/ButtonBigger.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonBigger extends TextButton {
    ButtonBigger (Application application) {
	super (application, "Bigger");
    }

    public void actionPerformed(ActionEvent e) {
	application.getCurrent().bigger();
    }
}

File: java/Button5/ButtonSmaller.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonSmaller extends TextButton {
    ButtonSmaller (Application application) {
	super (application, "Smaller");
    }

    public void actionPerformed(ActionEvent e) {
	application.getCurrent().smaller();
    }
}