001: package org.columba.core.gui.base;
002:
003: import java.awt.Component;
004: import java.awt.Cursor;
005: import java.awt.Dimension;
006: import java.awt.FontMetrics;
007: import java.awt.Graphics;
008: import java.awt.Insets;
009: import java.awt.Rectangle;
010: import java.awt.event.MouseEvent;
011:
012: import javax.swing.Icon;
013: import javax.swing.JPopupMenu;
014: import javax.swing.JTextField;
015: import javax.swing.border.AbstractBorder;
016: import javax.swing.border.Border;
017: import javax.swing.event.MouseInputAdapter;
018:
019: public class IconTextField extends JTextField {
020: private Icon icon;
021: private Rectangle iconBounds;
022: private JPopupMenu popupMenu;
023: private IconifiedBorder border;
024:
025: public IconTextField(Icon icon, int columns) {
026: // initialization
027: super (columns);
028:
029: popupMenu = new JPopupMenu();
030:
031: // icon (we can't use the setIcon-method this time, as it relies on the border being set)
032: this .icon = icon;
033: iconBounds = new Rectangle(0, 0, icon.getIconWidth(), icon
034: .getIconHeight());
035:
036: // border
037: border = new IconifiedBorder(getBorder(), icon, 1);
038: setBorder(border);
039:
040: // controller
041: MouseHandler handler = new MouseHandler();
042: addMouseListener(handler);
043: addMouseMotionListener(handler);
044: }
045:
046: public void setPopupMenu(JPopupMenu menu) {
047: JPopupMenu oldMenu = popupMenu;
048: popupMenu = menu;
049: firePropertyChange("popup", oldMenu, popupMenu);
050: }
051:
052: public void setIcon(Icon ico) {
053: Icon oldIcon = this .icon;
054: this .icon = ico;
055: iconBounds = new Rectangle(0, 0, ico.getIconWidth(), ico
056: .getIconHeight());
057: border.setIcon(icon);
058: firePropertyChange("icon", oldIcon, icon);
059: }
060:
061: public Icon getIcon() {
062: return icon;
063: }
064:
065: public JPopupMenu getPopupMenu() {
066: return popupMenu;
067: }
068:
069: public Dimension getPreferredSize() {
070: Dimension size = super .getPreferredSize();
071: Insets insets = getInsets();
072: Insets margin = getMargin();
073: FontMetrics fm = getFontMetrics(getFont());
074: size.height = Math.max(fm.getHeight(), icon.getIconHeight())
075: + insets.top + insets.bottom;
076: return size;
077: }
078:
079: private class MouseHandler extends MouseInputAdapter {
080: public void mouseMoved(MouseEvent e) {
081: if (iconBounds.contains(e.getPoint())) {
082: setCursor(Cursor.getDefaultCursor());
083: } else {
084: setCursor(Cursor
085: .getPredefinedCursor(Cursor.TEXT_CURSOR));
086: }
087: }
088:
089: public void mouseClicked(MouseEvent e) {
090: if (iconBounds.contains(e.getPoint())) {
091: if (popupMenu.isVisible()) {
092: popupMenu.setVisible(false);
093: } else {
094: popupMenu.show(IconTextField.this , 0, getHeight());
095: }
096: }
097: }
098: }
099:
100: private class IconifiedBorder extends AbstractBorder {
101: private Border innerBorder;
102: private Icon icon;
103: private Insets insets;
104: private int spacing;
105:
106: public IconifiedBorder(Border innerBorder, Icon icon,
107: int spacing) {
108: this .innerBorder = innerBorder;
109: this .icon = icon;
110: this .spacing = spacing;
111: }
112:
113: public void setIcon(Icon ico) {
114: this .icon = ico;
115: insets = null;
116: }
117:
118: public Border getInnerBorder() {
119: return innerBorder;
120: }
121:
122: public void paintBorder(Component c, Graphics g, int x, int y,
123: int width, int height) {
124: innerBorder.paintBorder(c, g, x, y, width, height);
125: Insets innerInsets = innerBorder.getBorderInsets(c);
126: iconBounds.x = x + innerInsets.left + spacing;
127: iconBounds.y = y + innerInsets.top + spacing;
128: icon.paintIcon(c, g, iconBounds.x, iconBounds.y);
129: }
130:
131: public Insets getBorderInsets(Component c) {
132: if (insets == null) {
133: insets = (Insets) innerBorder.getBorderInsets(c)
134: .clone();
135: insets.left += icon.getIconWidth() + spacing * 4;
136: //insets.top += spacing;
137: //insets.bottom += spacing;
138: }
139: return insets;
140: }
141: }
142: }
|