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