| /* |
| * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.java.swing.plaf.gtk; |
| |
| import java.awt.Font; |
| import java.util.*; |
| import javax.swing.*; |
| import javax.swing.plaf.synth.*; |
| import com.sun.java.swing.plaf.gtk.GTKEngine.WidgetType; |
| |
| /** |
| * |
| * @author Scott Violet |
| */ |
| class GTKStyleFactory extends SynthStyleFactory { |
| |
| /** |
| * Saves all styles that have been accessed. In most common cases, |
| * the hash key is simply the WidgetType, but in more complex cases |
| * it will be a ComplexKey object that contains arguments to help |
| * differentiate similar styles. |
| */ |
| private final Map<Object, GTKStyle> stylesCache; |
| |
| private Font defaultFont; |
| |
| GTKStyleFactory() { |
| stylesCache = new HashMap<Object, GTKStyle>(); |
| } |
| |
| /** |
| * Returns the <code>GTKStyle</code> to use based on the |
| * <code>Region</code> id |
| * |
| * @param c this parameter isn't used, may be null. |
| * @param id of the region to get the style. |
| */ |
| public synchronized SynthStyle getStyle(JComponent c, Region id) { |
| WidgetType wt = GTKEngine.getWidgetType(c, id); |
| |
| Object key = null; |
| if (id == Region.SCROLL_BAR) { |
| // The style/insets of a scrollbar can depend on a number of |
| // factors (see GTKStyle.getScrollBarInsets()) so use a |
| // complex key here. |
| if (c != null) { |
| JScrollBar sb = (JScrollBar)c; |
| boolean sp = (sb.getParent() instanceof JScrollPane); |
| boolean horiz = (sb.getOrientation() == JScrollBar.HORIZONTAL); |
| boolean ltr = sb.getComponentOrientation().isLeftToRight(); |
| boolean focusable = sb.isFocusable(); |
| key = new ComplexKey(wt, sp, horiz, ltr, focusable); |
| } |
| } |
| else if (id == Region.CHECK_BOX || id == Region.RADIO_BUTTON) { |
| // The style/insets of a checkbox or radiobutton can depend |
| // on the component orientation, so use a complex key here. |
| if (c != null) { |
| boolean ltr = c.getComponentOrientation().isLeftToRight(); |
| key = new ComplexKey(wt, ltr); |
| } |
| } |
| else if (id == Region.BUTTON) { |
| // The style/insets of a button can depend on whether it is |
| // default capable or in a toolbar, so use a complex key here. |
| if (c != null) { |
| JButton btn = (JButton)c; |
| boolean toolButton = (btn.getParent() instanceof JToolBar); |
| boolean defaultCapable = btn.isDefaultCapable(); |
| key = new ComplexKey(wt, toolButton, defaultCapable); |
| } |
| } else if (id == Region.MENU) { |
| if (c instanceof JMenu && ((JMenu) c).isTopLevelMenu() && |
| UIManager.getBoolean("Menu.useMenuBarForTopLevelMenus")) { |
| wt = WidgetType.MENU_BAR; |
| } |
| } |
| |
| if (key == null) { |
| // Otherwise, just use the WidgetType as the key. |
| key = wt; |
| } |
| |
| GTKStyle result = stylesCache.get(key); |
| if (result == null) { |
| result = new GTKStyle(defaultFont, wt); |
| stylesCache.put(key, result); |
| } |
| |
| return result; |
| } |
| |
| void initStyles(Font defaultFont) { |
| this.defaultFont = defaultFont; |
| stylesCache.clear(); |
| } |
| |
| /** |
| * Represents a hash key used for fetching GTKStyle objects from the |
| * cache. In most cases only the WidgetType is used for lookup, but |
| * in some complex cases, other Object arguments can be specified |
| * via a ComplexKey to differentiate the various styles. |
| */ |
| private static class ComplexKey { |
| private final WidgetType wt; |
| private final Object[] args; |
| |
| ComplexKey(WidgetType wt, Object... args) { |
| this.wt = wt; |
| this.args = args; |
| } |
| |
| @Override |
| public int hashCode() { |
| int hash = wt.hashCode(); |
| if (args != null) { |
| for (Object arg : args) { |
| hash = hash*29 + (arg == null ? 0 : arg.hashCode()); |
| } |
| } |
| return hash; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof ComplexKey)) { |
| return false; |
| } |
| ComplexKey that = (ComplexKey)o; |
| if (this.wt == that.wt) { |
| if (this.args == null && that.args == null) { |
| return true; |
| } |
| if (this.args != null && that.args != null && |
| this.args.length == that.args.length) |
| { |
| for (int i = 0; i < this.args.length; i++) { |
| Object a1 = this.args[i]; |
| Object a2 = that.args[i]; |
| if (!(a1==null ? a2==null : a1.equals(a2))) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| String str = "ComplexKey[wt=" + wt; |
| if (args != null) { |
| str += ",args=["; |
| for (int i = 0; i < args.length; i++) { |
| str += args[i]; |
| if (i < args.length-1) str += ","; |
| } |
| str += "]"; |
| } |
| str += "]"; |
| return str; |
| } |
| } |
| } |