/*
* @(#)DrawingJPanel.java
*
* Last Modified: 9/15/01
*/
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.beans.*;
/**
* A specific type of JPanel for the dedicated purpose of drawing some sort of node or tree onto
* the panel. Everything within the class is implemented except the draw
method. This
* must be implemented by extending class to activate the drawing.
*
*
* @author Corey Sanders
* @version 1.3 9/15/01
*/
public class DrawingJPanel extends JPanel implements ComponentListener{
/**
* Image of the Panel for drawing the tree onto. (Used so redrawing is not necessary.
*/
private BufferedImage drawTreeImage;
/**
* Graphics associate with the image of the Panel. (Used so redrawing is not necessary.
*/
private Graphics2D drawTreeGraphics;
/**
* Boolean flag whether the tree needs to be redrawn.
*/
private boolean drawTree = true;
/**
* Rectangle which represents the drawing area of the panel.
*/
private Rectangle drawingArea;
/**
* Flag whether the tree is shown or not.
*/
private boolean componentShown = false;
/**
* Sole Constructor for the JPanel that draws. The super constructor is called. Additionally, the
* default background is set as white and the comoponent adds it to listen to itself.
*/
public DrawingJPanel() {
super();
setBackground(Color.white);
this.addComponentListener(this);
}
/**
********************
* Accesssor methods*
********************
*/
/**
* Gets the draw Tree Image for this panel.
*
* @return BufferedImage set as the drawing image.
*/
public BufferedImage getDrawTreeImage() {
return drawTreeImage;
}
/**
* Gets the draw Tree Graphics for this panel.
*
* @return Graphics2D set as the drawing graphics.
*/
public Graphics2D getDrawTreeGraphics() {
return drawTreeGraphics;
}
/**
* Gets whether the tree needs to be redrawn.
*
* @param true if the tree needs drawing.
*/
public boolean isDrawTree() {
return drawTree;
}
/**
* Sets whether the tree is shown or not.
*
* @return boolean flag as to whether the tree is shown.
*/
public boolean isComponentShown() {
return componentShown;
}
/**
* Gets the drawing area for this panel.
*
* @return Rectangle2D rectangle set as the drawing area.
*/
public Rectangle2D getDrawingArea() {
return drawingArea;
}
/**
*******************
* Mutator methods *
*******************
*/
/**
* Sets the draw Tree Image for this panel.
*
* @param drawTreeImage BufferedImage set as the drawing image.
*/
protected void setDrawTreeImage(BufferedImage drawTreeImage) {
this.drawTreeImage = drawTreeImage;
}
/**
* Sets the draw Tree graphics for this panel.
*
* @param drawTreeImage Graphics2D set as the drawing graphics.
*/
protected void setDrawTreeGraphics(Graphics2D drawTreeGraphics) {
this.drawTreeGraphics = drawTreeGraphics;
}
/**
* Sets whether the tree needs drawing.
*
* @param animating boolean flag as to whether the tree needs drawing.
*/
public void setDrawTree(boolean drawTree) {
this.drawTree = drawTree;
}
/**
* Sets whether the tree is shown or not.
*
* @param componentShown boolean flag as to whether the tree is shown.
*/
public void setComponentShown(boolean componentShown) {
this.componentShown = componentShown;
}
/**
* Sets the drawing area for this panel. Keeps the Rectangle for usage in drawing.
*
* @param drawingArea Rectangle2D rectangle set as the drawing area.
*/
protected void setDrawingArea(Rectangle drawingArea) {
this.drawingArea = drawingArea;
}
/**
*******************
* Drawing methods *
*******************
*/
/**
* Method actually called to complete the drawing of the panel. WIthin this class, the method is
* empty. It must be overiden for anything to be drawn in the call.
*/
protected void draw() {
}
/**
* Makes the drawing image. An image is used because the tree might not always
* need to be redrawn, saving time.
*/
protected void makeDrawTreeImage() {
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
if (w <= 0 || h <= 0) {
return;
}
setDrawingArea(new Rectangle(dim));
setDrawTreeImage((BufferedImage)createImage(w,h));
setDrawTreeGraphics((Graphics2D)getDrawTreeImage().createGraphics());
makeDrawTreeGraphics();
}
/**
* Makes the drawing graphics. Uses the image made from makeDrawTreeImage.
*/
protected void makeDrawTreeGraphics() {
if (getDrawTreeGraphics() == null) {
return;
}
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
getDrawTreeGraphics().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
getDrawTreeGraphics().setClip(0, 0, w, h);
setDrawTree(true);
repaint();
}
/**
* Draws onto the defined draw tree graphic.
* This method is the only call to the draw
method.
*/
protected void drawTree() {
if (getDrawTreeGraphics() == null) {
return;
}
getDrawTreeGraphics().setBackground(getBackground());
getDrawTreeGraphics().clearRect(0,0,(int)drawingArea.getWidth(), (int)drawingArea.getHeight());
draw();
setDrawTree(false);
}
/**
* Draws the JPanel. This overides the paintComponent of JPanel,
* to draw the appropriate image and redraw the graphic if necessary. The drawing is double buffered automatically, but
* the image is only modified on resizing and a change of node. Therefore, dragging, hiding
* and so forth, do not change the image.
*
* @param g Graphics used to draw to the component.
*/
public void paintComponent(Graphics g) {
// Cast to 2D
Graphics2D g2 = (Graphics2D)g;
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
if (isDrawTree()) {
drawTree();
}
// Set Graphics clip
g2.setClip(0,0,w,h);
// Draws the image
g2.drawImage(getDrawTreeImage(), 0, 0, this);
}
/****************************************/
/* Component Listener Interface Methods */
/****************************************/
/**
* Called when the component is hidden. Sets the componentShown as false.
*
* @param e ComponentEvent not used for this particular listening.
*
*/
public void componentHidden(ComponentEvent e) {
setComponentShown(false);
}
/**
* Called when the component is Moved. No action occurs here.
*
* @param e ComponentEvent not used for this particular listening.
*
*/
public void componentMoved(ComponentEvent e) {
}
/**
* Called when the component is Shown. Sets the componentShown as true.
*
* @param e ComponentEvent not used for this particular listening.
*
*/
public void componentShown(ComponentEvent e) {
setComponentShown(true);
}
/**
* Called when the component is Resized. The image is modified according
* to the resizing of the Component.
*
* @param e ComponentEvent not used for this particular listening.
*/
public void componentResized(ComponentEvent e) {
// make the image if it is null
if(getDrawTreeImage() == null) {
makeDrawTreeImage();
return;
}
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
// If the image is too small.
if ((w > getDrawTreeImage().getWidth()) || (h > getDrawTreeImage().getHeight())) {
// Remove old image
getDrawTreeImage().flush();
// Make a new image
makeDrawTreeImage();
}
else {
// Reset drawing area
setDrawingArea(new Rectangle(dim));
// Reset Graphics
makeDrawTreeGraphics();
}
// Reset drawing of tree
setDrawTree(true);
repaint();
}
}