2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.ide.ui;
18 import com.intellij.CommonBundle;
19 import com.intellij.ide.IdeBundle;
20 import com.intellij.idea.StartupUtil;
21 import com.intellij.openapi.components.*;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.ui.Messages;
24 import com.intellij.openapi.util.Comparing;
25 import com.intellij.openapi.util.IconLoader;
26 import com.intellij.openapi.util.SystemInfo;
27 import com.intellij.ui.ColoredSideBorder;
28 import com.intellij.ui.IdeaBlueMetalTheme;
29 import com.intellij.ui.ScreenUtil;
30 import com.intellij.ui.mac.MacPopupMenuUI;
31 import com.intellij.ui.plaf.beg.*;
32 import com.intellij.util.ui.UIUtil;
33 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
34 import org.jdom.Element;
35 import org.jetbrains.annotations.NonNls;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
40 import javax.swing.border.Border;
41 import javax.swing.event.EventListenerList;
42 import javax.swing.plaf.ColorUIResource;
43 import javax.swing.plaf.FontUIResource;
44 import javax.swing.plaf.metal.DefaultMetalTheme;
45 import javax.swing.plaf.metal.MetalLookAndFeel;
46 import javax.swing.text.DefaultEditorKit;
48 import java.awt.event.KeyEvent;
49 import java.lang.reflect.InvocationTargetException;
50 import java.lang.reflect.Method;
51 import java.util.Arrays;
52 import java.util.Comparator;
53 import java.util.HashMap;
56 * @author Eugene Belyaev
57 * @author Vladimir Kondratyev
61 roamingType = RoamingType.PER_PLATFORM,
64 file = "$APP_CONFIG$/options.xml")})
65 public final class LafManagerImpl extends LafManager implements ApplicationComponent, PersistentStateComponent<Element> {
66 private static final Logger LOG=Logger.getInstance("#com.intellij.ide.ui.LafManager");
68 @NonNls private static final String IDEA_LAF_CLASSNAME = "idea.laf.classname";
71 * One of the possible values of -Didea.popup.weight property. Heavy weight means
72 * that all popups are shown inside the window. Under UNIXes it's possible to configure
73 * window manager "Focus follows mouse with Auto Raise". In this case popup window will
74 * be immediately closed after showing.
76 @NonNls private static final String HEAVY_WEIGHT_POPUP="heavy";
78 * One of the possible values of -Didea.popup.weight property. Medium weight means
79 * that popup will be shouw inside the paren't JLayeredPane if it can be fit to it.
80 * Otherwise popup will be shown in the window. This mode is defaut for the Swing but
81 * it's very slow (much slower then heavy weight popups).
83 @NonNls private static final String MEDIUM_WEIGHT_POPUP="medium";
85 private final EventListenerList myListenerList;
86 private final UIManager.LookAndFeelInfo[] myLafs;
87 private UIManager.LookAndFeelInfo myCurrentLaf;
89 @NonNls private static final String[] ourPatcheableFontResources = new String[]{
90 "Button.font", "ToggleButton.font", "RadioButton.font", "CheckBox.font", "ColorChooser.font", "ComboBox.font",
91 "Label.font", "List.font", "MenuBar.font", "MenuItem.font", "MenuItem.acceleratorFont", "RadioButtonMenuItem.font",
92 "CheckBoxMenuItem.font", "Menu.font", "PopupMenu.font", "OptionPane.font", "Panel.font", "ProgressBar.font",
93 "ScrollPane.font", "Viewport.font", "TabbedPane.font", "Table.font", "TableHeader.font", "TextField.font",
94 "PasswordField.font", "TextArea.font", "TextPane.font", "EditorPane.font", "TitledBorder.font", "ToolBar.font",
95 "ToolTip.font", "Tree.font"
97 @NonNls private static final String[] ourFileChooserTextKeys = new String[] {
98 "FileChooser.viewMenuLabelText", "FileChooser.newFolderActionLabelText", "FileChooser.listViewActionLabelText",
99 "FileChooser.detailsViewActionLabelText", "FileChooser.refreshActionLabelText"
102 private final HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>> myStoredDefaults = new HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>>();
103 private final UISettings myUiSettings;
105 @NonNls private static final String ELEMENT_LAF = "laf";
106 @NonNls private static final String ATTRIBUTE_CLASS_NAME = "class-name";
108 /** invoked by reflection
109 * @param uiSettings */
110 LafManagerImpl(UISettings uiSettings){
111 myUiSettings = uiSettings;
112 myListenerList=new EventListenerList();
114 IdeaLookAndFeelInfo ideaLaf=new IdeaLookAndFeelInfo();
115 UIManager.LookAndFeelInfo[] installedLafs=UIManager.getInstalledLookAndFeels();
117 // Get all installed LAFs
118 myLafs=new UIManager.LookAndFeelInfo[1+installedLafs.length];
120 System.arraycopy(installedLafs,0,myLafs,1,installedLafs.length);
121 Arrays.sort(myLafs,new MyComparator());
123 // Setup current LAF. Unfortunately it's system depended.
124 myCurrentLaf=getDefaultLaf();
128 * Adds specified listener
130 public void addLafManagerListener(@NotNull final LafManagerListener l){
131 myListenerList.add(LafManagerListener.class, l);
135 * Removes specified listener
137 public void removeLafManagerListener(@NotNull final LafManagerListener l){
138 myListenerList.remove(LafManagerListener.class, l);
141 private void fireLookAndFeelChanged(){
142 LafManagerListener[] listeners = myListenerList.getListeners(LafManagerListener.class);
143 for (LafManagerListener listener : listeners) {
144 listener.lookAndFeelChanged(this);
149 public String getComponentName(){
153 public void initComponent() {
154 setCurrentLookAndFeel(findLaf(myCurrentLaf.getClassName())); // setup default LAF or one specfied by readExternal.
158 public void disposeComponent(){}
160 public void loadState(final Element element) {
161 String className=null;
162 for (final Object o : element.getChildren()) {
163 Element child = (Element)o;
164 if (ELEMENT_LAF.equals(child.getName())) {
165 className = child.getAttributeValue(ATTRIBUTE_CLASS_NAME);
170 UIManager.LookAndFeelInfo laf=findLaf(className);
171 // If LAF is undefined (wrong class name or something else) we have set default LAF anyway.
176 if (myCurrentLaf != null && !laf.getClassName().equals(myCurrentLaf.getClassName())) {
177 setCurrentLookAndFeel(laf);
184 public Element getState() {
185 Element element = new Element("state");
186 if(myCurrentLaf.getClassName()!=null){
187 Element child=new Element(ELEMENT_LAF);
188 child.setAttribute(ATTRIBUTE_CLASS_NAME,myCurrentLaf.getClassName());
189 element.addContent(child);
194 public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){
195 return myLafs.clone();
198 public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){
202 public boolean isUnderAquaLookAndFeel() {
203 //noinspection HardCodedStringLiteral
204 return "Mac OS X".equals(getCurrentLookAndFeel().getName());
207 public boolean isUnderQuaquaLookAndFeel() {
208 //noinspection HardCodedStringLiteral
209 return "Quaqua".equals(getCurrentLookAndFeel().getName());
213 * @return default LookAndFeelInfo for the running OS. For Win32 and
214 * Linux the method returns Alloy LAF or IDEA LAF if first not found, for Mac OS X it returns Aqua
216 private UIManager.LookAndFeelInfo getDefaultLaf(){
217 if(SystemInfo.isMac) {
218 UIManager.LookAndFeelInfo laf=findLaf(UIManager.getSystemLookAndFeelClassName());
219 LOG.assertTrue(laf!=null);
223 String defaultLafName = StartupUtil.getDefaultLAF();
224 if (defaultLafName != null) {
225 UIManager.LookAndFeelInfo defaultLaf = findLaf(defaultLafName);
226 if (defaultLaf != null) {
230 return findLaf(IDEA_LAF_CLASSNAME);
235 * Finds LAF by its class name.
238 private UIManager.LookAndFeelInfo findLaf(String className){
239 for (UIManager.LookAndFeelInfo laf : myLafs) {
240 if (Comparing.equal(laf.getClassName(), className)) {
248 * Sets current LAF. The method doesn't update component hierarchy.
250 public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo){
251 if(findLaf(lookAndFeelInfo.getClassName())==null){
252 LOG.error("unknown LookAndFeel : "+lookAndFeelInfo);
258 if(IDEA_LAF_CLASSNAME.equals(lookAndFeelInfo.getClassName())){ // that is IDEA default LAF
259 IdeaLaf laf=new IdeaLaf();
260 IdeaLaf.setCurrentTheme(new IdeaBlueMetalTheme());
262 UIManager.setLookAndFeel(laf);
263 } catch (Exception exc) {
264 Messages.showMessageDialog(
265 IdeBundle.message("error.cannot.set.look.and.feel", lookAndFeelInfo.getName()),
266 CommonBundle.getErrorTitle(),
267 Messages.getErrorIcon()
271 }else{ // non default LAF
273 LookAndFeel laf=((LookAndFeel)Class.forName(lookAndFeelInfo.getClassName()).newInstance());
274 if(laf instanceof MetalLookAndFeel){
275 MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());
277 UIManager.setLookAndFeel(laf);
278 } catch(Exception exc) {
279 Messages.showMessageDialog(
280 IdeBundle.message("error.cannot.set.look.and.feel", lookAndFeelInfo.getName()),
281 CommonBundle.getErrorTitle(),
282 Messages.getErrorIcon()
287 myCurrentLaf=lookAndFeelInfo;
289 // The following code is a trick! By default Swing uses lightweight and "medium" weight
290 // popups to show JPopupMenu. The code below force the creation of real heavyweight menus.
291 // It dramatically increases speed of popups.
293 //noinspection HardCodedStringLiteral
294 String popupWeight=System.getProperty("idea.popup.weight");
295 if(popupWeight==null){ // use defaults if popup weight isn't specified
296 if(SystemInfo.isWindows){
297 popupWeight=HEAVY_WEIGHT_POPUP;
298 }else{ // UNIXes (Linux and MAC) go here
299 popupWeight=MEDIUM_WEIGHT_POPUP;
303 if (SystemInfo.isMacOSLeopard) {
304 // Force heavy weight popups under Leopard, otherwise they don't have shadow or any kind of border.
305 popupWeight = HEAVY_WEIGHT_POPUP;
308 popupWeight = popupWeight.trim();
310 PopupFactory popupFactory;
312 final PopupFactory oldFactory = PopupFactory.getSharedInstance();
313 if (!(oldFactory instanceof OurPopupFactory)) {
314 if (HEAVY_WEIGHT_POPUP.equals(popupWeight)) {
315 popupFactory = new OurPopupFactory() {
316 public Popup getPopup(
321 ) throws IllegalArgumentException {
322 final Point point = fixPopupLocation(contents, x, y);
323 if (SystemInfo.isLinux) {
324 return new Popup(owner, contents, point.x, point.y){};
326 return oldFactory.getPopup(owner, contents, point.x, point.y);
330 else if (MEDIUM_WEIGHT_POPUP.equals(popupWeight)) {
331 popupFactory = new OurPopupFactory() {
333 public Popup getPopup(final Component owner, final Component contents, final int x, final int y) throws IllegalArgumentException {
334 return createPopup(owner, contents, x, y);
337 private Popup createPopup(final Component owner, final Component contents, final int x, final int y) {
338 final Point point = fixPopupLocation(contents, x, y);
339 if (SystemInfo.isLinux) {
340 return new Popup(owner, contents, point.x, point.y){};
342 return oldFactory.getPopup(owner, contents, point.x, point.y);
347 throw new IllegalStateException("unknown value of property -Didea.popup.weight: " + popupWeight);
349 PopupFactory.setSharedInstance(popupFactory);
352 // update ui for popup menu to get round corners
353 if (UIUtil.isUnderAquaLookAndFeel()) {
354 final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
355 uiDefaults.put("PopupMenuUI", MacPopupMenuUI.class.getCanonicalName());
356 final Icon icon = getAquaMenuInvertedIcon();
358 uiDefaults.put("Menu.invertedArrowIcon", icon);
364 private static Icon getAquaMenuInvertedIcon() {
365 if (!UIUtil.isUnderAquaLookAndFeel()) return null;
366 final Icon arrow = (Icon) UIManager.get("Menu.arrowIcon");
367 if (arrow == null) return null;
370 final Method method = arrow.getClass().getMethod("getInvertedIcon");
371 if (method != null) {
372 method.setAccessible(true);
373 return (Icon) method.invoke(arrow);
378 catch (NoSuchMethodException e1) {
381 catch (InvocationTargetException e1) {
384 catch (IllegalAccessException e1) {
389 private Point fixPopupLocation(final Component contents, final int x, final int y) {
390 if (!(contents instanceof JToolTip)) return new Point(x, y);
392 final PointerInfo info;
394 info = MouseInfo.getPointerInfo();
396 catch (InternalError e) {
397 // http://www.jetbrains.net/jira/browse/IDEADEV-21390
398 // may happen under Mac OSX 10.5
399 return new Point(x, y);
404 final Point mouse = info.getLocation();
405 deltaY = mouse.y - y;
408 final Dimension size = contents.getPreferredSize();
409 final Rectangle rec = new Rectangle(new Point(x, y), size);
410 ScreenUtil.moveRectangleToFitTheScreen(rec);
416 return rec.getLocation();
421 * Updates LAF of all windows. The method also updates font of components
422 * as it's configured in <code>UISettings</code>.
424 public void updateUI(){
425 UIDefaults lookAndFeelDefaults=UIManager.getLookAndFeelDefaults();
426 initInputMapDefaults(lookAndFeelDefaults);
427 patchFileChooserStrings(lookAndFeelDefaults);
428 if (shouldPatchLAFFonts()) {
429 storeOriginalFontDefaults(lookAndFeelDefaults);
430 initFontDefaults(lookAndFeelDefaults);
433 restoreOriginalFontDefaults(lookAndFeelDefaults);
436 Frame[] frames=Frame.getFrames();
437 for (Frame frame : frames) {
440 fireLookAndFeelChanged();
443 private void patchFileChooserStrings(final UIDefaults defaults) {
444 if (!defaults.containsKey(ourFileChooserTextKeys [0])) {
445 // Alloy L&F does not define strings for names of context menu actions, so we have to patch them in here
446 for (String key : ourFileChooserTextKeys) {
447 defaults.put(key, IdeBundle.message(key));
452 private void restoreOriginalFontDefaults(UIDefaults defaults) {
453 UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel();
454 HashMap<String, Object> lfDefaults = myStoredDefaults.get(lf);
455 if (lfDefaults != null) {
456 for (String resource : ourPatcheableFontResources) {
457 defaults.put(resource, lfDefaults.get(resource));
462 private void storeOriginalFontDefaults(UIDefaults defaults) {
463 UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel();
464 HashMap<String, Object> lfDefaults = myStoredDefaults.get(lf);
465 if (lfDefaults == null) {
466 lfDefaults = new HashMap<String, Object>();
467 for (String resource : ourPatcheableFontResources) {
468 lfDefaults.put(resource, defaults.get(resource));
470 myStoredDefaults.put(lf, lfDefaults);
474 private boolean shouldPatchLAFFonts() {
475 //noinspection HardCodedStringLiteral
476 return getCurrentLookAndFeel().getName().startsWith("IDEA") || UISettings.getInstance().OVERRIDE_NONIDEA_LAF_FONTS;
479 private static void updateUI(Window window){
480 if(!window.isDisplayable()){
483 SwingUtilities.updateComponentTreeUI(window);
484 Window[] children=window.getOwnedWindows();
485 for (Window aChildren : children) {
491 * Repaints all displayable window.
493 public void repaintUI(){
494 Frame[] frames=Frame.getFrames();
495 for (Frame frame : frames) {
500 private static void repaintUI(Window window){
501 if(!window.isDisplayable()){
505 Window[] children=window.getOwnedWindows();
506 for (Window aChildren : children) {
507 repaintUI(aChildren);
511 private static void installCutCopyPasteShortcuts(InputMap inputMap, boolean useSimpleActionKeys){
512 String copyActionKey = useSimpleActionKeys ? "copy" : DefaultEditorKit.copyAction;
513 String pasteActionKey = useSimpleActionKeys ? "paste" : DefaultEditorKit.pasteAction;
514 String cutActionKey = useSimpleActionKeys ? "cut" : DefaultEditorKit.cutAction;
515 // Ctrl+Ins, Shift+Ins, Shift+Del
516 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),copyActionKey);
517 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,KeyEvent.SHIFT_MASK|KeyEvent.SHIFT_DOWN_MASK),pasteActionKey);
518 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,KeyEvent.SHIFT_MASK|KeyEvent.SHIFT_DOWN_MASK),cutActionKey);
519 // Ctrl+C, Ctrl+V, Ctrl+X
520 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),copyActionKey);
521 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),pasteActionKey);
522 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),DefaultEditorKit.cutAction);
525 @SuppressWarnings({"HardCodedStringLiteral"})
526 private static void initInputMapDefaults(UIDefaults defaults){
527 // Make ENTER work in JTrees
528 InputMap treeInputMap = (InputMap)defaults.get("Tree.focusInputMap");
529 if(treeInputMap!=null){ // it's really possible. For examle, GTK+ doesn't have such map
530 treeInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"toggle");
532 // Cut/Copy/Paste in JTextAreas
533 InputMap textAreaInputMap=(InputMap)defaults.get("TextArea.focusInputMap");
534 if(textAreaInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
535 installCutCopyPasteShortcuts(textAreaInputMap, false);
537 // Cut/Copy/Paste in JTextFields
538 InputMap textFieldInputMap=(InputMap)defaults.get("TextField.focusInputMap");
539 if(textFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
540 installCutCopyPasteShortcuts(textFieldInputMap, false);
542 // Cut/Copy/Paste in JPAsswordField
543 InputMap passwordFieldInputMap=(InputMap)defaults.get("PasswordField.focusInputMap");
544 if(passwordFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
545 installCutCopyPasteShortcuts(passwordFieldInputMap, false);
547 // Cut/Copy/Paste in JTables
548 InputMap tableInputMap=(InputMap)defaults.get("Table.ancestorInputMap");
549 if(tableInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
550 installCutCopyPasteShortcuts(tableInputMap, true);
554 @SuppressWarnings({"HardCodedStringLiteral"})
555 private void initFontDefaults(UIDefaults defaults) {
556 defaults.put("Tree.ancestorInputMap", null);
557 int uiFontSize = myUiSettings.FONT_SIZE;
558 String uiFontFace = myUiSettings.FONT_FACE;
559 FontUIResource font = new FontUIResource(uiFontFace, Font.PLAIN, uiFontSize);
560 FontUIResource font1 = new FontUIResource("Serif", Font.PLAIN, uiFontSize);
561 FontUIResource font3 = new FontUIResource("Monospaced", Font.PLAIN, uiFontSize);
563 for (String fontResource : ourPatcheableFontResources) {
564 defaults.put(fontResource, font);
567 defaults.put("PasswordField.font", font3);
568 defaults.put("TextArea.font", font3);
569 defaults.put("TextPane.font", font1);
570 defaults.put("EditorPane.font", font1);
571 defaults.put("TitledBorder.font", font);
574 private static final class IdeaLookAndFeelInfo extends UIManager.LookAndFeelInfo{
575 public IdeaLookAndFeelInfo(){
576 super(IdeBundle.message("idea.default.look.and.feel"), IDEA_LAF_CLASSNAME);
579 public boolean equals(Object obj){
580 return (obj instanceof IdeaLookAndFeelInfo);
583 public int hashCode(){
584 return getName().hashCode();
588 private static final class MyComparator implements Comparator{
589 public int compare(Object obj1,Object obj2){
590 String name1=((UIManager.LookAndFeelInfo)obj1).getName();
591 String name2=((UIManager.LookAndFeelInfo)obj2).getName();
592 return name1.compareToIgnoreCase(name2);
596 private static final class IdeaLaf extends MetalLookAndFeel{
597 protected void initComponentDefaults(UIDefaults table) {
598 super.initComponentDefaults(table);
599 initInputMapDefaults(table);
600 initIdeaDefaults(table);
603 protected void initSystemColorDefaults(UIDefaults table) {
604 super.initSystemColorDefaults(table);
606 table.put("control", new ColorUIResource(236, 233, 216));
607 table.put("controlHighlight", new ColorUIResource(255, 255, 255));
608 table.put("controlShadow", new ColorUIResource(172, 167, 153));
612 @SuppressWarnings({"HardCodedStringLiteral"})
613 private static void initIdeaDefaults(UIDefaults defaults) {
614 defaults.put("Menu.maxGutterIconWidth", 18);
615 defaults.put("MenuItem.maxGutterIconWidth", 18);
616 // TODO[vova,anton] REMOVE!!! INVESTIGATE??? Borland???
617 defaults.put("MenuItem.acceleratorDelimiter", "-");
619 defaults.put("TitledBorder.titleColor",IdeaBlueMetalTheme.primary1);
620 ColorUIResource col = new ColorUIResource(230, 230, 230);
621 defaults.put("ScrollBar.background", col);
622 defaults.put("ScrollBar.track", col);
624 // Border scrollPaneBorder = new BorderUIResource(new BegBorders.ScrollPaneBorder());
625 // defaults.put("ScrollPane.border", scrollPaneBorder);
626 defaults.put("TextField.border", BegBorders.getTextFieldBorder());
627 defaults.put("PasswordField.border", BegBorders.getTextFieldBorder());
628 Border popupMenuBorder = new BegPopupMenuBorder();
629 defaults.put("PopupMenu.border", popupMenuBorder);
630 defaults.put("ScrollPane.border", BegBorders.getScrollPaneBorder());
632 defaults.put("ButtonUI", BegButtonUI.class.getName());
633 defaults.put("ComboBoxUI", BegComboBoxUI.class.getName());
634 defaults.put("RadioButtonUI", BegRadioButtonUI.class.getName());
635 defaults.put("CheckBoxUI", BegCheckBoxUI.class.getName());
636 defaults.put("TabbedPaneUI", BegTabbedPaneUI.class.getName());
637 defaults.put("TableUI", BegTableUI.class.getName());
638 defaults.put("TreeUI", BegTreeUI.class.getName());
639 // defaults.put("ScrollPaneUI", BegScrollPaneUI.class.getName());
641 defaults.put("TabbedPane.tabInsets", new Insets(0, 4, 0, 4));
642 defaults.put("ToolTip.background", new ColorUIResource(255, 255, 231));
643 defaults.put("ToolTip.border", new ColoredSideBorder(Color.gray, Color.gray, Color.black, Color.black, 1));
644 defaults.put("Tree.ancestorInputMap", null);
645 defaults.put("FileView.directoryIcon", IconLoader.getIcon("/nodes/folder.png"));
646 defaults.put("FileChooser.upFolderIcon", IconLoader.getIcon("/nodes/upFolder.png"));
647 defaults.put("FileChooser.newFolderIcon", IconLoader.getIcon("/nodes/newFolder.png"));
648 defaults.put("FileChooser.homeFolderIcon", IconLoader.getIcon("/nodes/homeFolder.png"));
649 defaults.put("OptionPane.errorIcon", IconLoader.getIcon("/general/errorDialog.png"));
650 defaults.put("OptionPane.informationIcon", IconLoader.getIcon("/general/informationDialog.png"));
651 defaults.put("OptionPane.warningIcon", IconLoader.getIcon("/general/warningDialog.png"));
652 defaults.put("OptionPane.questionIcon", IconLoader.getIcon("/general/questionDialog.png"));
653 defaults.put("Tree.openIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeOpen.gif"));
654 defaults.put("Tree.closedIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeClosed.gif"));
655 defaults.put("Tree.leafIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeLeaf.gif"));
656 defaults.put("Tree.expandedIcon", com.sun.java.swing.plaf.windows.WindowsTreeUI.ExpandedIcon.createExpandedIcon());
657 defaults.put("Tree.collapsedIcon", com.sun.java.swing.plaf.windows.WindowsTreeUI.CollapsedIcon.createCollapsedIcon());
658 defaults.put("Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
665 "control INSERT", "copy",
666 "shift INSERT", "paste",
667 "shift DELETE", "cut",
668 "RIGHT", "selectNextColumn",
669 "KP_RIGHT", "selectNextColumn",
670 "LEFT", "selectPreviousColumn",
671 "KP_LEFT", "selectPreviousColumn",
672 "DOWN", "selectNextRow",
673 "KP_DOWN", "selectNextRow",
674 "UP", "selectPreviousRow",
675 "KP_UP", "selectPreviousRow",
676 "shift RIGHT", "selectNextColumnExtendSelection",
677 "shift KP_RIGHT", "selectNextColumnExtendSelection",
678 "shift LEFT", "selectPreviousColumnExtendSelection",
679 "shift KP_LEFT", "selectPreviousColumnExtendSelection",
680 "shift DOWN", "selectNextRowExtendSelection",
681 "shift KP_DOWN", "selectNextRowExtendSelection",
682 "shift UP", "selectPreviousRowExtendSelection",
683 "shift KP_UP", "selectPreviousRowExtendSelection",
684 "PAGE_UP", "scrollUpChangeSelection",
685 "PAGE_DOWN", "scrollDownChangeSelection",
686 "HOME", "selectFirstColumn",
687 "END", "selectLastColumn",
688 "shift PAGE_UP", "scrollUpExtendSelection",
689 "shift PAGE_DOWN", "scrollDownExtendSelection",
690 "shift HOME", "selectFirstColumnExtendSelection",
691 "shift END", "selectLastColumnExtendSelection",
692 "ctrl PAGE_UP", "scrollLeftChangeSelection",
693 "ctrl PAGE_DOWN", "scrollRightChangeSelection",
694 "ctrl HOME", "selectFirstRow",
695 "ctrl END", "selectLastRow",
696 "ctrl shift PAGE_UP", "scrollRightExtendSelection",
697 "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
698 "ctrl shift HOME", "selectFirstRowExtendSelection",
699 "ctrl shift END", "selectLastRowExtendSelection",
700 "TAB", "selectNextColumnCell",
701 "shift TAB", "selectPreviousColumnCell",
702 //"ENTER", "selectNextRowCell",
703 "shift ENTER", "selectPreviousRowCell",
704 "ctrl A", "selectAll",
705 //"ESCAPE", "cancel",
711 private static class OurPopupFactory extends PopupFactory {}