Java Tutorial/Swing/Icon — различия между версиями

Материал из Java эксперт
Перейти к: навигация, поиск
м (1 версия)
 
(нет различий)

Текущая версия на 15:32, 31 мая 2010

14. An empty icon with arbitrary width and height.

/**
 * @PROJECT.FULLNAME@ @VERSION@ License.
 *
 * Copyright @YEAR@ L2FProd.ru
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.awt.ruponent;
import java.awt.Graphics;
import javax.swing.Icon;
/**
 * An empty icon with arbitrary width and height.
 */
public final class EmptyIcon implements Icon {
  private int width;
  private int height;
  
  public EmptyIcon() {
    this(0, 0);
  }
  
  public EmptyIcon(int width, int height) {
    this.width = width;
    this.height = height;
  }
  public int getIconHeight() {
    return height;
  }
  public int getIconWidth() {
    return width;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
  }
}





14. An icon for painting a square swatch of a specified Color.

/*
 *  ColorSwatch.java
 *  2007-03-03
 */
//cb.aloe.decor;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import javax.swing.Icon;
/**
 * An icon for painting a square swatch of a specified Color.
 * 
 * @author Christopher Bach
 */
public class ColorSwatch implements Icon {
  private Color ourSwatchColor = Color.white;
  private Color ourBorderColor = Color.black;
  private boolean ourBorderPainted = true;
  private boolean ourSwatchIsMultiColor = false;
  private boolean ourSwatchIsVoid = false;
  private int ourSwatchSize = 14;
  /**
   * Creates a standard 14 x 14 swatch with a black border and white background.
   */
  public ColorSwatch() {
  }
  /**
   * Creates a swatch of the specified size with a black border and white
   * background.
   */
  public ColorSwatch(int size) {
    setSwatchSize(size);
  }
  /**
   * Creates a swatch of the specified size with a black border and white
   * background and determines whether or n not the border should be painted.
   */
  public ColorSwatch(int size, boolean borderPainted) {
    setSwatchSize(size);
    setBorderPainted(borderPainted);
  }
  /**
   * 
   */
  public ColorSwatch(Color color) {
    setColor(color);
  }
  /**
   * 
   */
  public ColorSwatch(int size, Color color) {
    setSwatchSize(size);
    setColor(color);
  }
  /**
   * 
   */
  public ColorSwatch(int size, Color color, Color borderColor) {
    setSwatchSize(size);
    setColor(color);
    setBorderColor(borderColor);
    setBorderPainted(true);
  }
  /**
   * Sets the size of this swatch.
   */
  public void setSwatchSize(int size) {
    if (size > 0)
      ourSwatchSize = size;
    else
      ourSwatchSize = 14;
  }
  /**
   * Returns the size of this swatch.
   */
  public int getSwatchSize() {
    return ourSwatchSize;
  }
  /**
   * Determines whether or not this swatch"s border should be painted.
   */
  public void setBorderPainted(boolean borderPainted) {
    ourBorderPainted = borderPainted;
  }
  /**
   * Returns whether or not this swatch"s border is painted.
   */
  public boolean isBorderPainted() {
    return ourBorderPainted;
  }
  /**
   * Sets the color of this swatch"s border.
   */
  public void setBorderColor(Color color) {
    ourBorderColor = color;
  }
  /**
   * Returns the color of this swatch"s border.
   */
  public Color getBorderColor() {
    return ourBorderColor;
  }
  /**
   * Sets the color that this swatch represents.
   */
  public void setColor(Color color) {
    ourSwatchIsMultiColor = false;
    ourSwatchColor = color;
  }
  /**
   * Returns the color that this swatch represents.
   */
  public Color getColor() {
    return ourSwatchColor;
  }
  /**
   * Sets this swatch to represent more than one color.
   */
  public void setMultiColor() {
    ourSwatchIsMultiColor = true;
  }
  /**
   * Returns whether or not this swatch represents more than one color.
   */
  public boolean isMultiColor() {
    return ourSwatchIsMultiColor;
  }
  /**
   * Determines whether or not this swatch is void. If the swatch is void, it
   * will not be painted at all.
   */
  public void setVoid(boolean isVoid) {
    // When true, this icon will not be painted at all.
    ourSwatchIsVoid = isVoid;
  }
  /**
   * Returns whether this swatch is void. If the swatch is void, it will not be
   * painted at all.
   */
  public boolean isVoid() {
    return ourSwatchIsVoid;
  }
  // // Icon implementation ////
  /**
   * Returns the width of this Icon.
   */
  public int getIconWidth() {
    return ourSwatchSize;
  }
  /**
   * Returns the height of this Icon.
   */
  public int getIconHeight() {
    return ourSwatchSize;
  }
  /**
   * Paints this Icon into the provided graphics context.
   */
  public void paintIcon(Component c, Graphics g, int x, int y) {
    if (ourSwatchIsVoid)
      return;
    Color oldColor = g.getColor();
    if (ourSwatchIsMultiColor) {
      g.setColor(Color.white);
      g.fillRect(x, y, ourSwatchSize, ourSwatchSize);
      g.setColor(ourBorderColor);
      for (int i = 0; i < ourSwatchSize; i += 2) {
        g.drawLine(x + i, y, x + i, y + ourSwatchSize);
      }
    }
    else if (ourSwatchColor != null) {
      g.setColor(ourSwatchColor);
      g.fillRect(x, y, ourSwatchSize, ourSwatchSize);
    }
    else {
      g.setColor(Color.white);
      g.fillRect(x, y, ourSwatchSize, ourSwatchSize);
      g.setColor(ourBorderColor);
      g.drawLine(x, y, x + ourSwatchSize, y + ourSwatchSize);
      g.drawLine(x, y + ourSwatchSize, x + ourSwatchSize, y);
    }
    if (ourBorderPainted) {
      g.setColor(ourBorderColor);
      g.drawRect(x, y, ourSwatchSize, ourSwatchSize);
    }
    g.setColor(oldColor);
  }
}





14. Arrow Icon

/*
 * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
/**
 *
 * @author Administrator
 */
public class ArrowIcon implements Icon, SwingConstants {
    private static final float DB = -.06f;
    private int direction;
    private int size;
    private Color color;
    private BufferedImage arrowImage;
    
    public ArrowIcon(int direction) {
        this(direction, 10, null);
    }
    
    public ArrowIcon(int direction, Color color) {
        this(direction, 10, color);
    }
    
    public ArrowIcon(int direction, int size, Color color) {
        this.size = size;
        this.direction = direction;
        this.color = color;
    }
    public int getIconHeight() {        
        return size;
    }
    public int getIconWidth() {
        return size;
    }
    public void paintIcon(Component c, Graphics g, int x, int y) {
        g.drawImage(getArrowImage(), x, y, c);
    }
    public static BufferedImage createTranslucentImage(int width, int height) {
      
      return GraphicsEnvironment.getLocalGraphicsEnvironment().
                  getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
             
  }
    protected Image getArrowImage() {
        if (arrowImage == null) {
            arrowImage = createTranslucentImage(size, size);
            AffineTransform atx = direction != SOUTH? new AffineTransform() : null;
            switch(direction ) {
                case NORTH:
                    atx.setToRotation(Math.PI, size/2, size/2);
                    break;
                case EAST:
                    atx.setToRotation(-(Math.PI/2), size/2, size/2);
                    break;
                case WEST:
                    atx.setToRotation(Math.PI/2, size/2, size/2);
                case SOUTH:
                default:{ /* no xform*/ }                   
            }       
            Graphics2D ig = (Graphics2D)arrowImage.getGraphics();
            if (atx != null) {
                ig.setTransform(atx);
            }
            int width = size;
            int height = size/2 + 1;
            int xx = (size - width)/2;
            int yy = (size - height + 1)/2;
            Color base = color != null? color : UIManager.getColor("controlDkShadow").darker(); 
            paintArrow(ig, base, xx, yy);
            paintArrowBevel(ig, base, xx, yy);
            paintArrowBevel(ig, deriveColorHSB(base, 0f, 0f, .20f), xx, yy + 1);
        }
        return arrowImage;
    }
    
    protected void paintArrow(Graphics2D g, Color base, int x, int y) {
        g.setColor(base);
        /*
        Path2D.Float arrowShape = new Path2D.Float();
        arrowShape.moveTo(x, y-1);
        System.out.println("moveTo "+(x)+","+(y-1));
        arrowShape.lineTo(size-1, y-1);
        System.out.println("lineTo "+(size-1)+","+(y-1));
        arrowShape.lineTo(size/2, y+(size/2));
        System.out.println("lineTo "+(size/2)+","+(y+(size/2)));
        arrowShape.lineTo(size/2 - 1, y+(size/2));
        System.out.println("lineTo "+ (size/2 - 1)+","+(y+(size/2)));
        arrowShape.lineTo(x, y-1);
        System.out.println("lineTo "+(x)+","+(y-1));
        g.fill(arrowShape);
*/       
        int len = size - 2;
        int xx = x;
        int yy = y-1;
        while (len >= 2) {
            xx++;
            yy++;
            g.fillRect(xx, yy, len, 1);
            len -= 2;
        }
    }
    protected void paintArrowBevel(Graphics g, Color base, int x, int y) {
        int len = size;
        int xx = x;
        int yy = y;
        Color c2 = deriveColorHSB(base, 0f, 0f, (-DB)*(size/2));
        while (len >= 2) {
            c2 = deriveColorHSB(c2, 0f, 0f, DB);
            g.setColor(c2);
            g.fillRect(xx, yy, 1, 1);
            g.fillRect(xx + len - 1, yy, 1, 1);
            len -= 2;
            xx++;
            yy++;
        }
    }
    
    /**
     * Derives a color by adding the specified offsets to the base color"s 
     * hue, saturation, and brightness values.   The resulting hue, saturation,
     * and brightness values will be contrained to be between 0 and 1.
     * @param base the color to which the HSV offsets will be added
     * @param dH the offset for hue
     * @param dS the offset for saturation
     * @param dB the offset for brightness
     * @return Color with modified HSV values
     */
    public static Color deriveColorHSB(Color base, float dH, float dS, float dB) {
        float hsb[] = Color.RGBtoHSB(
                base.getRed(), base.getGreen(), base.getBlue(), null);
        hsb[0] += dH;
        hsb[1] += dS;
        hsb[2] += dB;
        return Color.getHSBColor(
                hsb[0] < 0? 0 : (hsb[0] > 1? 1 : hsb[0]),
                hsb[1] < 0? 0 : (hsb[1] > 1? 1 : hsb[1]),
                hsb[2] < 0? 0 : (hsb[2] > 1? 1 : hsb[2]));
                                               
    }
    public static void main(String args[]) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.add(panel);
        
        panel.add(new JLabel("north", new ArrowIcon(ArrowIcon.NORTH), JLabel.CENTER));
        panel.add(new JLabel("west", new ArrowIcon(ArrowIcon.WEST), JLabel.CENTER));
        panel.add(new JLabel("south", new ArrowIcon(ArrowIcon.SOUTH), JLabel.CENTER));
        panel.add(new JLabel("east", new ArrowIcon(ArrowIcon.EAST), JLabel.CENTER));
        panel.add(new JLabel("east-20", new ArrowIcon(ArrowIcon.EAST, 20, Color.blue), JLabel.CENTER));
        
        frame.pack();
        frame.setVisible(true);
    }
}





14. Creates a transparent icon.

import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.swing.Icon;
import javax.swing.ImageIcon;

public final class ImageUtils
{

  /**
   * Creates a transparent image.  These can be used for aligning menu items.
   *
   * @param width  the width.
   * @param height the height.
   * @return the created transparent image.
   */
  public static BufferedImage createTransparentImage (final int width, final int height)
  {
    return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  }
  /**
   * Creates a transparent icon. The Icon can be used for aligning menu items.
   *
   * @param width  the width of the new icon
   * @param height the height of the new icon
   * @return the created transparent icon.
   */
  public static Icon createTransparentIcon (final int width, final int height)
  {
    return new ImageIcon(createTransparentImage(width, height));
  }
}





14. Creating an Icon(implement Icon interface)

import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.Icon;
class DiamondIcon implements Icon {
  public DiamondIcon() {
  }
  public int getIconHeight() {
    return 20;
  }
  public int getIconWidth() {
    return 20;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    g.setColor(color);
    g.drawRect(0,0,20,20);
  }
}





14. Demonstrate the loading of image files into icons for use in a Swing user interface

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
 * This application is intended to demonstrate the loading of image files into
 * icons for use in a Swing user interface. It creates a toolbar with a
 * thumbnail preview of each image. Clicking on the thumbnail will show the full
 * image in the main display area.
 * 
 * IconDemoApp.java requires the following files: <br>
 * The following files are copyright 2006 spriggs.net and licensed under a
 * Creative Commons License (http://creativecommons.org/licenses/by-sa/3.0/)
 * <br>
 * images/sunw01.jpg <br>
 * images/sunw02.jpg <br>
 * images/sunw03.jpg <br>
 * images/sunw04.jpg <br>
 * images/sunw05.jpg <br>
 * 
 * @author Collin Fagan
 * @date 7/25/2007
 * @version 2.0
 */
public class IconDemoApp extends JFrame {
  private JLabel photographLabel = new JLabel();
  private JToolBar buttonBar = new JToolBar();
  private String imagedir = "images/";
  private MissingIcon placeholderIcon = new MissingIcon();
  /**
   * List of all the descriptions of the image files. These correspond one to
   * one with the image file names
   */
  private String[] imageCaptions = { "Original SUNW Logo", "The Clocktower",
      "Clocktower from the West", "The Mansion", "Sun Auditorium" };
  /**
   * List of all the image files to load.
   */
  private String[] imageFileNames = { "sunw01.jpg", "sunw02.jpg", "sunw03.jpg",
      "sunw04.jpg", "sunw05.jpg" };
  /**
   * Main entry point to the demo. Loads the Swing elements on the "Event
   * Dispatch Thread".
   * 
   * @param args
   */
  public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        IconDemoApp app = new IconDemoApp();
        app.setVisible(true);
      }
    });
  }
  /**
   * Default constructor for the demo.
   */
  public IconDemoApp() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Icon Demo: Please Select an Image");
    // A label for displaying the pictures
    photographLabel.setVerticalTextPosition(JLabel.BOTTOM);
    photographLabel.setHorizontalTextPosition(JLabel.CENTER);
    photographLabel.setHorizontalAlignment(JLabel.CENTER);
    photographLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    // We add two glue components. Later in process() we will add thumbnail
    // buttons
    // to the toolbar inbetween thease glue compoents. This will center the
    // buttons in the toolbar.
    buttonBar.add(Box.createGlue());
    buttonBar.add(Box.createGlue());
    add(buttonBar, BorderLayout.SOUTH);
    add(photographLabel, BorderLayout.CENTER);
    setSize(400, 300);
    // this centers the frame on the screen
    setLocationRelativeTo(null);
    // start the image loading SwingWorker in a background thread
    loadimages.execute();
  }
  /**
   * SwingWorker class that loads the images a background thread and calls
   * publish when a new one is ready to be displayed.
   * 
   * We use Void as the first SwingWroker param as we do not need to return
   * anything from doInBackground().
   */
  private SwingWorker<Void, ThumbnailAction> loadimages = new SwingWorker<Void, ThumbnailAction>() {
    /**
     * Creates full size and thumbnail versions of the target image files.
     */
    @Override
    protected Void doInBackground() throws Exception {
      for (int i = 0; i < imageCaptions.length; i++) {
        ImageIcon icon;
        icon = createImageIcon(imagedir + imageFileNames[i], imageCaptions[i]);
        ThumbnailAction thumbAction;
        if (icon != null) {
          ImageIcon thumbnailIcon = new ImageIcon(getScaledImage(icon
              .getImage(), 32, 32));
          thumbAction = new ThumbnailAction(icon, thumbnailIcon,
              imageCaptions[i]);
        } else {
          // the image failed to load for some reason
          // so load a placeholder instead
          thumbAction = new ThumbnailAction(placeholderIcon, placeholderIcon,
              imageCaptions[i]);
        }
        publish(thumbAction);
      }
      // unfortunately we must return something, and only null is valid to
      // return when the return type is void.
      return null;
    }
    /**
     * Process all loaded images.
     */
    @Override
    protected void process(List<ThumbnailAction> chunks) {
      for (ThumbnailAction thumbAction : chunks) {
        JButton thumbButton = new JButton(thumbAction);
        // add the new button BEFORE the last glue
        // this centers the buttons in the toolbar
        buttonBar.add(thumbButton, buttonBar.getComponentCount() - 1);
      }
    }
  };
  /**
   * Creates an ImageIcon if the path is valid.
   * 
   * @param String -
   *            resource path
   * @param String -
   *            description of the file
   */
  protected ImageIcon createImageIcon(String path, String description) {
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL, description);
    } else {
      System.err.println("Couldn"t find file: " + path);
      return null;
    }
  }
  /**
   * Resizes an image using a Graphics2D object backed by a BufferedImage.
   * 
   * @param srcImg -
   *            source image to scale
   * @param w -
   *            desired width
   * @param h -
   *            desired height
   * @return - the new resized image
   */
  private Image getScaledImage(Image srcImg, int w, int h) {
    BufferedImage resizedImg = new BufferedImage(w, h,
        BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = resizedImg.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.drawImage(srcImg, 0, 0, w, h, null);
    g2.dispose();
    return resizedImg;
  }
  /**
   * Action class that shows the image specified in it"s constructor.
   */
  private class ThumbnailAction extends AbstractAction {
    /**
     * The icon if the full image we want to display.
     */
    private Icon displayPhoto;
    /**
     * @param Icon -
     *            The full size photo to show in the button.
     * @param Icon -
     *            The thumbnail to show in the button.
     * @param String -
     *            The descriptioon of the icon.
     */
    public ThumbnailAction(Icon photo, Icon thumb, String desc) {
      displayPhoto = photo;
      // The short description becomes the tooltip of a button.
      putValue(SHORT_DESCRIPTION, desc);
      // The LARGE_ICON_KEY is the key for setting the
      // icon when an Action is applied to a button.
      putValue(LARGE_ICON_KEY, thumb);
    }
    /**
     * Shows the full image in the main area and sets the application title.
     */
    public void actionPerformed(ActionEvent e) {
      photographLabel.setIcon(displayPhoto);
      setTitle("Icon Demo: " + getValue(SHORT_DESCRIPTION).toString());
    }
  }
}
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *  - Neither the name of Sun Microsystems nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * The "missing icon" is a white box with a black border and a red x. It"s used
 * to display something when there are issues loading an icon from an external
 * location.
 * 
 * @author Collin Fagan
 * @date 7/25/2007
 */
class MissingIcon implements Icon {
  private int width = 32;
  private int height = 32;
  private BasicStroke stroke = new BasicStroke(4);
  public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setColor(Color.WHITE);
    g2d.fillRect(x + 1, y + 1, width - 2, height - 2);
    g2d.setColor(Color.BLACK);
    g2d.drawRect(x + 1, y + 1, width - 2, height - 2);
    g2d.setColor(Color.RED);
    g2d.setStroke(stroke);
    g2d.drawLine(x + 10, y + 10, x + width - 10, y + height - 10);
    g2d.drawLine(x + 10, y + height - 10, x + width - 10, y + 10);
    g2d.dispose();
  }
  public int getIconWidth() {
    return width;
  }
  public int getIconHeight() {
    return height;
  }
}





14. implements Icon, SwingConstants

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
/*
 * CustomIconDemo.java (based on ButtonDemo.java) requires the following files:
 * ArrowIcon.java images/middle.gif
 */
public class CustomIconDemo extends JPanel implements ActionListener {
  protected JButton b1, b2, b3;
  public CustomIconDemo() {
    Icon leftButtonIcon = new ArrowIcon(SwingConstants.RIGHT);
    Icon middleButtonIcon = createImageIcon("images/middle.gif",
        "the middle button");
    Icon rightButtonIcon = new ArrowIcon(SwingConstants.LEFT);
    b1 = new JButton("Disable middle button", leftButtonIcon);
    b1.setVerticalTextPosition(AbstractButton.CENTER);
    b1.setHorizontalTextPosition(AbstractButton.LEADING);
    b1.setMnemonic(KeyEvent.VK_D);
    b1.setActionCommand("disable");
    b2 = new JButton("Middle button", middleButtonIcon);
    b2.setVerticalTextPosition(AbstractButton.BOTTOM);
    b2.setHorizontalTextPosition(AbstractButton.CENTER);
    b2.setMnemonic(KeyEvent.VK_M);
    b3 = new JButton("Enable middle button", rightButtonIcon);
    // Use the default text position of CENTER, TRAILING (RIGHT).
    b3.setMnemonic(KeyEvent.VK_E);
    b3.setActionCommand("enable");
    b3.setEnabled(false);
    // Listen for actions on buttons 1 and 3.
    b1.addActionListener(this);
    b3.addActionListener(this);
    b1.setToolTipText("Click this button to disable the middle button.");
    b2.setToolTipText("This middle button does nothing when you click it.");
    b3.setToolTipText("Click this button to enable the middle button.");
    // Add Components to this container, using the default FlowLayout.
    add(b1);
    add(b2);
    add(b3);
  }
  public void actionPerformed(ActionEvent e) {
    if ("disable".equals(e.getActionCommand())) {
      b2.setEnabled(false);
      b1.setEnabled(false);
      b3.setEnabled(true);
    } else {
      b2.setEnabled(true);
      b1.setEnabled(true);
      b3.setEnabled(false);
    }
  }
  /** Returns an ImageIcon, or null if the path was invalid. */
  protected static ImageIcon createImageIcon(String path, String description) {
    java.net.URL imgURL = CustomIconDemo.class.getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL, description);
    } else {
      System.err.println("Couldn"t find file: " + path);
      return null;
    }
  }
  /**
   * Create the GUI and show it. For thread safety, this method should be
   * invoked from the event-dispatching thread.
   */
  private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("CustomIconDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Set up the content pane.
    JComponent newContentPane = new CustomIconDemo();
    newContentPane.setOpaque(true); // content panes must be opaque
    frame.setContentPane(newContentPane);
    // Display the window.
    frame.pack();
    frame.setVisible(true);
  }
  public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application"s GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *  - Neither the name of Sun Microsystems nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/* This class is used by CustomIconDemo.java. */
class ArrowIcon implements Icon, SwingConstants {
  private int width = 9;
  private int height = 18;
  private int[] xPoints = new int[4];
  private int[] yPoints = new int[4];
  public ArrowIcon(int direction) {
    if (direction == LEADING) {
      xPoints[0] = width;
      yPoints[0] = -1;
      xPoints[1] = width;
      yPoints[1] = height;
      xPoints[2] = 0;
      yPoints[2] = height / 2;
      xPoints[3] = 0;
      yPoints[3] = height / 2 - 1;
    } else /* direction == TRAILING */{
      xPoints[0] = 0;
      yPoints[0] = -1;
      xPoints[1] = 0;
      yPoints[1] = height;
      xPoints[2] = width;
      yPoints[2] = height / 2;
      xPoints[3] = width;
      yPoints[3] = height / 2 - 1;
    }
  }
  public int getIconHeight() {
    return height;
  }
  public int getIconWidth() {
    return width;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    if (c.isEnabled()) {
      g.setColor(c.getForeground());
    } else {
      g.setColor(Color.gray);
    }
    g.translate(x, y);
    g.fillPolygon(xPoints, yPoints, xPoints.length);
    g.translate(-x, -y); // Restore graphics object
  }
}





14. Layered Icon

/*
 *  LayeredIcon.java
 *  2006-08-09
 */
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.SwingConstants;
/**
 * @author Christopher Bach
 */
public class LayeredIcon implements Icon {
  public static final int TOP = SwingConstants.TOP, LEFT = SwingConstants.LEFT,
      BOTTOM = SwingConstants.BOTTOM, RIGHT = SwingConstants.RIGHT, CENTER = SwingConstants.CENTER;
  private Dimension ourPrefSize = new Dimension(0, 0);
  private ArrayList ourLayers = new ArrayList();
  private Insets ourPadding = new Insets(0, 0, 0, 0);
  /**
   * 
   */
  public LayeredIcon() {
  }
  /**
   * 
   */
  public LayeredIcon(int padding) {
    setPadding(padding, padding, padding, padding);
  }
  /**
   * Creates a new instance of LayeredIcon with the specified width and height,
   * but no graphic.
   */
  public LayeredIcon(int width, int height) {
    setIconSize(width, height);
  }
  /**
   * 
   */
  public LayeredIcon(int width, int height, int padding) {
    setIconSize(width, height);
    setPadding(padding, padding, padding, padding);
  }
  /**
   * 
   */
  public LayeredIcon(int topPadding, int leftPadding, int bottomPadding, int rightPadding) {
    setPadding(topPadding, leftPadding, bottomPadding, rightPadding);
  }
  /**
   * 
   */
  public LayeredIcon(int width, int height, int topPadding, int leftPadding, int bottomPadding,
      int rightPadding) {
    setIconSize(width, height);
    setPadding(topPadding, leftPadding, bottomPadding, rightPadding);
  }
  /**
   * If any client Icons have been added and painting is enabled, paints the
   * client Icons at the specified coordinates into the provided graphics
   * context for the indicated Component.
   */
  public void paintIcon(Component c, Graphics g, int x, int y) {
    Dimension iconSize = getIconSize();
    for (int i = 0, size = ourLayers.size(); i < size; i++) {
      Layer layer = (Layer) ourLayers.get(i);
      if (layer.painted) {
        int w = layer.icon.getIconWidth();
        int h = layer.icon.getIconHeight();
        int dx = (layer.halign == LEFT ? 0 : iconSize.width - w);
        if (layer.halign != RIGHT)
          dx = dx / 2;
        dx += ourPadding.left;
        int dy = (layer.valign == TOP ? 0 : iconSize.height - h);
        if (layer.valign != BOTTOM)
          dy = dy / 2;
        dy += ourPadding.top;
        layer.icon.paintIcon(c, g, x + dx, y + dy);
      }
    }
  }
  /**
   * Returns the width of the LayeredIcon. If any client Icons have been added,
   * returns the max width of all client Icons. Otherwise, returns the
   * LayeredIcon"s explicit width.
   */
  public int getIconWidth() {
    return getIconSize().width + ourPadding.left + ourPadding.right;
  }
  /**
   * Returns the height of the LayeredIcon. If any client Icons have been added,
   * returns the max height of all client Icons. Otherwise, returns the
   * LayeredIcon"s explicit height.
   */
  public int getIconHeight() {
    return getIconSize().height + ourPadding.top + ourPadding.bottom;
  }
  /**
   * Sets the explicit size of the LayeredIcon to be used when no client Icons
   * have been added.
   */
  public void setIconSize(int width, int height) {
    ourPrefSize.width = width;
    ourPrefSize.height = height;
  }
  /**
   * 
   */
  public void setPadding(int padding) {
    ourPadding.top = padding;
    ourPadding.left = padding;
    ourPadding.bottom = padding;
    ourPadding.right = padding;
  }
  /**
   * 
   */
  public void setPadding(int topPadding, int leftPadding, int bottomPadding, int rightPadding) {
    ourPadding.top = topPadding;
    ourPadding.left = leftPadding;
    ourPadding.bottom = bottomPadding;
    ourPadding.right = rightPadding;
  }
  /**
   * 
   */
  public Insets getPadding() {
    return new Insets(ourPadding.top, ourPadding.left, ourPadding.bottom, ourPadding.right);
  }
  /**
   * 
   */
  public void addIcon(Icon icon) {
    if (icon != null) {
      ourLayers.add(new Layer(icon));
    }
  }
  /**
   * 
   */
  public void addIcon(Icon icon, int index) {
    if (icon != null && index >= 0 && index <= ourLayers.size()) {
      ourLayers.add(index, new Layer(icon));
    }
  }
  /**
   * 
   */
  public void addIcon(Icon icon, int halign, int valign) {
    if (icon != null) {
      ourLayers.add(new Layer(icon, checkHAlign(halign), checkVAlign(valign)));
    }
  }
  /**
   * 
   */
  public void addIcon(Icon icon, int index, int halign, int valign) {
    if (icon != null && index >= 0 && index <= ourLayers.size()) {
      ourLayers.add(index, new Layer(icon, checkHAlign(halign), checkVAlign(valign)));
    }
  }
  /**
   * 
   */
  public void removeIcon(Icon icon) {
    Layer layer = getLayer(icon);
    if (layer != null) {
      ourLayers.remove(layer);
    }
  }
  /**
   * 
   */
  public void clear() {
    ourLayers.clear();
  }
  /**
   * 
   */
  public Icon getIcon(int index) {
    Layer layer = (Layer) ourLayers.get(index);
    if (layer != null)
      return layer.icon;
    else
      return null;
  }
  /**
   * 
   */
  public int indexOf(Icon icon) {
    for (int i = 0, size = ourLayers.size(); i < size; i++) {
      Layer layer = (Layer) ourLayers.get(i);
      if (layer.icon == icon)
        return i;
    }
    return -1;
  }
  /**
   * 
   */
  public int iconCount() {
    return ourLayers.size();
  }
  /**
   * 
   */
  public boolean isIconPainted(int iconIndex) {
    Layer layer = (Layer) ourLayers.get(iconIndex);
    if (layer != null)
      return layer.painted;
    else
      return false;
  }
  /**
   * 
   */
  public void setIconPainted(int iconIndex, boolean painted) {
    Layer layer = (Layer) ourLayers.get(iconIndex);
    if (layer != null)
      layer.painted = painted;
  }
  /**
   * 
   */
  public boolean isIconPainted(Icon icon) {
    Layer layer = getLayer(icon);
    if (layer != null)
      return layer.painted;
    else
      return false;
  }
  /**
   * 
   */
  public void setIconPainted(Icon icon, boolean painted) {
    Layer layer = getLayer(icon);
    if (layer != null)
      layer.painted = painted;
  }
  /**
   * 
   */
  public void setIconAlignment(Icon icon, int halign, int valign) {
    Layer layer = getLayer(icon);
    if (layer != null) {
      layer.halign = checkHAlign(halign);
      layer.valign = checkVAlign(valign);
    }
  }
  /**
   * 
   */
  public void setIconAlignment(int iconIndex, int halign, int valign) {
    Layer layer = (Layer) ourLayers.get(iconIndex);
    if (layer != null) {
      layer.halign = checkHAlign(halign);
      layer.valign = checkVAlign(valign);
    }
  }
  /**
   * 
   */
  public int getIconHAlignment(Icon icon) {
    Layer layer = getLayer(icon);
    if (layer != null)
      return layer.halign;
    else
      return CENTER;
  }
  /**
   * 
   */
  public int getIconVAlignment(Icon icon) {
    Layer layer = getLayer(icon);
    if (layer != null)
      return layer.valign;
    else
      return CENTER;
  }
  /**
   * 
   */
  public int getIconHAlignment(int iconIndex) {
    Layer layer = (Layer) ourLayers.get(iconIndex);
    if (layer != null)
      return layer.halign;
    else
      return CENTER;
  }
  /**
   * 
   */
  public int getIconVAlignment(int iconIndex) {
    Layer layer = (Layer) ourLayers.get(iconIndex);
    if (layer != null)
      return layer.valign;
    else
      return CENTER;
  }
  /**
   * 
   */
  private int checkHAlign(int halign) {
    if (halign != LEFT && halign != RIGHT && halign != CENTER)
      return CENTER;
    else
      return halign;
  }
  /**
   * 
   */
  private int checkVAlign(int valign) {
    if (valign != TOP && valign != BOTTOM && valign != CENTER)
      return CENTER;
    else
      return valign;
  }
  /**
   * 
   */
  private Layer getLayer(Icon icon) {
    for (int i = 0, size = ourLayers.size(); i < size; i++) {
      Layer layer = (Layer) ourLayers.get(i);
      if (layer.icon == icon)
        return layer;
    }
    return null;
  }
  /**
   * 
   */
  private Dimension getIconSize() {
    if (ourLayers.size() == 0)
      return ourPrefSize;
    Dimension d = new Dimension(0, 0);
    for (int i = 0, size = ourLayers.size(); i < size; i++) {
      Layer layer = (Layer) ourLayers.get(i);
      d.height = Math.max(d.height, layer.icon.getIconHeight());
      d.width = Math.max(d.width, layer.icon.getIconWidth());
    }
    return d;
  }
  /**
   * 
   */
  private class Layer {
    public Icon icon = null;
    public boolean painted = true;
    public int halign = CENTER;
    public int valign = CENTER;
    public Layer() {
    }
    public Layer(Icon icon) {
      this.icon = icon;
    }
    public Layer(Icon icon, int halign, int valign) {
      this.icon = icon;
      this.halign = halign;
      this.valign = valign;
    }
  }
}





14. State-Aware Icon Definition

import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
class DiamondAbstractButtonStateIcon implements Icon {
  public DiamondAbstractButtonStateIcon() {
  }
  public int getIconHeight() {
    return 20;
  }
  public int getIconWidth() {
    return 20;
  }
  public void paintIcon(Component component, Graphics g, int x, int y) {
    if (component instanceof AbstractButton) {
      AbstractButton abstractButton = (AbstractButton) component;
      boolean selected = abstractButton.isSelected();
      if (selected) {
        g.setColor(Color.RED);
      } else {
        g.setColor(Color.BLUE);
      }
      g.drawRect(0, 0, 20, 20);
    
    }
  }
}
public class DiamondAbstractButtonStateIconDemo {
  public static void main(String[] a) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JCheckBox bn = new JCheckBox("Click to change the icon color");
    bn.setIcon(new DiamondAbstractButtonStateIcon());
    frame.add(bn);
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}