home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / dek17tau / classes / spt / gui / imagebutton.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  7.4 KB  |  349 lines

  1.  
  2. /*
  3.  * ImageButton.java
  4.  *
  5.  * Copyright (C) 1996 Shaun Terry. All Rights Reserved.
  6.  */
  7.  
  8. package spt.gui;
  9.  
  10. import java.awt.Panel;
  11. import java.awt.Graphics;
  12. import java.awt.Font;
  13. import java.awt.Event;
  14. import java.awt.Color;
  15. import java.awt.Image;
  16. import java.awt.FontMetrics;
  17. import java.awt.Toolkit;
  18. import java.applet.AudioClip;
  19.  
  20. import spt.gui.Rectangle3D;
  21. import spt.gui.ImagePanel;
  22.  
  23.  
  24. /**
  25.  * A push button with an image on it. A text label
  26.  * may also be displayed.
  27.  *
  28.  * @author Shaun Terry
  29.  */
  30.  
  31. public class ImageButton extends Panel {
  32.  
  33.     private boolean isDown = false;
  34.     private int borderW = Rectangle3D.borderWidthOfMode(Rectangle3D.IN);
  35.  
  36.     /** Left of the image */
  37.     public static final int LEFT = 0;
  38.  
  39.     /** Top of the image */
  40.     public static final int TOP = 1;
  41.  
  42.     /** Right of the image */
  43.     public static final int RIGHT = 2;
  44.  
  45.     /** Bottom of the image */
  46.     public static final int BOTTOM = 3;
  47.  
  48.  
  49.     private String label;
  50.     private Image img;
  51.     private Image inactive_img;
  52.     private Image shadowed_img;
  53.     private float imageScale = 1;
  54.     private AudioClip audio;
  55.  
  56.     private boolean fShowBorder = true;
  57.     private boolean fDrawPushedIn = true;
  58.  
  59.     private int    pos = RIGHT;
  60.     private int padding = 2;
  61.     private int gap = 0;
  62.  
  63.     private int ix=0, iy=0, iw=0, ih=0;    // Internal image info
  64.  
  65.      public ImageButton(Image image) {
  66.         this(image, null);
  67.     }
  68.  
  69.     /** A null image or label is ok; a null image <em>and</em> label
  70.      *    is pretty darn useless.
  71.      */
  72.      public ImageButton(Image image, String label) {
  73.         this.label = label;
  74.         setLayout(null);
  75.         img = image;
  76.         resize();
  77.     }
  78.  
  79.     public synchronized void addNotify() {
  80.         resize();
  81.         super.addNotify();
  82.     }
  83.  
  84.     public void setFont(Font f) {
  85.         super.setFont(f);
  86.         resize();
  87.     }
  88.  
  89.     /** Show the border of the button? Useful when you just want
  90.      *    the image without the 3D button look around it.
  91.      */
  92.     public void setShowBorder(boolean b) {
  93.         fShowBorder = b;
  94.         if (b) borderW = Rectangle3D.borderWidthOfMode(Rectangle3D.IN);
  95.         else borderW = 0;
  96.         resize();
  97.     }
  98.  
  99.     /** Make the button "depress" when clicked? If false the button
  100.      *    will behave normally, except when pushed it will give no
  101.      *    visual feedback.
  102.      */
  103.     public void setDrawPushedIn(boolean b) {
  104.         fDrawPushedIn = b;
  105.     }
  106.  
  107.     public int getLabelPosition() { return pos; }
  108.  
  109.     /** Set the position of the label in relation to the image:
  110.      *    TOP, LEFT, RIGHT or BOTTOM.
  111.      */
  112.     public void setLabelPosition(int a) {
  113.         if (a != LEFT && a != TOP && a != RIGHT && a != BOTTOM)
  114.                     throw new IllegalArgumentException();
  115.         pos = a;
  116.         resize();
  117.    }
  118.  
  119.     public String getLabel() { return label; }
  120.  
  121.     public void setLabel(String l) {
  122.         label = l;
  123.         resize();
  124.         repaint();
  125.     }
  126.  
  127.     /** Set the audio clip to play when the button is pushed.
  128.      */
  129.     public void setAudioClip(AudioClip a) {
  130.         audio = a;
  131.     }
  132.  
  133.     /** Set the padding, in pixels, between the button border and
  134.      *    its image.
  135.      */
  136.     public void setPadding(int p) {
  137.         padding = p;
  138.         resize();
  139.         repaint();
  140.     }
  141.  
  142.     public int getPadding() { return padding; }
  143.  
  144.     /** Set the gap, in pixels, between the label, if any, and image.
  145.      */
  146.     public void setImageLabelGap(int g) {
  147.         gap = g;
  148.         resize();
  149.         repaint();
  150.     }
  151.  
  152.     public int getImageLabelGap() { return gap; }
  153.  
  154.     /** The image to be shown.
  155.      */
  156.     public void setImage(Image i) {
  157.         if (i == null || img == null) { img = i; resize(); }
  158.         else if (i.getWidth(this) != img.getWidth(this) ||
  159.                 i.getHeight(this) != img.getHeight(this)) {
  160.             img = i;
  161.             // If new image has a different size, then resize
  162.             resize();
  163.         }
  164.         else img = i;
  165.  
  166.         repaintImage();
  167.     }
  168.  
  169.     /** Scale the image to the given value (1.0 = 100%).
  170.      */
  171.     public void setImageScale(double f) { setImageScale((float) f); }
  172.  
  173.     /** Scale the image to the given value (1.0 = 100%).
  174.      */
  175.     public void setImageScale(float pct) {
  176.         if (pct <= 0) pct = 1;
  177.         imageScale = pct;
  178.         resize();
  179.     }
  180.  
  181.     /** Enables the button.
  182.      */
  183.     public void enable() {
  184.         if (!isEnabled()) {
  185.             isDown = false;
  186.             super.enable();
  187.             repaint();
  188.         }
  189.     }
  190.  
  191.     /** Disables the button. A grayed-out version of the image is
  192.      *    shown.
  193.      */
  194.     public void disable() {
  195.         if (isEnabled()) {
  196.             isDown = false;
  197.             super.disable();
  198.             repaint();
  199.         }
  200.     }
  201.  
  202.     /** Resize the button the the size of its image plus padding
  203.      *    and border.
  204.      */
  205.     public void resize() {
  206.         Font f = getFont();
  207.         FontMetrics fm = null;
  208.         if (f != null && label != null)
  209.             fm = getToolkit().getFontMetrics(f);
  210.  
  211.         int iw=0, ih=0, _gap=0;
  212.  
  213.         if (img != null) {
  214.             iw = (int) (img.getWidth(this) * imageScale);
  215.             ih = (int) (img.getHeight(this) * imageScale);
  216.             _gap = gap;
  217.         }
  218.  
  219.         int w, h;
  220.         w = iw + (2*(padding+borderW));
  221.         h = ih + (2*(padding+borderW));
  222.  
  223.         if (fm != null) {
  224.             if (pos == LEFT || pos == RIGHT) {
  225.                 w += _gap + fm.stringWidth(label);
  226.  
  227.                 // Cuz the text could be taller than the image
  228.                 h = Math.max(h, fm.getAscent() + (2*(padding+borderW)));
  229.             }
  230.             else {
  231.                 h += _gap + fm.getAscent();
  232.  
  233.                 // Cause the text could be wider than the image
  234.                 w = Math.max(w, fm.stringWidth(label) + (2*(padding+borderW)));
  235.             }
  236.         }
  237.  
  238.         resize(w, h);
  239.     }
  240.  
  241.     protected void repaintImage() {
  242.         if (img != null) {
  243.             Graphics g = getGraphics();
  244.             if (g == null) return;
  245.             g.clearRect(ix, iy, iw, ih);
  246.             if (imageScale == 1)
  247.                 g.drawImage(isEnabled() ? img : inactive_img, ix, iy, this);
  248.             else g.drawImage(isEnabled() ? img : inactive_img, ix, iy, iw, ih, this);
  249.         }
  250.     }
  251.  
  252.     public synchronized void paint(Graphics g) {
  253.         if (!isEnabled() && inactive_img == null) {
  254.             inactive_img = ImagePanel.createDisabledImage(img, this);
  255.         }
  256.  
  257.         int w = size().width;
  258.         int h = size().height;
  259.  
  260.         if (fShowBorder) {
  261.             Rectangle3D r = new Rectangle3D(this, 0, 0, w, h);
  262.  
  263.             if (isDown && fDrawPushedIn) r.setDrawingMode(Rectangle3D.IN);
  264.             else r.setDrawingMode(Rectangle3D.OUT);
  265.  
  266.             r.paint(g);
  267.         }
  268.  
  269.         int o = padding + borderW + ((isDown && fDrawPushedIn) ? 1 : 0);
  270.  
  271.         iw=0; ih=0;
  272.         int _gap=0;
  273.  
  274.         if (img != null) {
  275.             iw = (int) (img.getWidth(this) * imageScale);
  276.             ih = (int) (img.getHeight(this) * imageScale);
  277.             _gap = gap;
  278.         }
  279.  
  280.         FontMetrics fm=null;
  281.  
  282.         if (label != null) {
  283.             fm = getFontMetrics(getFont());
  284.  
  285.             if (pos == RIGHT) ix = o;
  286.             else if (pos == LEFT) ix = o + _gap + fm.stringWidth(label);
  287.             else ix = (int) ((w-iw)/2) + ((isDown && fDrawPushedIn) ? 1 : 0);
  288.  
  289.             if (pos == TOP) iy = o + _gap + fm.getAscent();
  290.             else if (pos == BOTTOM) iy = o;
  291.             else iy = (int) ((h-ih)/2) + ((isDown && fDrawPushedIn) ? 1 : 0);
  292.         }
  293.         else { ix = iy = o; }
  294.  
  295.         repaintImage();
  296.  
  297.         int x, y;
  298.         if (label != null) {
  299.  
  300.             if (pos == LEFT) x = o;
  301.             else if (pos == RIGHT) x = o + _gap + iw;
  302.             else x = (int) ((w-fm.stringWidth(label))/2)
  303.                         + ((isDown && fDrawPushedIn) ? 1 : 0);
  304.  
  305.             if (pos == TOP) y = o + fm.getAscent();
  306.             else if (pos == BOTTOM) y = o + _gap + fm.getAscent() + ih;
  307.             else y = h - (int) ((h-fm.getAscent())/2)
  308.                         + ((isDown && fDrawPushedIn) ? 1 : 0) - 1;
  309.  
  310.             g.setColor(getForeground());
  311.  
  312.             if (!isEnabled()) {
  313.                 g.setColor(Color.white);
  314.                 g.drawString(label, x+1, y+1);
  315.                 g.setColor(getBackground().darker());
  316.             }
  317.  
  318.             g.drawString(label, x, y);
  319.         }
  320.     }
  321.  
  322.     public boolean mouseDown(Event e, int x, int y) {
  323.         if (isEnabled()) {
  324.             isDown = true;
  325.             repaint();
  326.             if (audio != null) audio.play();
  327.         }
  328.         return true;
  329.     }
  330.  
  331.     public boolean mouseUp(Event e, int x, int y) {
  332.         if (isEnabled() && isDown) {
  333.             isDown = false;
  334.             repaint();
  335.             e.id = Event.ACTION_EVENT;
  336.             postEvent(e);
  337.         }
  338.         return true;
  339.     }
  340.  
  341.     public boolean mouseExit(Event e, int x, int y) {
  342.         if (isEnabled() && isDown) {
  343.             isDown = false;
  344.             repaint();
  345.         }
  346.         return true;
  347.     }
  348. }
  349.