001: /*
002: * Copyright 2005 Patrick Gotthardt
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.pagosoft.plaf;
017:
018: import javax.swing.*;
019: import javax.swing.event.*;
020: import javax.swing.plaf.*;
021: import javax.swing.plaf.basic.*;
022: import javax.swing.plaf.metal.*;
023: import java.awt.*;
024: import java.beans.PropertyChangeEvent;
025: import java.beans.PropertyChangeListener;
026:
027: /**
028: * It tasts bad, that I had to copy most of MetalComboBoxUIs Code
029: * just to change a little things of it's behaviour...
030: */
031: public class PgsComboBoxUI extends MetalComboBoxUI {
032: private boolean iconPaintPressed = false;
033: private PopupHandler popupHandler;
034:
035: public static ComponentUI createUI(JComponent c) {
036: return new PgsComboBoxUI();
037: }
038:
039: public void paintCurrentValue(Graphics g, Rectangle bounds,
040: boolean hasFocus) {
041: ListCellRenderer renderer = comboBox.getRenderer();
042: Component c;
043:
044: if (hasFocus && !isPopupVisible(comboBox)) {
045: c = renderer.getListCellRendererComponent(listBox, comboBox
046: .getSelectedItem(), -1, true, false);
047: } else {
048: c = renderer.getListCellRendererComponent(listBox, comboBox
049: .getSelectedItem(), -1, false, false);
050: c.setBackground(UIManager.getColor("ComboBox.background"));
051: }
052: c.setFont(comboBox.getFont());
053: if (comboBox.isEnabled()) {
054: c.setForeground(comboBox.getForeground());
055: c.setBackground(comboBox.getBackground());
056: } else {
057: c.setForeground(UIManager
058: .getColor("ComboBox.disabledForeground"));
059: c.setBackground(UIManager
060: .getColor("ComboBox.disabledBackground"));
061: }
062:
063: // Fix for 4238829: should lay out the JPanel.
064: boolean shouldValidate = false;
065: if (c instanceof JPanel) {
066: shouldValidate = true;
067: }
068:
069: currentValuePane.paintComponent(g, c, comboBox, bounds.x,
070: bounds.y, bounds.width, bounds.height, shouldValidate);
071:
072: /*if(hasFocus && !isPopupVisible(comboBox)) {
073: g.setColor(listBox.getSelectionBackground());
074: PgsUtils.drawRoundRect(g, bounds.x + 2, bounds.y + 2, bounds.width-4, bounds.height-4);
075: }*/
076: }
077:
078: public void paintCurrentValueBackground(Graphics g,
079: Rectangle bounds, boolean hasFocus) {
080: /*g.setColor(MetalLookAndFeel.getControlDarkShadow());
081: g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
082: g.setColor(MetalLookAndFeel.getControlShadow());
083: g.drawRect(bounds.x + 1, bounds.y + 1, bounds.width - 2,
084: bounds.height - 3);*/
085: }
086:
087: protected void installListeners() {
088: super .installListeners();
089: if (popup instanceof BasicComboPopup) {
090: popupHandler = new PopupHandler();
091: ((BasicComboPopup) popup)
092: .addPopupMenuListener(popupHandler);
093: }
094: }
095:
096: protected void uninstallListeners() {
097: super .uninstallListeners();
098: if (popup instanceof BasicComboPopup) {
099: ((BasicComboPopup) popup)
100: .removePopupMenuListener(popupHandler);
101: }
102: }
103:
104: public void paint(Graphics g, JComponent c) {
105: hasFocus = comboBox.hasFocus();
106: if (!comboBox.isEditable()) {
107: Rectangle r = rectangleForCurrentValue();
108: paintCurrentValueBackground(g, r, hasFocus);
109: paintCurrentValue(g, r, hasFocus);
110: }
111: }
112:
113: protected ComboBoxEditor createEditor() {
114: ComboBoxEditor editor = super .createEditor();
115: ((JComponent) editor.getEditorComponent()).setBorder(UIManager
116: .getBorder("ComboBox.editorBorder"));
117: return editor;
118: }
119:
120: protected JButton createArrowButton() {
121: JButton button = new PgsComboBoxButtonUI(comboBox,
122: new PgsComboBoxIcon(), comboBox.isEditable(),
123: currentValuePane, listBox);
124: button.setMargin(new Insets(2, 2, 2, 2));
125: button.setFocusPainted(comboBox.isEditable());
126: return button;
127: }
128:
129: protected ComboPopup createPopup() {
130: BasicComboPopup basiccombopopup = (BasicComboPopup) super
131: .createPopup();
132: basiccombopopup.setBorder(UIManager
133: .getBorder("ComboBox.popup.border"));
134: return basiccombopopup;
135: }
136:
137: public void layoutComboBox(Container parent,
138: MetalComboBoxLayoutManager manager) {
139: if (arrowButton != null) {
140: if (arrowButton instanceof PgsComboBoxButtonUI) {
141: Icon icon = ((PgsComboBoxButtonUI) arrowButton)
142: .getComboIcon();
143: Insets buttonInsets = arrowButton.getInsets();
144: Insets insets = comboBox.getInsets();
145: int buttonWidth = icon.getIconWidth()
146: + buttonInsets.left + buttonInsets.right;
147: arrowButton.setBounds(
148: PgsUtils.isLeftToRight(comboBox) ? (comboBox
149: .getWidth()
150: - insets.right - buttonWidth - 1)
151: : insets.left, insets.top + 2,
152: buttonWidth - 1, comboBox.getHeight()
153: - insets.top - insets.bottom - 4);
154: } else {
155: Insets insets = comboBox.getInsets();
156: int width = comboBox.getWidth();
157: int height = comboBox.getHeight();
158: arrowButton.setBounds(insets.left, insets.top, width
159: - (insets.left + insets.right), height
160: - (insets.top + insets.bottom));
161: }
162: }
163:
164: if (editor != null) {
165: Rectangle cvb = rectangleForCurrentValue();
166: editor.setBounds(cvb);
167: }
168: }
169:
170: public Dimension getMinimumSize(JComponent c) {
171: if (!isMinimumSizeDirty) {
172: return new Dimension(cachedMinimumSize);
173: }
174:
175: Dimension size = null;
176:
177: if (!comboBox.isEditable() && arrowButton != null
178: && arrowButton instanceof PgsComboBoxButtonUI) {
179:
180: PgsComboBoxButtonUI button = (PgsComboBoxButtonUI) arrowButton;
181: Insets buttonInsets = button.getInsets();
182: Insets insets = comboBox.getInsets();
183:
184: size = getDisplaySize();
185: size.width += insets.left + insets.right;
186: size.width += buttonInsets.left + buttonInsets.right;
187: size.width += buttonInsets.right
188: + button.getComboIcon().getIconWidth();
189: size.height += insets.top + insets.bottom;
190: //size.height += buttonInsets.top + buttonInsets.bottom;
191: } else if (comboBox.isEditable() && arrowButton != null
192: && editor != null) {
193: size = super .getMinimumSize(c);
194: Insets margin = arrowButton.getMargin();
195: size.height += margin.top + margin.bottom;
196: size.width += margin.left + margin.right;
197: } else {
198: size = super .getMinimumSize(c);
199: }
200:
201: cachedMinimumSize.setSize(size.width, size.height);
202: isMinimumSizeDirty = false;
203:
204: return new Dimension(cachedMinimumSize);
205: }
206:
207: public PropertyChangeListener createPropertyChangeListener() {
208: return new PgsPropertyChangeListener();
209: }
210:
211: public class PgsPropertyChangeListener extends
212: BasicComboBoxUI.PropertyChangeHandler {
213: public void propertyChange(PropertyChangeEvent e) {
214: super .propertyChange(e);
215: String propertyName = e.getPropertyName();
216:
217: if (propertyName == "editable") {
218: PgsComboBoxButtonUI button = (PgsComboBoxButtonUI) arrowButton;
219: button.setIconOnly(comboBox.isEditable());
220: comboBox.repaint();
221: button.setFocusPainted(comboBox.isEditable());
222: } else if (propertyName == "background") {
223: Color color = (Color) e.getNewValue();
224: arrowButton.setBackground(color);
225: listBox.setBackground(color);
226:
227: } else if (propertyName == "foreground") {
228: Color color = (Color) e.getNewValue();
229: arrowButton.setForeground(color);
230: listBox.setForeground(color);
231: }
232: }
233: }
234:
235: private class PgsComboBoxIcon implements Icon {
236: public void paintIcon(Component component, Graphics g, int x,
237: int y) {
238: JButton c = (JButton) component;
239: int iconWidth = getIconWidth();
240:
241: g.translate(x, y);
242:
243: g.setColor(c.isEnabled() ? PgsLookAndFeel.getControlInfo()
244: : PgsLookAndFeel.getControlShadow());
245: if (iconPaintPressed) {
246: g.drawLine(1, 3, 1 + iconWidth - 3, 3);
247: g.drawLine(2, 2, 2 + iconWidth - 5, 2);
248: g.drawLine(3, 1, 3 + iconWidth - 7, 1);
249: g.drawLine(4, 0, 4 + iconWidth - 9, 0);
250: } else {
251: g.drawLine(1, 1, 1 + (iconWidth - 3), 1);
252: g.drawLine(2, 2, 2 + (iconWidth - 5), 2);
253: g.drawLine(3, 3, 3 + (iconWidth - 7), 3);
254: g.drawLine(4, 4, 4 + (iconWidth - 9), 4);
255: }
256:
257: g.translate(-x, -y);
258: }
259:
260: /**
261: * Created a stub to satisfy the interface.
262: */
263: public int getIconWidth() {
264: return 10;
265: }
266:
267: /**
268: * Created a stub to satisfy the interface.
269: */
270: public int getIconHeight() {
271: return 4;
272: }
273: }
274:
275: private class PopupHandler implements PopupMenuListener {
276: public void popupMenuCanceled(PopupMenuEvent e) {
277: }
278:
279: public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
280: iconPaintPressed = false;
281: }
282:
283: public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
284: iconPaintPressed = true;
285: }
286: }
287: }
|