History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/plaf/basic/BasicButtonUI.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/plaf/basic/BasicButtonUI.java+471−0
@@ -0,0 +1,471 @@
1+/*
2+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.swing.plaf.basic;
27+
28+import sun.swing.SwingUtilities2;
29+import sun.awt.AppContext;
30+
31+import java.awt.*;
32+import java.awt.event.*;
33+import java.io.Serializable;
34+import javax.swing.*;
35+import javax.swing.border.*;
36+import java.awt.*;
37+import java.awt.event.*;
38+import javax.swing.plaf.ButtonUI;
39+import javax.swing.plaf.UIResource;
40+import javax.swing.plaf.ComponentUI;
41+import javax.swing.text.View;
42+
43+/**
44+ * BasicButton implementation
45+ *
46+ * @author Jeff Dinkins
47+ */
48+public class BasicButtonUI extends ButtonUI{
49+ // Visual constants
50+ // NOTE: This is not used or set any where. Were we allowed to remove
51+ // fields, this would be removed.
52+ protected int defaultTextIconGap;
53+
54+ // Amount to offset text, the value of this comes from
55+ // defaultTextShiftOffset once setTextShiftOffset has been invoked.
56+ private int shiftOffset = 0;
57+ // Value that is set in shiftOffset once setTextShiftOffset has been
58+ // invoked. The value of this comes from the defaults table.
59+ protected int defaultTextShiftOffset;
60+
61+ private final static String propertyPrefix = "Button" + ".";
62+
63+ private static final Object BASIC_BUTTON_UI_KEY = new Object();
64+
65+ // ********************************
66+ // Create PLAF
67+ // ********************************
68+ public static ComponentUI createUI(JComponent c) {
69+ AppContext appContext = AppContext.getAppContext();
70+ BasicButtonUI buttonUI =
71+ (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);
72+ if (buttonUI == null) {
73+ buttonUI = new BasicButtonUI();
74+ appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);
75+ }
76+ return buttonUI;
77+ }
78+
79+ protected String getPropertyPrefix() {
80+ return propertyPrefix;
81+ }
82+
83+
84+ // ********************************
85+ // Install PLAF
86+ // ********************************
87+ public void installUI(JComponent c) {
88+ installDefaults((AbstractButton) c);
89+ installListeners((AbstractButton) c);
90+ installKeyboardActions((AbstractButton) c);
91+ BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());
92+ }
93+
94+ protected void installDefaults(AbstractButton b) {
95+ // load shared instance defaults
96+ String pp = getPropertyPrefix();
97+
98+ defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
99+
100+ // set the following defaults on the button
101+ if (b.isContentAreaFilled()) {
102+ LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
103+ } else {
104+ LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
105+ }
106+
107+ if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {
108+ b.setMargin(UIManager.getInsets(pp + "margin"));
109+ }
110+
111+ LookAndFeel.installColorsAndFont(b, pp + "background",
112+ pp + "foreground", pp + "font");
113+ LookAndFeel.installBorder(b, pp + "border");
114+
115+ Object rollover = UIManager.get(pp + "rollover");
116+ if (rollover != null) {
117+ LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
118+ }
119+
120+ LookAndFeel.installProperty(b, "iconTextGap", Integer.valueOf(4));
121+ }
122+
123+ protected void installListeners(AbstractButton b) {
124+ BasicButtonListener listener = createButtonListener(b);
125+ if(listener != null) {
126+ b.addMouseListener(listener);
127+ b.addMouseMotionListener(listener);
128+ b.addFocusListener(listener);
129+ b.addPropertyChangeListener(listener);
130+ b.addChangeListener(listener);
131+ }
132+ }
133+
134+ protected void installKeyboardActions(AbstractButton b){
135+ BasicButtonListener listener = getButtonListener(b);
136+
137+ if(listener != null) {
138+ listener.installKeyboardActions(b);
139+ }
140+ }
141+
142+
143+ // ********************************
144+ // Uninstall PLAF
145+ // ********************************
146+ public void uninstallUI(JComponent c) {
147+ uninstallKeyboardActions((AbstractButton) c);
148+ uninstallListeners((AbstractButton) c);
149+ uninstallDefaults((AbstractButton) c);
150+ BasicHTML.updateRenderer(c, "");
151+ }
152+
153+ protected void uninstallKeyboardActions(AbstractButton b) {
154+ BasicButtonListener listener = getButtonListener(b);
155+ if(listener != null) {
156+ listener.uninstallKeyboardActions(b);
157+ }
158+ }
159+
160+ protected void uninstallListeners(AbstractButton b) {
161+ BasicButtonListener listener = getButtonListener(b);
162+ if(listener != null) {
163+ b.removeMouseListener(listener);
164+ b.removeMouseMotionListener(listener);
165+ b.removeFocusListener(listener);
166+ b.removeChangeListener(listener);
167+ b.removePropertyChangeListener(listener);
168+ }
169+ }
170+
171+ protected void uninstallDefaults(AbstractButton b) {
172+ LookAndFeel.uninstallBorder(b);
173+ }
174+
175+ // ********************************
176+ // Create Listeners
177+ // ********************************
178+ protected BasicButtonListener createButtonListener(AbstractButton b) {
179+ return new BasicButtonListener(b);
180+ }
181+
182+ public int getDefaultTextIconGap(AbstractButton b) {
183+ return defaultTextIconGap;
184+ }
185+
186+ /* These rectangles/insets are allocated once for all
187+ * ButtonUI.paint() calls. Re-using rectangles rather than
188+ * allocating them in each paint call substantially reduced the time
189+ * it took paint to run. Obviously, this method can't be re-entered.
190+ */
191+ private static Rectangle viewRect = new Rectangle();
192+ private static Rectangle textRect = new Rectangle();
193+ private static Rectangle iconRect = new Rectangle();
194+
195+ // ********************************
196+ // Paint Methods
197+ // ********************************
198+
199+ public void paint(Graphics g, JComponent c)
200+ {
201+ AbstractButton b = (AbstractButton) c;
202+ ButtonModel model = b.getModel();
203+
204+ String text = layout(b, SwingUtilities2.getFontMetrics(b, g),
205+ b.getWidth(), b.getHeight());
206+
207+ clearTextShiftOffset();
208+
209+ // perform UI specific press action, e.g. Windows L&F shifts text
210+ if (model.isArmed() && model.isPressed()) {
211+ paintButtonPressed(g,b);
212+ }
213+
214+ // Paint the Icon
215+ if(b.getIcon() != null) {
216+ paintIcon(g,c,iconRect);
217+ }
218+
219+ if (text != null && !text.equals("")){
220+ View v = (View) c.getClientProperty(BasicHTML.propertyKey);
221+ if (v != null) {
222+ v.paint(g, textRect);
223+ } else {
224+ paintText(g, b, textRect, text);
225+ }
226+ }
227+
228+ if (b.isFocusPainted() && b.hasFocus()) {
229+ // paint UI specific focus
230+ paintFocus(g,b,viewRect,textRect,iconRect);
231+ }
232+ }
233+
234+ protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){
235+ AbstractButton b = (AbstractButton) c;
236+ ButtonModel model = b.getModel();
237+ Icon icon = b.getIcon();
238+ Icon tmpIcon = null;
239+
240+ if(icon == null) {
241+ return;
242+ }
243+
244+ Icon selectedIcon = null;
245+
246+ /* the fallback icon should be based on the selected state */
247+ if (model.isSelected()) {
248+ selectedIcon = b.getSelectedIcon();
249+ if (selectedIcon != null) {
250+ icon = selectedIcon;
251+ }
252+ }
253+
254+ if(!model.isEnabled()) {
255+ if(model.isSelected()) {
256+ tmpIcon = b.getDisabledSelectedIcon();
257+ if (tmpIcon == null) {
258+ tmpIcon = selectedIcon;
259+ }
260+ }
261+
262+ if (tmpIcon == null) {
263+ tmpIcon = b.getDisabledIcon();
264+ }
265+ } else if(model.isPressed() && model.isArmed()) {
266+ tmpIcon = b.getPressedIcon();
267+ if(tmpIcon != null) {
268+ // revert back to 0 offset
269+ clearTextShiftOffset();
270+ }
271+ } else if(b.isRolloverEnabled() && model.isRollover()) {
272+ if(model.isSelected()) {
273+ tmpIcon = b.getRolloverSelectedIcon();
274+ if (tmpIcon == null) {
275+ tmpIcon = selectedIcon;
276+ }
277+ }
278+
279+ if (tmpIcon == null) {
280+ tmpIcon = b.getRolloverIcon();
281+ }
282+ }
283+
284+ if(tmpIcon != null) {
285+ icon = tmpIcon;
286+ }
287+
288+ if(model.isPressed() && model.isArmed()) {
289+ icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),
290+ iconRect.y + getTextShiftOffset());
291+ } else {
292+ icon.paintIcon(c, g, iconRect.x, iconRect.y);
293+ }
294+
295+ }
296+
297+ /**
298+ * As of Java 2 platform v 1.4 this method should not be used or overriden.
299+ * Use the paintText method which takes the AbstractButton argument.
300+ */
301+ protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
302+ AbstractButton b = (AbstractButton) c;
303+ ButtonModel model = b.getModel();
304+ FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
305+ int mnemonicIndex = b.getDisplayedMnemonicIndex();
306+
307+ /* Draw the Text */
308+ if(model.isEnabled()) {
309+ /*** paint the text normally */
310+ g.setColor(b.getForeground());
311+ SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
312+ textRect.x + getTextShiftOffset(),
313+ textRect.y + fm.getAscent() + getTextShiftOffset());
314+ }
315+ else {
316+ /*** paint the text disabled ***/
317+ g.setColor(b.getBackground().brighter());
318+ SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
319+ textRect.x, textRect.y + fm.getAscent());
320+ g.setColor(b.getBackground().darker());
321+ SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
322+ textRect.x - 1, textRect.y + fm.getAscent() - 1);
323+ }
324+ }
325+
326+ /**
327+ * Method which renders the text of the current button.
328+ * <p>
329+ * @param g Graphics context
330+ * @param b Current button to render
331+ * @param textRect Bounding rectangle to render the text.
332+ * @param text String to render
333+ * @since 1.4
334+ */
335+ protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
336+ paintText(g, (JComponent)b, textRect, text);
337+ }
338+
339+ // Method signature defined here overriden in subclasses.
340+ // Perhaps this class should be abstract?
341+ protected void paintFocus(Graphics g, AbstractButton b,
342+ Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
343+ }
344+
345+
346+
347+ protected void paintButtonPressed(Graphics g, AbstractButton b){
348+ }
349+
350+ protected void clearTextShiftOffset(){
351+ this.shiftOffset = 0;
352+ }
353+
354+ protected void setTextShiftOffset(){
355+ this.shiftOffset = defaultTextShiftOffset;
356+ }
357+
358+ protected int getTextShiftOffset() {
359+ return shiftOffset;
360+ }
361+
362+ // ********************************
363+ // Layout Methods
364+ // ********************************
365+ public Dimension getMinimumSize(JComponent c) {
366+ Dimension d = getPreferredSize(c);
367+ View v = (View) c.getClientProperty(BasicHTML.propertyKey);
368+ if (v != null) {
369+ d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
370+ }
371+ return d;
372+ }
373+
374+ public Dimension getPreferredSize(JComponent c) {
375+ AbstractButton b = (AbstractButton)c;
376+ return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());
377+ }
378+
379+ public Dimension getMaximumSize(JComponent c) {
380+ Dimension d = getPreferredSize(c);
381+ View v = (View) c.getClientProperty(BasicHTML.propertyKey);
382+ if (v != null) {
383+ d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
384+ }
385+ return d;
386+ }
387+
388+ /**
389+ * Returns the baseline.
390+ *
391+ * @throws NullPointerException {@inheritDoc}
392+ * @throws IllegalArgumentException {@inheritDoc}
393+ * @see javax.swing.JComponent#getBaseline(int, int)
394+ * @since 1.6
395+ */
396+ public int getBaseline(JComponent c, int width, int height) {
397+ super.getBaseline(c, width, height);
398+ AbstractButton b = (AbstractButton)c;
399+ String text = b.getText();
400+ if (text == null || "".equals(text)) {
401+ return -1;
402+ }
403+ FontMetrics fm = b.getFontMetrics(b.getFont());
404+ layout(b, fm, width, height);
405+ return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),
406+ textRect.width, textRect.height);
407+ }
408+
409+ /**
410+ * Returns an enum indicating how the baseline of the component
411+ * changes as the size changes.
412+ *
413+ * @throws NullPointerException {@inheritDoc}
414+ * @see javax.swing.JComponent#getBaseline(int, int)
415+ * @since 1.6
416+ */
417+ public Component.BaselineResizeBehavior getBaselineResizeBehavior(
418+ JComponent c) {
419+ super.getBaselineResizeBehavior(c);
420+ if (c.getClientProperty(BasicHTML.propertyKey) != null) {
421+ return Component.BaselineResizeBehavior.OTHER;
422+ }
423+ switch(((AbstractButton)c).getVerticalAlignment()) {
424+ case AbstractButton.TOP:
425+ return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
426+ case AbstractButton.BOTTOM:
427+ return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
428+ case AbstractButton.CENTER:
429+ return Component.BaselineResizeBehavior.CENTER_OFFSET;
430+ }
431+ return Component.BaselineResizeBehavior.OTHER;
432+ }
433+
434+ private String layout(AbstractButton b, FontMetrics fm,
435+ int width, int height) {
436+ Insets i = b.getInsets();
437+ viewRect.x = i.left;
438+ viewRect.y = i.top;
439+ viewRect.width = width - (i.right + viewRect.x);
440+ viewRect.height = height - (i.bottom + viewRect.y);
441+
442+ textRect.x = textRect.y = textRect.width = textRect.height = 0;
443+ iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
444+
445+ // layout the text and icon
446+ return SwingUtilities.layoutCompoundLabel(
447+ b, fm, b.getText(), b.getIcon(),
448+ b.getVerticalAlignment(), b.getHorizontalAlignment(),
449+ b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
450+ viewRect, iconRect, textRect,
451+ b.getText() == null ? 0 : b.getIconTextGap());
452+ }
453+
454+ /**
455+ * Returns the ButtonListener for the passed in Button, or null if one
456+ * could not be found.
457+ */
458+ private BasicButtonListener getButtonListener(AbstractButton b) {
459+ MouseMotionListener[] listeners = b.getMouseMotionListeners();
460+
461+ if (listeners != null) {
462+ for (MouseMotionListener listener : listeners) {
463+ if (listener instanceof BasicButtonListener) {
464+ return (BasicButtonListener) listener;
465+ }
466+ }
467+ }
468+ return null;
469+ }
470+
471+}