KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > plaf > gtk > GtkLFCustoms


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.swing.plaf.gtk;
21
22 import java.awt.Color JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Font JavaDoc;
25 import java.awt.Graphics JavaDoc;
26 import java.awt.GraphicsConfiguration JavaDoc;
27 import java.awt.GraphicsEnvironment JavaDoc;
28 import java.awt.Image JavaDoc;
29 import java.awt.Transparency JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import javax.swing.BorderFactory JavaDoc;
32 import javax.swing.Icon JavaDoc;
33 import javax.swing.JComponent JavaDoc;
34 import javax.swing.JTree JavaDoc;
35 import javax.swing.LookAndFeel JavaDoc;
36 import javax.swing.UIDefaults JavaDoc;
37 import javax.swing.UIManager JavaDoc;
38 import javax.swing.plaf.FontUIResource JavaDoc;
39 import javax.swing.plaf.synth.Region JavaDoc;
40 import javax.swing.plaf.synth.SynthConstants JavaDoc;
41 import javax.swing.plaf.synth.SynthContext JavaDoc;
42 import javax.swing.plaf.synth.SynthLookAndFeel JavaDoc;
43 import javax.swing.plaf.synth.SynthStyle JavaDoc;
44 import org.netbeans.swing.plaf.LFCustoms;
45 import org.netbeans.swing.plaf.util.UIUtils;
46
47 /** UI customizations for GTK look and feel
48  *
49  * @author Tim Boudreau
50  */

51 public class GtkLFCustoms extends LFCustoms {
52     private Object JavaDoc light = new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.WHITE, Color.GRAY);
53     private Object JavaDoc control = new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.MID, Color.GRAY);
54     private Object JavaDoc controlFont = new ThemeValue (ThemeValue.REGION_TAB, new FontUIResource JavaDoc ("Dialog", Font.PLAIN, 11)); //NOI18N
55

56
57     //Background colors for winsys tabs
58

59
60     public Object JavaDoc[] createApplicationSpecificKeysAndValues () {
61         //Avoid using ThemeValue if it can't work - mainly due to testing issues when trying to run GTK UI customizations
62
//on the Mac, which doesn't have a GTKLookAndFeel
63

64         Object JavaDoc selBg = ThemeValue.functioning() ? new ThemeValue (ThemeValue.REGION_BUTTON, ThemeValue.DARK, Color.CYAN) : (Object JavaDoc) Color.CYAN;
65         Object JavaDoc selFg = ThemeValue.functioning() ? new ThemeValue (ThemeValue.REGION_BUTTON, ThemeValue.TEXT_FOREGROUND, Color.BLACK) : (Object JavaDoc) Color.BLACK;
66
67         Object JavaDoc fb = new Color JavaDoc (144, 144, 255);
68         Object JavaDoc tabBg = ThemeValue.functioning() ? new ThemeValue (ThemeValue.REGION_INTFRAME, ThemeValue.DARK, fb) : (Object JavaDoc) fb;
69         
70         if (!ThemeValue.functioning()) {
71             Integer JavaDoc i = (Integer JavaDoc) UIManager.get("customFontSize"); //NOI18N
72
int sz = 11;
73             if (i != null) {
74                 sz = i.intValue();
75             }
76             controlFont = new Font JavaDoc ("Dialog", Font.PLAIN, sz); //NOI18N
77
}
78
79         Color JavaDoc borderColor = (Color JavaDoc) UIManager.get("InternalFrame.borderShadow");
80         if (borderColor == null) {
81             borderColor = new Color JavaDoc(144,150,162);
82         }
83         
84         Object JavaDoc[] result = {
85             PROPSHEET_SELECTION_BACKGROUND, selBg,
86             PROPSHEET_SELECTION_FOREGROUND, selFg,
87             PROPSHEET_SELECTED_SET_BACKGROUND, selBg,
88             PROPSHEET_SELECTED_SET_FOREGROUND, selFg,
89             PROPSHEET_BUTTON_COLOR, selFg,
90             
91             PROPSHEET_SET_BACKGROUND, ThemeValue.functioning() ? (Object JavaDoc) control : (Object JavaDoc) Color.CYAN,
92             PROPSHEET_DISABLED_FOREGROUND, new Color JavaDoc(161,161,146),
93             "Table.selectionBackground", selBg, //NOI18N
94
"Table.selectionForeground", selFg, //NOI18N
95
PROPSHEET_BACKGROUND, Color.WHITE,
96             "window", light,
97             
98             VIEW_TAB_OUTER_BORDER, BorderFactory.createEmptyBorder(),
99             VIEW_TAB_TABS_BORDER, BorderFactory.createEmptyBorder(),
100             VIEW_TAB_CONTENT_BORDER, BorderFactory.createMatteBorder(0,1,1,1,borderColor),
101             EDITOR_TAB_OUTER_BORDER, BorderFactory.createEmptyBorder(),
102             EDITOR_TAB_CONTENT_BORDER, BorderFactory.createMatteBorder(0,1,1,1,borderColor),
103             EDITOR_TAB_TABS_BORDER, BorderFactory.createEmptyBorder(),
104             
105             EDITOR_STATUS_LEFT_BORDER, new InsetBorder (false, true),
106             EDITOR_STATUS_RIGHT_BORDER, new InsetBorder (false, false),
107             EDITOR_STATUS_ONLYONEBORDER, new InsetBorder (false, false),
108             EDITOR_STATUS_INNER_BORDER, new InsetBorder (false, true),
109             
110             OUTPUT_BACKGROUND, control,
111             OUTPUT_HYPERLINK_FOREGROUND, selFg,
112             OUTPUT_SELECTION_BACKGROUND, selBg,
113             
114             "controlFont", controlFont, //NOI18N
115

116             //UI Delegates for the tab control
117
EDITOR_TAB_DISPLAYER_UI,
118                 "org.netbeans.swing.tabcontrol.plaf.GtkEditorTabDisplayerUI", //NOI18N
119
VIEW_TAB_DISPLAYER_UI,
120                 "org.netbeans.swing.tabcontrol.plaf.GtkViewTabDisplayerUI", //NOI18N
121
SLIDING_TAB_BUTTON_UI, "org.netbeans.swing.tabcontrol.plaf.SlidingTabDisplayerButtonUI", //NOI18N
122
SLIDING_BUTTON_UI, "org.netbeans.swing.tabcontrol.plaf.GtkSlidingButtonUI", //NOI18N
123

124             DESKTOP_BACKGROUND, ThemeValue.functioning() ? new ThemeValue (ThemeValue.REGION_BUTTON, ThemeValue.LIGHT, Color.GRAY) : (Object JavaDoc) Color.GRAY,
125             EXPLORER_MINISTATUSBAR_BORDER, BorderFactory.createEmptyBorder(),
126
127             //TOOLBAR_UI, "org.netbeans.swing.plaf.gtk.GtkToolbarUI", //NOI18N
128

129             PROGRESS_CANCEL_BUTTON_ICON, UIUtils.loadImage("org/netbeans/swing/plaf/resources/cancel_task_linux_mac.png"),
130             "winclassic_tab_sel_gradient", tabBg,
131         };
132         return result;
133     }
134     
135     public Object JavaDoc[] createLookAndFeelCustomizationKeysAndValues() {
136         JTree JavaDoc tree = new JTree JavaDoc();
137         Icon JavaDoc treeExpandedIcon = SynthIconWrapper.createSynthIconWrapper("Tree.expandedIcon", tree, Region.TREE);
138         // fallback
139
if (treeExpandedIcon == null) {
140             treeExpandedIcon = new GTKExpandedIcon();
141         }
142         Icon JavaDoc treeCollapsedIcon = SynthIconWrapper.createSynthIconWrapper("Tree.collapsedIcon", tree, Region.TREE);
143         // fallback
144
if (treeCollapsedIcon == null) {
145             treeCollapsedIcon = new GTKCollapsedIcon();
146         }
147                 
148         if (ThemeValue.functioning()) {
149             return new Object JavaDoc[] {
150                 //XXX once the JDK team has integrated support for standard
151
//UIManager keys into 1.5 (not there as of b47), these can
152
//probably be deleted, resulting in a performance improvement:
153
"control", control,
154                 "controlHighlight", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.LIGHT, Color.LIGHT_GRAY), //NOI18N
155
"controlShadow", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.DARK, Color.DARK_GRAY), //NOI18N
156
"controlDkShadow", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.BLACK, Color.BLACK), //NOI18N
157
"controlLtHighlight", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.WHITE, Color.WHITE), //NOI18N
158
"textText", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.TEXT_FOREGROUND, Color.BLACK), //NOI18N
159
"text", new ThemeValue (ThemeValue.REGION_PANEL, ThemeValue.TEXT_BACKGROUND, Color.GRAY), //NOI18N
160

161                 "tab_unsel_fill", control, //NOI18N
162

163                 "SplitPane.dividerSize", new Integer JavaDoc (2), //NOI18N
164

165                 SYSTEMFONT, controlFont, //NOI18N
166
USERFONT, controlFont, //NOI18N
167
MENUFONT, controlFont, //NOI18N
168
LISTFONT, controlFont, //NOI18N
169
"Label.font", controlFont, //NOI18N
170
"Panel.font", controlFont, //NOI18N
171

172                 // workaround: GTKLookAndFeel FileChooser is unusable, cannot
173
// choose a dir and doesn't look native anyway. We force MetalFileChooserUI
174

175                 "FileChooserUI", "javax.swing.plaf.metal.MetalFileChooserUI", // NOI18N
176
"FileView.computerIcon", javax.swing.plaf.metal.MetalIconFactory.getTreeComputerIcon(), // NOI18N
177
"FileView.hardDriveIcon", javax.swing.plaf.metal.MetalIconFactory.getTreeHardDriveIcon(), // NOI18N
178
"FileView.floppyDriveIcon", javax.swing.plaf.metal.MetalIconFactory.getTreeFloppyDriveIcon(), // NOI18N
179
"FileChooser.newFolderIcon", javax.swing.plaf.metal.MetalIconFactory.getFileChooserNewFolderIcon(), // NOI18N
180
"FileChooser.upFolderIcon", javax.swing.plaf.metal.MetalIconFactory.getFileChooserUpFolderIcon(), // NOI18N
181
"FileChooser.homeFolderIcon", javax.swing.plaf.metal.MetalIconFactory.getFileChooserHomeFolderIcon(), // NOI18N
182
"FileChooser.detailsViewIcon", javax.swing.plaf.metal.MetalIconFactory.getFileChooserDetailViewIcon(), // NOI18N
183
"FileChooser.listViewIcon", javax.swing.plaf.metal.MetalIconFactory.getFileChooserListViewIcon(), // NOI18N
184
"FileChooser.usesSingleFilePane", Boolean.TRUE, // NOI18N
185
"FileChooser.ancestorInputMap", // NOI18N
186
new UIDefaults.LazyInputMap JavaDoc(new Object JavaDoc[] {
187                                 "ESCAPE", "cancelSelection", // NOI18N
188
"F2", "editFileName", // NOI18N
189
"F5", "refresh", // NOI18N
190
"BACK_SPACE", "Go Up", // NOI18N
191
"ENTER", "approveSelection" // NOI18N
192
}),
193                 // workaround for GTK: put GTK icons on place where there are also on other LFs
194
"Tree.expandedIcon", treeExpandedIcon,
195                 "Tree.collapsedIcon", treeCollapsedIcon,
196             };
197         } else {
198             Object JavaDoc[] result = new Object JavaDoc[] {
199                 TOOLBAR_UI, new UIDefaults.ProxyLazyValue JavaDoc("org.netbeans.swing.plaf.gtk.GtkToolbarUI"), //NOI18N
200
};
201             return result;
202         }
203     }
204     
205     /** Workaround for GTK - retrieves GTK icon and returns it in static form
206      * which is usable also outside Synth implementation (doesn't need SynthContext).
207      */

208     private static final class SynthIconWrapper implements Icon JavaDoc {
209
210         /** Creates wrapper for Synth icon of given iconID, which can be used
211          * outside Synth.
212          *
213          * @return Icon or null if Icon can't be created for some reason
214          */

215         public static Icon JavaDoc createSynthIconWrapper (String JavaDoc iconID, JComponent JavaDoc comp, Region JavaDoc region) {
216             LookAndFeel JavaDoc laf = UIManager.getLookAndFeel();
217
218             if (!(laf instanceof SynthLookAndFeel JavaDoc)) {
219                 return null;
220             }
221
222             SynthStyle JavaDoc style = ((SynthLookAndFeel JavaDoc)laf).getStyleFactory().getStyle(comp, region);
223             SynthContext JavaDoc context = new SynthContext JavaDoc(comp, region, style, SynthConstants.ENABLED);
224             Icon JavaDoc synthIcon = style.getIcon(context, iconID);
225
226             if (synthIcon == null) {
227                 return null;
228             }
229
230             Method JavaDoc paintMethod;
231             try {
232                 paintMethod = synthIcon.getClass().getMethod(
233                         "paintIcon", SynthContext JavaDoc.class, Graphics JavaDoc.class,
234                         Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE);
235                 paintMethod.setAccessible(true);
236             } catch (Exception JavaDoc e) {
237                 // return null in case of any problems (method not available anymore)
238
return null;
239             }
240             
241             GraphicsConfiguration JavaDoc gc = GraphicsEnvironment.getLocalGraphicsEnvironment().
242                     getDefaultScreenDevice().getDefaultConfiguration();
243
244             // Create an image that supports transparent pixels
245
Image JavaDoc img = gc.createCompatibleImage(synthIcon.getIconWidth(),
246                     synthIcon.getIconHeight(), Transparency.BITMASK);
247             
248             return new SynthIconWrapper(synthIcon, context, paintMethod, img);
249         }
250         
251         private Icon JavaDoc original;
252         
253         private Method JavaDoc paintMethod;
254         
255         private SynthContext JavaDoc context;
256         
257         private Image JavaDoc image;
258         
259         private SynthIconWrapper(Icon JavaDoc original, SynthContext JavaDoc context, Method JavaDoc paintMethod, Image JavaDoc image) {
260             this.original = original;
261             this.paintMethod = paintMethod;
262             this.context = context;
263             this.image = image;
264         }
265         
266         public void paintIcon(Component JavaDoc c, Graphics JavaDoc g, int x, int y) {
267             try {
268                 paintMethod.invoke(original, context, image.getGraphics(), 0, 0,
269                                    getIconWidth(), getIconHeight());
270             } catch (Exception JavaDoc ex) {
271                 // fail silently, image will just be empty, no tragedy
272
return;
273             }
274             g.drawImage(image, x, y, null);
275         }
276
277         public int getIconWidth() {
278             return original.getIconWidth();
279         }
280
281         public int getIconHeight() {
282             return original.getIconHeight();
283         }
284 }
285     
286     
287     /** Temporary workaround for GTK L&F */
288     private static abstract class GTKIcon implements Icon JavaDoc {
289         private static final int SIZE = 11;
290         public int getIconWidth() {
291             return GTKIcon.SIZE;
292         }
293         
294         public int getIconHeight() {
295             return GTKIcon.SIZE;
296         }
297     }
298
299     /**
300      * Temporary workaround for GTK L&F - they provide an icon which does not
301      * know its width or height until it has been painted. So for it to work
302      * correctly, we have this silliness.
303      */

304     private static final class GTKCollapsedIcon extends GTKIcon {
305         public void paintIcon(Component JavaDoc c, Graphics JavaDoc g, int x, int y) {
306             g.translate(x, y);
307             int mid, height, thick, i, j, up, down;
308             int size = Math.min(getIconWidth(),getIconHeight());
309             mid = (size / 2);
310             height = size / 2 + 1;
311             thick = Math.max(1, size / 7);
312             
313             i = size / 2 - height / 2 - 1;
314             
315             // Fill in the background of the expander icon.
316
g.setColor((Color JavaDoc) UIManager.get("Button.background"));
317             for (j = height - 1; j > 0; j--) {
318                 g.drawLine(i, mid - j + 1, i, mid + j - 1);
319                 i++;
320             }
321             
322             g.setColor((Color JavaDoc) UIManager.get("Button.foreground"));
323             i = size / 2 - height / 2 - 1;
324             down = thick - 1;
325             // Draw the base of the triangle.
326
for (up = 0; up < thick; up++) {
327                 g.drawLine(i + up, 0 - down, i + up, size + down);
328                 down--;
329             }
330             i++;
331             
332             // Paint sides of triangle.
333
for (j = height - 1; j > 0; j--) {
334                 for (up = 0; up < thick; up++) {
335                     g.drawLine(i, mid - j + 1 - up, i, mid - j + 1 - up);
336                     g.drawLine(i, mid + j - 1 + up, i, mid + j - 1 + up);
337                 }
338                 i++;
339             }
340             
341             // Paint remainder of tip if necessary.
342
if (thick > 1) {
343                 for (up = thick - 2; up >= 0; up--) {
344                     g.drawLine(i, mid - up, i, mid + up);
345                     i++;
346                 }
347             }
348             
349             g.translate(-x, -y);
350         }
351     }
352
353     /**
354      * Temporary workaround for GTK L&F - they provide an icon which does not
355      * know its width or height until it has been painted. So for it to work
356      * correctly, we have this silliness.
357      */

358     private static final class GTKExpandedIcon extends GTKIcon {
359         public void paintIcon(Component JavaDoc c, Graphics JavaDoc g, int x, int y) {
360             g.translate(x, y);
361             int mid, height, thick, i, j, up, down;
362             int size = Math.min(getIconWidth(),getIconHeight());
363             mid = (size / 2);
364             height = size / 2 + 1;
365             thick = Math.max(1, size / 7);
366  
367             j = size / 2 - height / 2 - 1;
368             // Fill in the background of the expander icon.
369
g.setColor((Color JavaDoc) UIManager.get("Button.background"));
370             for (i = height - 1; i > 0; i--) {
371                 g.drawLine(mid - i + 1, j, mid + i - 1, j);
372                 j++;
373             }
374
375             g.setColor((Color JavaDoc) UIManager.get("Button.foreground"));
376             j = size / 2 - height / 2 - 1;
377             down = thick - 1;
378             // Draw the base of the triangle.
379
for (up = 0; up < thick; up++) {
380                 g.drawLine(0 - down, j + up, size + down, j + up);
381                 down--;
382             }
383             j++;
384
385             // Paint sides of triangle.
386
for (i = height - 1; i > 0; i--) {
387                 for (up = 0; up < thick; up++ ) {
388                     g.drawLine(mid - i + 1 - up, j, mid - i + 1 - up, j);
389                     g.drawLine(mid + i - 1 + up, j, mid + i - 1 + up, j);
390                 }
391                 j++;
392             }
393
394             // Paint remainder of tip if necessary.
395
if (thick > 1) {
396                 for (up = thick - 2; up >= 0; up--) {
397                     g.drawLine(mid - up, j, mid + up, j);
398                     j++;
399                 }
400             }
401              
402             g.translate(-x, -y);
403         }
404     }
405     
406
407 }
408
Popular Tags