Okay. For completeness, I modified the demo to include two objectives: show how a shape object can draw itself on a Graphics object passed to it, AND how the variables in one class can be updated by another using mutator (or setter) methods.
For the second objective, the DrawPanel class was separated from the main class, a Shape field, currentClass, was added to DrawPanel, the setCurrentShape() method was added to the DrawPanel class, and the setCurrentShape() method is called by the main class when either the buttons or the slider cause the current shape to change. I also simplified the drawing panel's paintComponent() method that originally had code in it that belonged in other places. Sorry if I caused any confusion.
// a class to demonstrate shapes drawing themselves
// GregBrannon, Dec 5, 2013, ver 0.1 Dec 6, 2013
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
// a class to demonstrate how shapes can draw themselves
public class DrawDemo
{
private JFrame demoFrame;
private JPanel controlPanel;
private DrawPanel drawPanel;
private JSlider shapeSlider;
private JRadioButton squareButton;
private JRadioButton circleButton;
private ButtonGroup buttonGroup;
private Shape currentShape;
// a default constructor
public DrawDemo()
{
// initialize the instance variables
controlPanel = new JPanel();
controlPanel.setPreferredSize( new Dimension( 300, 50 ) );
drawPanel = new DrawPanel();
// create the slider initially set at 25
shapeSlider = new JSlider( JSlider.HORIZONTAL, 5, 150, 25 );
shapeSlider.addChangeListener( new SliderListener() );
squareButton = new JRadioButton( "Square" );
squareButton.addActionListener( new ButtonListener() );
// make the circle button selected at start
circleButton = new JRadioButton( "Circle" );
circleButton.setSelected( true );
circleButton.addActionListener( new ButtonListener() );
// add the buttons to a button group
buttonGroup = new ButtonGroup();
buttonGroup.add( squareButton );
buttonGroup.add( circleButton );
// build the control panel
controlPanel.add( squareButton );
controlPanel.add( circleButton );
controlPanel.add( shapeSlider );
// initialize the frame to display the demo
demoFrame = new JFrame( "Demo Frame" );
demoFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
demoFrame.setLocationRelativeTo( null );
// initialize the current shape with width 25 and send the
// object to the drawing class
currentShape = new Circle( );
currentShape.setWidth( 25 );
drawPanel.setCurrentShape( currentShape );
// build the frame
demoFrame.add( controlPanel, BorderLayout.NORTH );
demoFrame.add( drawPanel, BorderLayout.CENTER );
// pack the frame and display it
demoFrame.pack();
demoFrame.setVisible( true );
} // end default constructor
// to listen for changes to the slider and act on them
private final class SliderListener implements ChangeListener
{
@Override
public void stateChanged( ChangeEvent e )
{
// get the current slider value and set the width of the
// displayed shape to that value
currentShape.setWidth( shapeSlider.getValue() );
// update the current shape in the class being drawn
drawPanel.setCurrentShape( currentShape );
// repaint the drawing
drawPanel.repaint();
}
} // end class SliderListener
// to listen to the buttons and act on them
private final class ButtonListener implements ActionListener
{
@Override
public void actionPerformed( ActionEvent e )
{
// determine if a square or circle has been selected and
// define the current shape accordingly
if ( squareButton.isSelected() )
{
currentShape = new Square( 80, 50, shapeSlider.getValue() );
}
else
{
currentShape = new Circle( 80, 50, shapeSlider.getValue() );
}
// send the current shape to the drawing class and
// redraw when the button values change
drawPanel.setCurrentShape( currentShape );
drawPanel.repaint();
} // end method actionPerformed()
} // end class Button Listener
// a main() method to launch the app on the EDT
public static void main( String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
@Override
public void run()
{
new DrawDemo();
} // end method run()
} );
} // end method main()
} // end class DrawDemo
// an abstract class to define the basic properties of all shapes and
// specify which methods implementations must have
abstract class Shape
{
// x/y specify the upper left corner, width the width
int x;
int y;
int width;
// an abstract method to require shapes to draw themselves on the
// Graphics objects passed by the parameter g
protected abstract void draw( Graphics g );
// a mutator to set x
public void setX( int x )
{
this.x = x;
} // end method setX()
// a mutator to set y
public void setY( int y )
{
this.y = y;
} // end method setY()
// a mutator to set width
public void setWidth( int width )
{
this.width = width;
} // end method setWidth()
} // end class Shape
// a simple class that defines and draws a circle
class Circle extends Shape
{
// default constructor
public Circle()
{
x = 80;
y = 50;
width = 10;
} // end default constructor
// a constructor that specifies x, y, and the diameter as width
public Circle( int x, int y, int width )
{
this.x = x;
this.y = y;
this.width = width;
} // end constructor
// the draw method as required by the abstract Shape class
protected void draw( Graphics g )
{
g.fillOval( x, y, width, width );
} // end method draw()
} // end class Circle
//a simple class that defines and draws a square
class Square extends Shape
{
// default constructor
public Square()
{
x = 80;
y = 50;
width = 10;
} // end default constructor
// a constructor that specifies x, y, and the diameter as width
public Square( int x, int y, int width )
{
this.x = x;
this.y = y;
this.width = width;
} // end constructor
// the draw method as required by the abstract Shape class
protected void draw( Graphics g )
{
g.fillRect( x, y, width, width );
} // end method draw()
} // end class Square
// a JPanel on which to draw - this is where the magic is
final class DrawPanel extends JPanel
{
// a current shape object for use by the draing panel
Shape currentShape;
// default constructor
protected DrawPanel()
{
// initialize the current shape object to ensure that
// the current shape object will never be null
currentShape = new Circle();
setPreferredSize( new Dimension( 300, 250 ) );
} // end default constructor
// a method to paint or draw on the draw panel
@Override
public void paintComponent( Graphics g )
{
// clear the pallette each time the method is called
super.paintComponent( g );
// vary the color, red for square, blue for circle
if ( currentShape instanceof Square )
{
g.setColor( Color.RED );
}
else
{
g.setColor( Color.BLUE );
}
// draw the correct shape
currentShape.draw( g );
} // end method paintComponent()
// a method to set the drawing panel's current shape
protected void setCurrentShape( Shape currentShape )
{
this.currentShape = currentShape;
} // end method setCurrentShape()
} // end class DrawPanel