home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-08-14 | 13.3 KB | 512 lines |
- /*
- * Copyright (c) 1996 by Jan Andersson, Torpa Konsult AB.
- *
- * Permission to use, copy, and distribute this software for
- * NON-COMMERCIAL purposes and without fee is hereby granted
- * provided that this copyright notice appears in all copies.
- *
- */
- import java.awt.image.*;
- import java.awt.*;
-
- /**
- * A class that implements an image and/or string labelled button.
- * No fancy animations are supported. It's just a simple button with
- * image support. <p>
- *
- * It is (supposed to be) compatible with the awt.Button class, regarding
- * generated actions event etc. Image does not have to be preloaded and
- * the button is sized when the image size is known.<p>
- *
- * Note: not using preloaded images may cause problems with the layout,
- * depending on the layout manager used for the parent of the button.
- * When the image size is know the layout() function of the parent is
- * called. You might have to resize and/or reshape the parent when
- * the layout() function is called. See how this is done in the class
- * JanneToolbar.
- *
- * Sub-class of Canvas due to the awt design.
- *
- *
- * @version 1.8 96/02/21
- * @author Jan Andersson, Torpa Konsult AB. (janne@torpa.se)
- */
-
- public class JanneButton extends Canvas {
- /**
- * The image
- */
- protected Image image = null;
-
- /**
- * Flag to keep track of if image size (yet) known
- */
- protected boolean imageSizeKnown = false;
-
- /**
- * The label string (also used in action event for image buttons)
- */
- protected String label;
-
- /**
- * Flag to keep track if image loaded
- */
- protected boolean imageLoaded = false;
-
- /**
- * Button shadow border width
- */
- protected int shadow = 2;
-
- /**
- * Button border width
- */
- protected int border = 2;
-
- /**
- * The button state.
- */
- protected boolean selected = false;
-
- /**
- * Resize image to actual size of button.
- */
- protected boolean resizeImage = true;
-
- /**
- * Show label as well as image
- */
- protected boolean showLabel = true;
-
- /**
- * Constructs a Button with a string label and/or an image.
- * @param image the button image
- * @param label the button label (used in action events)
- * @param shadow the button shadow width
- * @param border the button border width
- * @param resizeImage true if image to be resized to actual width
- * of button.
- * @param showLabel if label to be displayed as well as image.
- */
- public JanneButton(Image image, String label,
- int shadow, int border,
- boolean resizeImage,
- boolean showLabel) {
- this.image = image;
- if (image == null)
- imageSizeKnown = true; // kind of ;-)
- this.label = label;
- this.shadow = shadow;
- this.border = border;
- this.resizeImage = resizeImage;
- this.showLabel = showLabel;
- }
-
- /**
- * Constructs a Button with a string label and an image.
- * @param image the button image
- * @param label the button label (used in action events)
- * @param resizeImage true if image to be resized to actual width
- * @param showLabel if label to be displayed as well as image.
- * of button.
- */
- public JanneButton(Image image, String label,
- boolean resizeImage,
- boolean showLabel) {
- this(image, label, 2, 2, resizeImage, showLabel);
- }
-
- /**
- * Constructs a Button with an image.
- * @param image the button image
- * @param label the button label (only used in action events)
- */
- public JanneButton(Image image, String label) {
- this(image, label, 2, 2, false, false);
- }
-
- /**
- * Constructs a Button with an string label.
- * @param label the button label
- */
- public JanneButton(String label) {
- this(null, label, 2, 2, false, true);
- }
-
- /**
- * Gets the string label of the button.
- * @see #setLabel
- */
- public String getLabel() {
- return label;
- }
-
- /**
- * Sets the string label of the button.
- * @param label the label to set the button with
- * @see #getLabel
- */
- public void setLabel(String label) {
- this.label = label;
- layoutParent();
- repaint();
- }
-
- /**
- * Gets the image of the button.
- * @see #setImage
- */
- public Image getImage() {
- return image;
- }
-
- /**
- * Sets the image of the button.
- * @param image the image to set the button with
- * @see #getImage
- */
- public void setImage(Image image) {
- this.image = image;
- layoutParent();
- repaint();
- }
-
- /**
- * Gets the resizeImage flag of the button.
- * @see #setResizeImage
- */
- public boolean getResizeImage() {
- return resizeImage;
- }
-
- /**
- * Sets the resizeImage flag of the button.
- * @param resizeImage true if image to be resized to actual width
- * of button.
- */
- public void setResizeImage(boolean resizeImage) {
- this.resizeImage = resizeImage;
- layoutParent();
- repaint();
- }
-
- /**
- * Gets the showLabel flag of the button.
- * @see #setShowLabel
- */
- public boolean getShowLabel() {
- return showLabel;
- }
-
- /**
- * Sets the showLabel flag of the button.
- * @param showLabel true if label to be displayed as well as image.
- */
- public void setShowLabel(boolean showLabel) {
- this.showLabel = showLabel;
- layoutParent();
- repaint();
- }
-
- /**
- * Check if image size (yet) known
- */
- public boolean imageSizeKnown() {
- return imageSizeKnown;
- }
-
- /**
- * Returns the parameter String of this button.
- */
- protected String paramString() {
- return super.paramString() + ",label=" + label;
- }
-
- /**
- * Repaints the button when the image has changed.
- * Set flag if some bits loaded.
- * @return true if image has changed; false otherwise.
- */
- public boolean imageUpdate(Image img, int flags,
- int x, int y, int w, int h) {
- if ((flags & SOMEBITS) != 0) {
- // part of the image is loaded; start painting
- imageLoaded = true;
- }
- if ((flags & (HEIGHT|WIDTH)) != 0) {
- // got the size; make sure we (re-) layout parent.
- imageSizeKnown = true;
- layoutParent();
- }
- return super.imageUpdate(img, flags, x, y, w, h);
- }
-
- /**
- * Re-layout parent. Called when a button changes image,
- * size etc.
- */
- protected void layoutParent() {
- Container parent = getParent();
- if (parent != null) {
- parent.layout();
- }
- }
-
- /**
- * Paints the button.
- * @param g the specified Graphics window
- */
- public void paint(Graphics g) {
- Dimension size = size();
- if (isVisible()) {
- if (isEnabled()) {
- if (selected)
- paintSelected(g, size);
- else
- paintUnSelected(g, size);
- }
- else if (!isEnabled())
- paintDisabled(g, size);
- }
- }
-
- /**
- * Paints the button when selected.
- * @param g the specified Graphics window
- * @param size the button size
- * @see #paint
- */
- protected void paintSelected(Graphics g, Dimension size) {
- Color c = getBackground();
- g.setColor(c);
- draw3DRect(g, 0, 0, size.width, size.height, false);
- drawBody(g, size);
- }
-
- /**
- * Paints the button when not selected.
- * @param g the specified Graphics window
- * @param size the button size
- * @see #paint
- */
- protected void paintUnSelected(Graphics g, Dimension size) {
- Color c = getBackground();
- g.setColor(c);
- g.fillRect(0, 0, size.width, size.height);
- draw3DRect(g, 0, 0, size.width, size.height, true);
- drawBody(g, size);
- }
-
- /**
- * Paints the button when disabled.
- * @param g the specified Graphics window
- * @param size the button size
- * @see #paint
- */
- protected void paintDisabled(Graphics g, Dimension size) {
- Color c = getBackground();
- g.setColor(c);
- g.fillRect(0, 0, size.width, size.height);
- draw3DRect(g, 0, 0, size.width, size.height, true);
-
- // BUG ALERT: we should really do something "smart" to indicate
- // that an image is disabled here...
-
- // use a gray foreground for string label
- Color fg = getForeground();
- setForeground(Color.gray);
- drawBody(g, size);
- setForeground(fg);
- }
-
- /**
- * Draw a 3D Rectangle.
- * @param g the specified Graphics window
- * @param x, y, width, height
- * @param raised - true if border should be painted as raised.
- * @see #paint
- */
- public void draw3DRect(Graphics g, int x, int y, int width, int height,
- boolean raised) {
- Color c = g.getColor();
- Color brighter = c.brighter();
- Color darker = c.darker();
-
- // upper left corner
- g.setColor(raised ? brighter : darker);
- for (int i=0; i<shadow; i++) {
- g.drawLine(x+i, y+i, x+width-1-i, y+i);
- g.drawLine(x+i, y+i, x+i, y+height-1-i);
- }
- // lower right corner
- g.setColor(raised ? darker : brighter);
- for (int i=0; i<shadow; i++) {
- g.drawLine(x+i, y+height-1-i, x+width-1-i, y+height-1-i);
- g.drawLine(x+width-1-i, y+height-1-i, x+width-1-i, y+i);
- }
- g.setColor(c);
- }
-
- /**
- * Draw body of button. I.e image and/or label string
- * @param g the specified Graphics window
- * @param size the button size
- * @see #paint
- */
- protected void drawBody(Graphics g, Dimension size) {
- int selOff = selected ? 1 : 0;
- int labelX = 0;
- int labelY = 0;
- int labelW = 0;
- int labelH = 0;
- FontMetrics fm = null;
- if (image == null || showLabel) {
- // calculate size and x/y pos. of label string
- Font f = getFont();
- fm = getFontMetrics(f);
- labelH = fm.getAscent() + fm.getDescent();
- labelW = fm.stringWidth(label);
- labelX = size.width/2 - labelW/2 + selOff;
- labelY = size.height/2 - labelH/2 + fm.getAscent() + selOff;
- }
- if (image != null) {
- // draw image
- int x, y, w, h;
- if (resizeImage) {
- // image resized to actual button size
- x = shadow + border + selOff;
- y = shadow + border + selOff;
- w = size.width - 2*(shadow+border) - selOff;
- h = size.height - 2*(shadow+border) - selOff;
- if (showLabel)
- h -= (labelH + border);
- }
- else {
- // image centered in button
- Dimension d = new Dimension();
- d.width = image.getWidth(this);
- d.height = image.getHeight(this);
- if (d.width > 0 && d.height > 0)
- imageSizeKnown = true;
- w = d.width - selOff;
- h = d.height - selOff;
- if (showLabel) {
- x = size.width/2 - d.width/2 + selOff;
- y = (size.height - labelH - border - shadow)/2 -
- d.height/2 + selOff;
- }
- else {
- x = size.width/2 - d.width/2 + selOff;
- y = size.height/2 - d.height/2 + selOff;
- }
- }
- g.drawImage(image, x, y, w, h, this);
- if (showLabel) {
- // draw label string, below image
- g.setColor(getForeground());
- labelY = size.height - fm.getDescent() -
- border - shadow - selOff;
- g.drawString(label, labelX, labelY);
- }
- }
- else {
- // no image; draw label string
- g.setColor(getForeground());
- g.drawString(label, labelX, labelY);
- }
- }
-
- /**
- * Returns the preferred size of this component.
- * @see #minimumSize
- * @see LayoutManager
- */
- public Dimension preferredSize() {
- return minimumSize();
- }
-
- /**
- * Returns the minimum size of this component.
- * @see #preferredSize
- * @see LayoutManager
- */
- public synchronized Dimension minimumSize() {
- Dimension d = new Dimension();
- Dimension labelDimension = new Dimension();
- if (image == null || showLabel) {
- // get size of label
- FontMetrics fm = getFontMetrics(getFont());
- labelDimension.width = fm.stringWidth(label) + 2*(shadow+border);
- labelDimension.height = fm.getAscent() + fm.getDescent() +
- 2*(shadow+border);
- if (image == null)
- d = labelDimension;
- }
- if (image != null) {
- // image used; get image size (If the height is not known
- // yet then the ImageObserver (this) will be notified later
- // and -1 will be returned).
- d.width = image.getWidth(this) ;
- d.height = image.getHeight(this);
- if (d.width > 0 && d.height > 0) {
- // size known; adjust for shadow and border
- d.width += 2*(shadow+border);
- d.height += 2*(shadow+border);
- if (showLabel) {
- // show label as well as image; adjust for label size
- if (labelDimension.width > d.width)
- d.width = labelDimension.width;
- d.height += labelDimension.height - 2*shadow - border;
- }
- }
- }
- return d;
- }
-
- /**
- * Called if the mouse is down.
- * @param evt the event
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public boolean mouseDown(Event evt, int x, int y) {
- // mark as selected and repaint
- selected = true;
- repaint();
- return true;
- }
-
- /**
- * Called when the mouse exits the button.
- * @param evt the event
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public boolean mouseExit(Event evt, int x, int y) {
- if (selected) {
- // mark as un-selected and repaint
- selected = false;
- repaint();
- }
- return true;
- }
-
- /**
- * Called if the mouse is up.
- * @param evt the event
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public boolean mouseUp(Event evt, int x, int y) {
- if (selected) {
- // mark as un-selected and repaint
- selected = false;
- repaint();
- // generate action event
- Event event = new Event(this, Event.ACTION_EVENT, (Object) label);
- deliverEvent(event);
- }
- return true;
- }
- }
-