001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Alexander T. Simbirtsev
019: * @version $Revision$
020: * Created on 01.05.2005
021:
022: */package org.apache.harmony.x.swing;
023:
024: import java.awt.Color;
025: import java.awt.Dimension;
026: import java.awt.FontMetrics;
027: import java.awt.Graphics;
028: import java.awt.Insets;
029: import java.awt.Rectangle;
030:
031: import javax.swing.AbstractButton;
032: import javax.swing.ButtonModel;
033: import javax.swing.Icon;
034: import javax.swing.SwingUtilities;
035:
036: /**
037: * The storage of different utility methods used for buttons drawing.
038: */
039: public class ButtonCommons {
040: private static final int[][] CHECK_COORDINATES = {
041: { 1, 3, 8, 8, 3, 1 }, { 4, 6, 1, 3, 8, 6 } };
042:
043: private static final Insets INSETS = new Insets(0, 0, 0, 0);
044:
045: /**
046: * Paints focus border at the specified bounds.
047: *
048: * @param g Graphics to paint on
049: * @param focusRect Rectangle which specifies the focus border location
050: * @param color Color to paint focus
051: */
052: public static void paintFocus(final Graphics g,
053: final Rectangle focusRect, final Color color) {
054: Color oldColor = g.getColor();
055: g.setColor(color);
056: g.drawRect(focusRect.x - 1, focusRect.y - 1, focusRect.width,
057: focusRect.height);
058: g.setColor(oldColor);
059: }
060:
061: /**
062: * Paints button in the pressed state (push buttons and toggle-buttons).
063: *
064: * @param g Graphics to paint on
065: * @param button AbstractButton to be painted as pressed
066: * @param color Color of the button in the pressed state
067: */
068: public static void paintPressed(final Graphics g,
069: final AbstractButton button, final Color color) {
070: Color oldColor = g.getColor();
071: Dimension buttonSize = button.getSize();
072: g.setColor(color);
073: g.fillRect(0, 0, buttonSize.width, buttonSize.height);
074: g.setColor(oldColor);
075: }
076:
077: /**
078: * Paints text on a button.
079: *
080: * @param g Graphics to paint on
081: * @param b AbstractButton to be painted
082: * @param textRect Rectangle bounding the text location
083: * @param clippedText String to be displayed on the button surface (should be trimmed by the bouding rectangle)
084: * @param color Color of the text
085: */
086: public static void paintText(final Graphics g,
087: final AbstractButton b, final Rectangle textRect,
088: final String clippedText, final Color color) {
089: paintText(g, b.getFontMetrics(b.getFont()), b.getText(), b
090: .getDisplayedMnemonicIndex(), textRect, clippedText,
091: color);
092: }
093:
094: /**
095: * Paints text on the specified Graphics in the specified location.
096: *
097: * @param g Graphics to paint on
098: * @param fm FontMetrics set for the button
099: * @param text String representing the original (not-trimmed) button text (AbstractButton.getText())
100: * @param displayedMnemonicIndex int value specifing an index of a 'mnemonical char', i.e. index in the text to be underscored.
101: * -1 if no mnemonic is set
102: * @param textRect Rectangle bounding the text location
103: * @param clippedText String to be displayed on the button surface (should be trimmed by the bouding rectangle)
104: * @param color Color of the text
105: */
106: public static void paintText(final Graphics g,
107: final FontMetrics fm, final String text,
108: final int displayedMnemonicIndex, final Rectangle textRect,
109: final String clippedText, final Color color) {
110: int underscore = Utilities.getClippedUnderscoreIndex(text,
111: clippedText, displayedMnemonicIndex);
112: Utilities.drawString(g, clippedText, textRect.x, Utilities
113: .getTextY(fm, textRect), fm, color, underscore);
114: }
115:
116: /**
117: * Calculates the preferred button size.
118: *
119: * @param button AbstractButton for which the preferred size to be calculated
120: * @param defaultIcon Icon which is set for the button when calculating its preferred size.
121: * Null if no icon is set. Usually that is AbstractButton.getIcon()
122: * @param textIconGap int value representing the gap between text and icon (ususally AbstractButton.getIconTextGap())
123: * @return Dimension of the button preferred size
124: */
125: public static Dimension getPreferredSize(
126: final AbstractButton button, final Icon defaultIcon,
127: final int textIconGap) {
128: Icon icon = (button.getIcon() != null) ? button.getIcon()
129: : defaultIcon;
130:
131: Dimension size = Utilities.getCompoundLabelSize(button, button
132: .getText(), icon, button.getVerticalTextPosition(),
133: button.getHorizontalTextPosition(), textIconGap);
134:
135: return Utilities.addInsets(size, button.getInsets(INSETS));
136: }
137:
138: /**
139: * Calculates the preferred button size.
140: *
141: * @param button AbstractButton for which the preferred size to be calculated
142: * @param defaultIcon Icon which is set for the button when calculating its preferred size.
143: * Null if no icon is set. Usually that is AbstractButton.getIcon()
144: * @return Dimension of the button preferred size
145: */
146: public static Dimension getPreferredSize(
147: final AbstractButton button, final Icon defaultIcon) {
148: return getPreferredSize(button, defaultIcon, button
149: .getIconTextGap());
150: }
151:
152: /**
153: * Calculate button layout and clipping text.
154: *
155: * @param button AbstractButton for which parameters to be calculated
156: * @param viewR Rectangle which will be initialized as button local bounds
157: * @param iconR Rectangle which will be initialized as icon bounds
158: * @param textR Rectangle which will be initialized as text bounds
159: * @param icon Icon which is set to button (ususally that is AbstractButton.getIcon()) or null
160: * @param leftInset int value representing button left inset (border) if any
161: * @param rightInset int value representing button right inset (border) if any
162: * @return String which represent the text to be displayed in the button (button label
163: * clipped and complemented with "..." if required)
164: */
165: public static String getPaintingParameters(
166: final AbstractButton button, final Rectangle viewR,
167: final Rectangle iconR, final Rectangle textR,
168: final Icon icon, final int leftInset, final int rightInset) {
169: Insets borderInsets = button.getInsets(INSETS);
170: borderInsets.left += leftInset;
171: borderInsets.right += rightInset;
172:
173: viewR.setBounds(0, 0, button.getWidth(), button.getHeight());
174: Utilities.subtractInsets(viewR, borderInsets);
175: FontMetrics fm = button.getFontMetrics(button.getFont());
176: return SwingUtilities.layoutCompoundLabel(button, fm, button
177: .getText(), icon, button.getVerticalAlignment(), button
178: .getHorizontalAlignment(), button
179: .getVerticalTextPosition(), button
180: .getHorizontalTextPosition(), viewR, iconR, textR,
181: button.getIconTextGap());
182: }
183:
184: /**
185: * Calculate button layout and clipping text.
186: *
187: * @param button AbstractButton for which parameters to be calculated
188: * @param viewR Rectangle which will be initialized as button local bounds
189: * @param iconR Rectangle which will be initialized as icon bounds
190: * @param textR Rectangle which will be initialized as text bounds
191: * @param icon Icon which is set to button (ususally that is AbstractButton.getIcon()) or null
192: * @return String which represent the text to be displayed in the button (button label clipped and complemented with "..." if required)
193: */
194: public static String getPaintingParameters(
195: final AbstractButton button, final Rectangle viewR,
196: final Rectangle iconR, final Rectangle textR,
197: final Icon icon) {
198: return getPaintingParameters(button, viewR, iconR, textR, icon,
199: 0, 0);
200: }
201:
202: /**
203: * Retrieves 'current' button icon - icon which is set for the current button state (enabled/disabled/pressed).
204: *
205: * @param button AbstractButton for which icon should be calculated.
206: * @return Icon or null if there is no icon for the button.
207: */
208: public static Icon getCurrentIcon(final AbstractButton button) {
209: Icon icon = null;
210:
211: final ButtonModel model = button.getModel();
212: if (model.isEnabled()) {
213: if (model.isArmed()) {
214: icon = button.getPressedIcon();
215: } else if (model.isRollover()) {
216: icon = model.isSelected() ? button
217: .getRolloverSelectedIcon() : button
218: .getRolloverIcon();
219: } else if (model.isSelected()) {
220: icon = button.getSelectedIcon();
221: }
222: } else {
223: icon = model.isSelected() ? button
224: .getDisabledSelectedIcon() : button
225: .getDisabledIcon();
226: }
227: if (icon == null) {
228: icon = button.getIcon();
229: }
230:
231: return icon;
232: }
233:
234: /**
235: * Draws 'check' icon at the specified location. Used for check boxes.
236: *
237: * @param g Graphics to draw on
238: * @param color Color of the check
239: * @param x int value representing the icon's x-location
240: * @param y int value representing the icon's y-location
241: */
242: public static void drawCheck(final Graphics g, final Color color,
243: final int x, final int y) {
244: g.setColor(color);
245: g.translate(x, y);
246: g.fillPolygon(CHECK_COORDINATES[0], CHECK_COORDINATES[1],
247: CHECK_COORDINATES[0].length);
248: g.translate(-x, -y);
249: }
250:
251: /**
252: * Decides which bounds should be used for drawing focus.
253: * Usually the choice is done among button bounds (rect1), button text bounds (rect2) and button icon bounds (rect3).
254: * The order is the following: if rect1 is apecified (and not empty) rect1 is returned.
255: * Otherwise if rect2 is specified and not empty rect2 is returned.
256: * Otherwise rect3 is returned.
257: *
258: * @param rect1 Rectangle of the most preferrable focus bounds
259: * @param rect2 Rectangle of the next preferrable focus bounds
260: * @param rect3 Rectangle of the least preferrable focus bounds
261: * @return Rectangle of the focus bounds
262: */
263: public static Rectangle getFocusRect(final Rectangle rect1,
264: final Rectangle rect2, final Rectangle rect3) {
265: if (rect1 != null && !rect1.isEmpty()) {
266: return rect1;
267: }
268: if (rect2 != null && !rect2.isEmpty()) {
269: return rect2;
270: }
271:
272: return rect3;
273: }
274: }
|