Child of ImageIcon overriding paintIcon() paints over JScrollPane

Here's a screenshot of the bottom icon painting over the scroll bar. I call super.paintIcon(...) through the hierarchy. My paintIcon(...) uses Java2D to paint the icon.

http://picasaweb.google.com/initialZero/Java

Any ideas what is causing this? I've seen similar things happen when JPanels override paint() and update() instead of using paintComponent().

[376 byte] By [bensteina] at [2007-11-27 6:39:00]
# 1

If you need further help then you need to create a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

Don't forget to use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] so the posted code retains its original formatting.

camickra at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...
# 2

These four classes clearly demonstrate the icon painting over other components when the window is resized or the tree is resized in a small window. I'm using JDK 1.6.0_01-b06 on GNU/Linux.

package icons;

import java.awt.Component;

import java.awt.Graphics;

import java.awt.Color;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.Shape;

import java.awt.geom.Rectangle2D;

/**

* This class is used to fill a box with color, for example to show the color of

* a route in a

* <tt>JTree<tt>. Note that due to recent additions, this object can be

* used as an empty placeholder icon if the background and color are set to 'clear'

* (as in transparent)

*

*/

public class CustomColor16 extends CustomIcon16 {

private boolean colorClear;

private Color borderColor = Color.BLACK;

private boolean borderClear;

private Color selectionColor = Color.BLACK;

/**

* Creates a new instance of CustomColor16, with the border black and the

* color white.

*/

public CustomColor16() {

super(CustomIcon16.T_CustomColor);

}

/**

* Creates a new <tt>CustomColor16</tt> with black border, white color,

* and an image.

*

* @param i

*An image to be displayed in this object.

*/

public CustomColor16(Image i) {

super(i, CustomIcon16.T_CustomColor);

}

/**

* Constructs a new CustomColor16 with black border, white color, and type.

*

* @param type

*/

protected CustomColor16(int type) {

super(type);

}

/**

* Setter method setting the color inside the border to be clear (that is

* not drawn).

*

* @param b

*true = the color inside the border to is clear

*/

public void setColorClear(boolean b) {

colorClear = b;

}

/**

* Getter method returning true if the color inside the border is clear.

*

* @return true if the color inside the border is clear.

*/

public boolean isColorClear() {

return colorClear;

}

/**

* Setter method setting the color of the border around the cell.

*

* @param c

*the color of the border around the cell.

*/

public void setBorderColor(Color c) {

borderColor = c;

}

/**

* Getter method getting the border <tt>Color</tt> of the icon.

*

* @return the border <tt>Color</tt> of the icon.

*/

public Color getBorderColor() {

return borderColor;

}

/**

* Setter method setting the border to be clear (that is not drawn).

*

* @param b

*true = the border is clear (that is not drawn).

*/

public void setBorderClear(boolean b) {

borderClear = b;

}

/**

* Getter method returning true if the border is not drawn (is transparent).

*

* @return true if the border is not drawn (is transparent).

*/

public boolean isBorderClear() {

return borderClear;

}

/**

* Overrides <tt>ImageIcon</tt>.paintIcon() draws to the icon. Paints the

* icon. The top-left corner of the icon is drawn at the point (<CODE>x</CODE>,

* <CODE>y</CODE>) in the coordinate space of the graphics context <CODE>g</CODE>.

* If this icon has no image observer, this method uses the <CODE>c</CODE>

* component as the observer.

*

* @param c

*the component to be used as the observer if this icon has no

*image observer

* @param g

*the graphics context

* @param x

*the X coordinate of the icon's top left corner

* @param y

*the Y coordinate of the icon's top right corner

*/

@Override

public void paintIcon(Component c, Graphics g, int x, int y) {

super.paintIcon(c, g, x, y);

if (!(colorClear) && (!(borderClear))) {

Graphics2D g2d = (Graphics2D) g;

Shape oldClip = g2d.getClip();

Rectangle2D.Double background = new Rectangle2D.Double(x + 1, y + 1, this.getWidth() - 1, this.getHeight() - 1);

Rectangle2D.Double border = new Rectangle2D.Double(x, y, this.getWidth(), this.getHeight());

g2d.setClip(new Rectangle2D.Double(x, y, this.getWidth() + 1, this.getHeight() + 1));

if (this.isDisabled()) {

g2d.setColor(Color.LIGHT_GRAY);

g2d.fill(background);

g2d.setColor(Color.GRAY);

g2d.draw(border);

} else {

g2d.setColor(colorClear ? Color.WHITE : this.getBackgroundColor());

g2d.fill(background);

g2d.setColor(borderClear ? Color.WHITE : borderColor);

g2d.draw(border);

}

g2d.setClip(oldClip);

}

}

public Color getSelectionColor() {

return selectionColor;

}

public void setSelectionColor(Color selectionColor) {

this.selectionColor = selectionColor;

}

}

package icons;

import java.awt.AlphaComposite;

import java.awt.Color;

import java.awt.Component;

import java.awt.Composite;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.Shape;

import java.awt.geom.Rectangle2D;

import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;

public class CustomIcon16 extends javax.swing.ImageIcon {

//added these constants to act as an enumeration for the purpose of creating

//a rudimentary "type" system to facilitate comparison of icons

public final static int T_CustomColor = 2;

public final static int T_Symbol = 6;

private final int type;

public int getType(){

return type;

}

/**

* If the icon is purely software-made, use this constructor.

*/

public CustomIcon16(int type) {

super();

this.type = type;

codeOnly = true;

disabled = false;

}

/**

* If the Icon uses a pre-existing icon from file, this constructor should

* be used.

*

* @param i

*An image used in this tree icon. Such a folder icon.

*/

public CustomIcon16(Image i, int type) {

super(i);

this.type = type;

codeOnly = false;

disabled = false;

}

/**

* If the Icon uses a pre-existing icon from file and you wish for it to be

* alpha blended with a color, this constructor should be used.

*

* @param i

*An image used in this tree icon. Such a folder icon.

* @param blendColor

*the color to blend the icon with

* @param alpha

*the amount of the color to blend 0.0f - 1.0f

*/

public CustomIcon16(Image i, Color blendColor, float alpha, int type) {

super(i);

this.type = type;

setAlphaBlending(blendColor, alpha);

}

/**

* A simple getter getting the width of the icon in pixels.

*

* @return the width of the icon in pixels.

*/

public int getWidth() {

return width;

}

/**

* A simple getter getting the height of the icon in pixels.

*

* @return the height of the icon in pixels.

*/

public int getHeight() {

return height;

}

/**

* Called by the parent component, this determines the height of the icon

* when displayed.

*

* @return the height of the icon when displayed.

*/

public int getIconHeight() {

return getHeight();

}

/**

* Called by the parent component, this determines the width of the icon

* when displayed.

*

* @return the width of the icon when displayed.

*/

public int getIconWidth() {

return getWidth();

}

/**

* Is this icon alpha blended with a color?

*

* @return true if this icon is alpha blended

*/

public boolean isAlphaBlended() {

return alphaBlending;

}

/**

* Turn on alpha blending with a color.

*

* @param blendColor

*the color to blend the icon with

* @param alpha

*the amount of the color to blend 0.0f - 1.0f

*/

public void setAlphaBlending(Color blendColor, float alpha) {

if (alpha < 0 || alpha > 1.0f) {

throw new IllegalArgumentException("Alpha required to be between"

+ " 0 and 1");

}

alphaBlending = true;

this.blendColor = blendColor;

this.alpha = alpha;

}

/**

* Getter method returns the color used in AlphaBlending

* @return the color used in AlphaBlending

*/

public Color getBlendingColor(){

return blendColor;

}

/**

* Turn alpha blending off.

*/

public void unsetAlphaBlending() {

alphaBlending = false;

}

/**

* Added to this object to handle disabling icons for objects that extend this

* class. The problem was that without some trickery, <tt>Icons</tt> that had no

* true image loaded from file behind them would have problems displaying. This

* technique solves that problem.

* @return true if this <tt>Icon</tt> is code only.

*/

public boolean isCodeOnly(){return codeOnly;}

/**

* Needed for icons that are only code. This lets the icon know during repaint

* that it has been disabled and should be drawn differently.

* @param b true = this icon has been disabled.

*/

public void setDisabled(boolean b){disabled = b;}

/**

* Needed for icons that are only code. This lets the icon know during repaint

* that it has been disabled and should be drawn differently.

* @return true = this icon has been disabled.

*/

public boolean isDisabled(){return disabled;}

/**

* Overrides <tt>JLabel</tt> <code>paintIcon</code>, allowing for the custom

* alpha blending and image control necessary in MDTs custom icons.

*

* Paints the icon. The top-left corner of the icon is drawn at the point

* (<CODE>x</CODE>, <CODE>y</CODE>) in the coordinate space of the graphics context

* <CODE>g</CODE>. If this icon has no image observer, this method uses the

* <CODE>c</CODE> component as the observer.

* @param c The component to be used as the observer if this image has no observer.

* @param g the graphics context

* @param x the X coordinate of the icons top-left corner.

* @param y the Y coordinate of the icons top-left corner.

*/

@Override

public void paintIcon(Component c, Graphics g, int x, int y) {

super.paintIcon(c, g, x, y);

Shape oldClip = g.getClip();

g.setClip(new Rectangle2D.Double(x,y,getWidth()+1,getHeight()+1));

if (alphaBlending) {

ImageIcon icon = new ImageIcon(super.getImage());

Graphics2D g2 = (Graphics2D) g;

BufferedImage bufImg = new BufferedImage(icon.getIconWidth(), icon

.getIconHeight(), BufferedImage.TYPE_INT_ARGB);

Graphics2D srcG2 = bufImg.createGraphics();

icon.paintIcon(c, srcG2, x, y); // paint the original icon

srcG2.setXORMode(blendColor); // highlight color

icon.paintIcon(c, srcG2, x, y); // paint the icon on the incoming graphics

srcG2.dispose(); // clean up on aisle g2

icon.paintIcon(c, g2, x, y); // paint original icon in our main graphics

ImageIcon highlight = new ImageIcon(bufImg); // create the highlighting image

Composite originalComposite = g2.getComposite();

g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,

alpha));

highlight.paintIcon(c, g2, x, y); // overlay the highlight

g2.setComposite(originalComposite); // restore the original composite.

}

g.setClip(oldClip);

}

/**

* @return the backgroundColor

*/

public Color getBackgroundColor() {

return backgroundColor;

}

/**

* @param backgroundColor the backgroundColor to set

*/

public void setBackgroundColor(Color backgroundColor) {

this.backgroundColor = backgroundColor;

}

/**

* @return the symbolColor

*/

public Color getSymbolColor() {

return symbolColor;

}

/**

* @param symbolColor the symbolColor to set

*/

public void setSymbolColor(Color symbolColor) {

this.symbolColor = symbolColor;

}

private int height = 16;

private int width = 16;

private boolean alphaBlending;

private float alpha;

private Color blendColor;

private boolean codeOnly;

private boolean disabled;//used for code-only icons

private Color backgroundColor;

private Color symbolColor;

}

package tree.renderers;

import icons.CustomColor16;

import javax.swing.Icon;

import javax.swing.JLabel;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeCellRenderer;

public class MDBTreeCellRenderer extends DefaultTreeCellRenderer {

@Override

public java.awt.Component getTreeCellRendererComponent(javax.swing.JTree tree,

Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {

java.awt.Component retValue = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

try{

JLabel nodeLabel = (JLabel) ((DefaultMutableTreeNode) value).getUserObject();

Icon icon = nodeLabel.getIcon();

if (icon instanceof CustomColor16) {

CustomColor16 cc16 = (CustomColor16) icon;

cc16.setBorderColor(sel ? cc16.getSelectionColor() : cc16.getBackgroundColor());

}

this.setIcon(icon);

this.setText(nodeLabel.getText());

return this;

} catch (ClassCastException cce2){

cce2.printStackTrace();

} catch (NullPointerException npe){

npe.printStackTrace();

}

return retValue;

}

}

package view;

import icons.Symbol16;

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTree;

import javax.swing.SwingConstants;

import javax.swing.SwingUtilities;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeModel;

import tree.renderers.MDBTreeCellRenderer;

public class View {

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

startUI();

}

});

}

private static void startUI() {

mainFrame = new JFrame("Bad Icon");

mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

mainFrame.setContentPane(initUI());

mainFrame.pack();

mainFrame.setVisible(true);

}

private static JPanel initUI() {

JTree jt = new JTree();

addTreeNodes(jt);

jt.setRootVisible(true);

jt.setShowsRootHandles(true);

jt.setCellRenderer(new MDBTreeCellRenderer());

jt.setRowHeight(18);

JScrollPane jsp = new JScrollPane();

jsp.setViewportView(jt);

JPanel jp = new JPanel(new BorderLayout());

jp.add(jsp, BorderLayout.CENTER);

jp.setOpaque(true);

return jp;

}

private static void addTreeNodes(JTree jt) {

DefaultMutableTreeNode node = new DefaultMutableTreeNode();

node.setUserObject(initTreeLabel(-1));

DefaultTreeModel model = new DefaultTreeModel(generateNode(10, node));

jt.setModel(model);

}

private static DefaultMutableTreeNode generateNode(int quantity, final DefaultMutableTreeNode node) {

if (quantity-- == 0) {

return node;

} else {

DefaultMutableTreeNode n = new DefaultMutableTreeNode();

n.setUserObject(initTreeLabel(quantity));

node.add(n);

return generateNode(quantity, node);

}

}

private static JLabel initTreeLabel(int quantity) {

Symbol16 s = new Symbol16();

s.setBackgroundColor(Color.BLACK);

s.setSelectionColor(Color.RED);

s.setSymbolColor(Color.RED);

return new JLabel("Sample " + quantity, s, SwingConstants.LEADING);

}

private static JFrame mainFrame;

}

bensteina at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...
# 3

Your code doesn't compile, you are missing a class.

Anyway we want a SSCCE, not your entire application.

Your question is about a custom icon. So create a simple example that uses a custom icon. Read the Swing tutorial on "How to Use Trees". It shows how to change icons. Once your icon works with the default renderer, then you can move on to a custom renderer. If it stops working, then you know what you have changed.

Don't expect us to read through hundreds of lines of code. Isoloate the problem first. Is it your icon, the color, the renderer.

camickra at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...
# 4

My bad for not keeping it simple enough before. This single class encapsulates the issue.

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.Shape;

import java.awt.geom.GeneralPath;

import java.awt.geom.Rectangle2D;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTree;

import javax.swing.SwingConstants;

import javax.swing.SwingUtilities;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeCellRenderer;

import javax.swing.tree.DefaultTreeModel;

public class View {

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

startUI();

}

});

}

private static void startUI() {

mainFrame = new JFrame("Bad Icon");

mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

mainFrame.setContentPane(initUI());

mainFrame.pack();

mainFrame.setVisible(true);

}

private static JPanel initUI() {

JTree jt = new JTree();

addTreeNodes(jt);

jt.setRootVisible(true);

jt.setShowsRootHandles(true);

jt.setCellRenderer(new MDBTreeCellRenderer());

jt.setRowHeight(18);

JScrollPane jsp = new JScrollPane();

jsp.setViewportView(jt);

JPanel jp = new JPanel(new BorderLayout());

jp.add(jsp, BorderLayout.CENTER);

jp.setOpaque(true);

return jp;

}

private static void addTreeNodes(JTree jt) {

DefaultMutableTreeNode node = new DefaultMutableTreeNode();

node.setUserObject(initTreeLabel(-1));

DefaultTreeModel model = new DefaultTreeModel(generateNode(10, node));

jt.setModel(model);

}

private static DefaultMutableTreeNode generateNode(int quantity, final DefaultMutableTreeNode node) {

if (quantity-- == 0) {

return node;

} else {

DefaultMutableTreeNode n = new DefaultMutableTreeNode();

n.setUserObject(initTreeLabel(quantity));

node.add(n);

return generateNode(quantity, node);

}

}

private static JLabel initTreeLabel(int quantity) {

Symbol16 s = new Symbol16();

return new JLabel("Sample " + quantity, s, SwingConstants.TRAILING);

}

private static JFrame mainFrame;

static class Symbol16 extends ImageIcon {

/**

* {@inheritDoc}

*/

public void paintIcon(Component c, Graphics g, int x, int y) {

super.paintIcon(c, g, x, y);

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(Color.RED);

Shape oldClip = g2d.getClip();

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Rectangle2D.Double background = new Rectangle2D.Double(x, y, getWidth(), getHeight());

g2d.setClip(background);

g2d.setColor(Color.BLACK);

g2d.fill(background);

g2d.setColor(Color.RED);

GeneralPath choper = new GeneralPath();

choper.moveTo(1f, 5f);

choper.lineTo(1f, 11f);

choper.lineTo(3f, 8f);

choper.lineTo(1f, 5f);

choper.moveTo(3f, 8f);

choper.lineTo(6f, 8f);

choper.lineTo(7f, 6f);

choper.lineTo(13f, 6f);

choper.lineTo(15f, 8f);

choper.lineTo(13f, 10f);

choper.lineTo(7f, 10f);

choper.lineTo(6f, 8f);

choper.moveTo(3f, 2f);

choper.lineTo(15f, 15f);

choper.moveTo(15f, 2f);

choper.lineTo(3f, 15f);

g2d.draw(choper);

g2d.setClip(oldClip);

}

public int getIconWidth() {

return getWidth();

}

public int getIconHeight() {

return getHeight();

}

public int getWidth() {

return 16;

}

public int getHeight() {

return 16;

}

}

static class MDBTreeCellRenderer extends DefaultTreeCellRenderer {

public java.awt.Component getTreeCellRendererComponent(javax.swing.JTree tree,

Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {

java.awt.Component retValue = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

try{

JLabel nodeLabel = (JLabel) ((DefaultMutableTreeNode) value).getUserObject();

this.setIcon(nodeLabel.getIcon());

this.setText(nodeLabel.getText());

return this;

} catch (ClassCastException cce2){

cce2.printStackTrace();

} catch (NullPointerException npe){

npe.printStackTrace();

}

return retValue;

}

}

}

bensteina at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...
# 5
Please ignore post 3, since post 4 is much more SSCCE. The behavior is the same when Symbol16 implements Icon and there is no call to super.paintIcon(Component, Graphics, int, int). I'm going to assume this is a bug and report it. Although, for now I am going to bump up the duke count.
bensteina at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...
# 6

> Please ignore post 3, since post 4 is much more SSCCE

But it is still not a SSCCE. I asked you to read the tutorial on "how to use trees" and to change the default renderer to use your custom icon. There was no need to post a custom renderer and all the code associated with it.

Your code as posted gets runtime exeptions from your paintIcon(...) method on JDK1.4.2.

Here is a SSCCE that works on my machine. Note how much simpler the code is when you only include the code for the custom icon

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.Shape;

import java.awt.geom.GeneralPath;

import java.awt.geom.Rectangle2D;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTree;

import javax.swing.SwingConstants;

import javax.swing.SwingUtilities;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeCellRenderer;

import javax.swing.tree.DefaultTreeModel;

public class View {

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

startUI();

}

});

}

private static void startUI() {

mainFrame = new JFrame("Bad Icon");

mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

mainFrame.setContentPane(initUI());

mainFrame.pack();

mainFrame.setVisible(true);

}

private static JPanel initUI() {

JTree jt = new JTree();

//addTreeNodes(jt);

jt.setRootVisible(true);

jt.setShowsRootHandles(true);

// These are the lines taken from the tutorial

DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();

renderer.setLeafIcon(new Symbol16());

jt.setCellRenderer(renderer);

//jt.setCellRenderer(new MDBTreeCellRenderer());

jt.setRowHeight(18);

JScrollPane jsp = new JScrollPane();

jsp.setViewportView(jt);

JPanel jp = new JPanel(new BorderLayout());

jp.add(jsp, BorderLayout.CENTER);

jp.setOpaque(true);

return jp;

}

private static JFrame mainFrame;

static class Symbol16 extends ImageIcon {

/**

* {@inheritDoc}

*/

public void paintIcon(Component c, Graphics g, int x, int y) {

// For some reason this causes a NPE.

//super.paintIcon(c, g, x, y);

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(Color.RED);

Shape oldClip = g2d.getClip();

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Rectangle2D.Double background = new Rectangle2D.Double(x, y, getWidth(), getHeight());

// this fixed your overlapping problem

//g2d.setClip(background);

g2d.setColor(Color.BLACK);

g2d.fill(background);

g2d.setColor(Color.RED);

GeneralPath choper = new GeneralPath();

choper.moveTo(1f, 5f);

choper.lineTo(1f, 11f);

choper.lineTo(3f, 8f);

choper.lineTo(1f, 5f);

choper.moveTo(3f, 8f);

choper.lineTo(6f, 8f);

choper.lineTo(7f, 6f);

choper.lineTo(13f, 6f);

choper.lineTo(15f, 8f);

choper.lineTo(13f, 10f);

choper.lineTo(7f, 10f);

choper.lineTo(6f, 8f);

choper.moveTo(3f, 2f);

choper.lineTo(15f, 15f);

choper.moveTo(15f, 2f);

choper.lineTo(3f, 15f);

g2d.draw(choper);

g2d.setClip(oldClip);

}

public int getIconWidth() {

return getWidth();

}

public int getIconHeight() {

return getHeight();

}

public int getWidth() {

return 16;

}

public int getHeight() {

return 16;

}

}

}

P.S. I would still rather win your money then receive your dukes :)

camickra at 2007-7-12 18:07:57 > top of Java-index,Desktop,Core GUI APIs...