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.ui.popup.util.PopupUtil;
25 import com.intellij.openapi.util.Comparing;
26 import com.intellij.openapi.util.IconLoader;
27 import com.intellij.openapi.util.SystemInfo;
28 import com.intellij.ui.ColoredSideBorder;
29 import com.intellij.ui.IdeaBlueMetalTheme;
30 import com.intellij.ui.ScreenUtil;
31 import com.intellij.ui.mac.MacPopupMenuUI;
32 import com.intellij.ui.plaf.beg.*;
33 import com.intellij.util.ui.UIUtil;
34 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
35 import org.jdom.Element;
36 import org.jetbrains.annotations.NonNls;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
41 import javax.swing.border.Border;
42 import javax.swing.event.EventListenerList;
43 import javax.swing.plaf.ColorUIResource;
44 import javax.swing.plaf.FontUIResource;
45 import javax.swing.plaf.metal.DefaultMetalTheme;
46 import javax.swing.plaf.metal.MetalLookAndFeel;
47 import javax.swing.text.DefaultEditorKit;
49 import java.awt.event.KeyEvent;
50 import java.lang.reflect.InvocationTargetException;
51 import java.lang.reflect.Method;
52 import java.util.Arrays;
53 import java.util.Comparator;
54 import java.util.HashMap;
57 * @author Eugene Belyaev
58 * @author Vladimir Kondratyev
62 roamingType = RoamingType.PER_PLATFORM,
65 file = "$APP_CONFIG$/options.xml")})
66 public final class LafManagerImpl extends LafManager implements ApplicationComponent, PersistentStateComponent<Element> {
67 private static final Logger LOG=Logger.getInstance("#com.intellij.ide.ui.LafManager");
69 @NonNls private static final String IDEA_LAF_CLASSNAME = "idea.laf.classname";
72 * One of the possible values of -Didea.popup.weight property. Heavy weight means
73 * that all popups are shown inside the window. Under UNIXes it's possible to configure
74 * window manager "Focus follows mouse with Auto Raise". In this case popup window will
75 * be immediately closed after showing.
77 @NonNls private static final String HEAVY_WEIGHT_POPUP="heavy";
79 * One of the possible values of -Didea.popup.weight property. Medium weight means
80 * that popup will be shouw inside the paren't JLayeredPane if it can be fit to it.
81 * Otherwise popup will be shown in the window. This mode is defaut for the Swing but
82 * it's very slow (much slower then heavy weight popups).
84 @NonNls private static final String MEDIUM_WEIGHT_POPUP="medium";
86 private final EventListenerList myListenerList;
87 private final UIManager.LookAndFeelInfo[] myLafs;
88 private UIManager.LookAndFeelInfo myCurrentLaf;
90 @NonNls private static final String[] ourPatcheableFontResources = new String[]{
91 "Button.font", "ToggleButton.font", "RadioButton.font", "CheckBox.font", "ColorChooser.font", "ComboBox.font",
92 "Label.font", "List.font", "MenuBar.font", "MenuItem.font", "MenuItem.acceleratorFont", "RadioButtonMenuItem.font",
93 "CheckBoxMenuItem.font", "Menu.font", "PopupMenu.font", "OptionPane.font", "Panel.font", "ProgressBar.font",
94 "ScrollPane.font", "Viewport.font", "TabbedPane.font", "Table.font", "TableHeader.font", "TextField.font",
95 "PasswordField.font", "TextArea.font", "TextPane.font", "EditorPane.font", "TitledBorder.font", "ToolBar.font",
96 "ToolTip.font", "Tree.font"
98 @NonNls private static final String[] ourFileChooserTextKeys = new String[] {
99 "FileChooser.viewMenuLabelText", "FileChooser.newFolderActionLabelText", "FileChooser.listViewActionLabelText",
100 "FileChooser.detailsViewActionLabelText", "FileChooser.refreshActionLabelText"
103 private final HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>> myStoredDefaults = new HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>>();
104 private final UISettings myUiSettings;
106 @NonNls private static final String ELEMENT_LAF = "laf";
107 @NonNls private static final String ATTRIBUTE_CLASS_NAME = "class-name";
109 /** invoked by reflection
110 * @param uiSettings */
111 LafManagerImpl(UISettings uiSettings){
112 myUiSettings = uiSettings;
113 myListenerList=new EventListenerList();
115 IdeaLookAndFeelInfo ideaLaf=new IdeaLookAndFeelInfo();
116 UIManager.LookAndFeelInfo[] installedLafs=UIManager.getInstalledLookAndFeels();
118 // Get all installed LAFs
119 myLafs=new UIManager.LookAndFeelInfo[1+installedLafs.length];
121 System.arraycopy(installedLafs,0,myLafs,1,installedLafs.length);
122 Arrays.sort(myLafs,new MyComparator());
124 // Setup current LAF. Unfortunately it's system depended.
125 myCurrentLaf=getDefaultLaf();
129 * Adds specified listener
131 public void addLafManagerListener(@NotNull final LafManagerListener l){
132 myListenerList.add(LafManagerListener.class, l);
136 * Removes specified listener
138 public void removeLafManagerListener(@NotNull final LafManagerListener l){
139 myListenerList.remove(LafManagerListener.class, l);
142 private void fireLookAndFeelChanged(){
143 LafManagerListener[] listeners = myListenerList.getListeners(LafManagerListener.class);
144 for (LafManagerListener listener : listeners) {
145 listener.lookAndFeelChanged(this);
150 public String getComponentName(){
154 public void initComponent() {
155 setCurrentLookAndFeel(findLaf(myCurrentLaf.getClassName())); // setup default LAF or one specfied by readExternal.
159 public void disposeComponent(){}
161 public void loadState(final Element element) {
162 String className=null;
163 for (final Object o : element.getChildren()) {
164 Element child = (Element)o;
165 if (ELEMENT_LAF.equals(child.getName())) {
166 className = child.getAttributeValue(ATTRIBUTE_CLASS_NAME);
171 UIManager.LookAndFeelInfo laf=findLaf(className);
172 // If LAF is undefined (wrong class name or something else) we have set default LAF anyway.
177 if (myCurrentLaf != null && !laf.getClassName().equals(myCurrentLaf.getClassName())) {
178 setCurrentLookAndFeel(laf);
185 public Element getState() {
186 Element element = new Element("state");
187 if(myCurrentLaf.getClassName()!=null){
188 Element child=new Element(ELEMENT_LAF);
189 child.setAttribute(ATTRIBUTE_CLASS_NAME,myCurrentLaf.getClassName());
190 element.addContent(child);
195 public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){
196 return myLafs.clone();
199 public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){
203 public boolean isUnderAquaLookAndFeel() {
204 //noinspection HardCodedStringLiteral
205 return "Mac OS X".equals(getCurrentLookAndFeel().getName());
208 public boolean isUnderQuaquaLookAndFeel() {
209 //noinspection HardCodedStringLiteral
210 return "Quaqua".equals(getCurrentLookAndFeel().getName());
214 * @return default LookAndFeelInfo for the running OS. For Win32 and
215 * Linux the method returns Alloy LAF or IDEA LAF if first not found, for Mac OS X it returns Aqua
217 private UIManager.LookAndFeelInfo getDefaultLaf(){
218 if(SystemInfo.isMac) {
219 UIManager.LookAndFeelInfo laf=findLaf(UIManager.getSystemLookAndFeelClassName());
220 LOG.assertTrue(laf!=null);
224 String defaultLafName = StartupUtil.getDefaultLAF();
225 if (defaultLafName != null) {
226 UIManager.LookAndFeelInfo defaultLaf = findLaf(defaultLafName);
227 if (defaultLaf != null) {
231 return findLaf(IDEA_LAF_CLASSNAME);
236 * Finds LAF by its class name.
239 private UIManager.LookAndFeelInfo findLaf(String className){
240 for (UIManager.LookAndFeelInfo laf : myLafs) {
241 if (Comparing.equal(laf.getClassName(), className)) {
249 * Sets current LAF. The method doesn't update component hierarchy.
251 public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo){
252 if(findLaf(lookAndFeelInfo.getClassName())==null){
253 LOG.error("unknown LookAndFeel : "+lookAndFeelInfo);
259 if(IDEA_LAF_CLASSNAME.equals(lookAndFeelInfo.getClassName())){ // that is IDEA default LAF
260 IdeaLaf laf=new IdeaLaf();
261 IdeaLaf.setCurrentTheme(new IdeaBlueMetalTheme());
263 UIManager.setLookAndFeel(laf);
264 } catch (Exception exc) {
265 Messages.showMessageDialog(
266 IdeBundle.message("error.cannot.set.look.and.feel", lookAndFeelInfo.getName()),
267 CommonBundle.getErrorTitle(),
268 Messages.getErrorIcon()
272 }else{ // non default LAF
274 LookAndFeel laf=((LookAndFeel)Class.forName(lookAndFeelInfo.getClassName()).newInstance());
275 if(laf instanceof MetalLookAndFeel){
276 MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());
278 UIManager.setLookAndFeel(laf);
279 } catch(Exception exc) {
280 Messages.showMessageDialog(
281 IdeBundle.message("error.cannot.set.look.and.feel", lookAndFeelInfo.getName()),
282 CommonBundle.getErrorTitle(),
283 Messages.getErrorIcon()
288 myCurrentLaf=lookAndFeelInfo;
290 // The following code is a trick! By default Swing uses lightweight and "medium" weight
291 // popups to show JPopupMenu. The code below force the creation of real heavyweight menus.
292 // It dramatically increases speed of popups.
294 //noinspection HardCodedStringLiteral
295 String popupWeight=System.getProperty("idea.popup.weight");
296 if(popupWeight==null){ // use defaults if popup weight isn't specified
297 if(SystemInfo.isWindows){
298 popupWeight=HEAVY_WEIGHT_POPUP;
299 }else{ // UNIXes (Linux and MAC) go here
300 popupWeight=MEDIUM_WEIGHT_POPUP;
302 } else if (!HEAVY_WEIGHT_POPUP.equals(popupWeight) && !MEDIUM_WEIGHT_POPUP.equals(popupWeight)) {
303 throw new IllegalStateException("unknown value of property -Didea.popup.weight: " + popupWeight);
306 if (SystemInfo.isMacOSLeopard) {
307 // Force heavy weight popups under Leopard, otherwise they don't have shadow or any kind of border.
308 popupWeight = HEAVY_WEIGHT_POPUP;
311 popupWeight = popupWeight.trim();
313 PopupFactory popupFactory;
314 final PopupFactory oldFactory = PopupFactory.getSharedInstance();
315 if (!(oldFactory instanceof OurPopupFactory)) {
316 popupFactory = new OurPopupFactory() {
317 public Popup getPopup(
322 ) throws IllegalArgumentException {
323 final Point point = fixPopupLocation(contents, x, y);
325 final int popupType = PopupUtil.getPopupType(this);
326 if (popupType >= 0) {
327 PopupUtil.setPopupType(oldFactory, popupType);
330 return oldFactory.getPopup(owner, contents, point.x, point.y);
334 PopupUtil.setPopupType(popupFactory, HEAVY_WEIGHT_POPUP.equals(popupWeight) ? 2 : 1);
335 PopupFactory.setSharedInstance(popupFactory);
338 // update ui for popup menu to get round corners
339 if (UIUtil.isUnderAquaLookAndFeel()) {
340 final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
341 uiDefaults.put("PopupMenuUI", MacPopupMenuUI.class.getCanonicalName());
342 final Icon icon = getAquaMenuInvertedIcon();
344 uiDefaults.put("Menu.invertedArrowIcon", icon);
350 private static Icon getAquaMenuInvertedIcon() {
351 if (!UIUtil.isUnderAquaLookAndFeel()) return null;
352 final Icon arrow = (Icon) UIManager.get("Menu.arrowIcon");
353 if (arrow == null) return null;
356 final Method method = arrow.getClass().getMethod("getInvertedIcon");
357 if (method != null) {
358 method.setAccessible(true);
359 return (Icon) method.invoke(arrow);
364 catch (NoSuchMethodException e1) {
367 catch (InvocationTargetException e1) {
370 catch (IllegalAccessException e1) {
375 private Point fixPopupLocation(final Component contents, final int x, final int y) {
376 if (!(contents instanceof JToolTip)) return new Point(x, y);
378 final PointerInfo info;
380 info = MouseInfo.getPointerInfo();
382 catch (InternalError e) {
383 // http://www.jetbrains.net/jira/browse/IDEADEV-21390
384 // may happen under Mac OSX 10.5
385 return new Point(x, y);
390 final Point mouse = info.getLocation();
391 deltaY = mouse.y - y;
394 final Dimension size = contents.getPreferredSize();
395 final Rectangle rec = new Rectangle(new Point(x, y), size);
396 ScreenUtil.moveRectangleToFitTheScreen(rec);
402 return rec.getLocation();
407 * Updates LAF of all windows. The method also updates font of components
408 * as it's configured in <code>UISettings</code>.
410 public void updateUI(){
411 UIDefaults lookAndFeelDefaults=UIManager.getLookAndFeelDefaults();
412 initInputMapDefaults(lookAndFeelDefaults);
413 patchFileChooserStrings(lookAndFeelDefaults);
414 if (shouldPatchLAFFonts()) {
415 storeOriginalFontDefaults(lookAndFeelDefaults);
416 initFontDefaults(lookAndFeelDefaults);
419 restoreOriginalFontDefaults(lookAndFeelDefaults);
422 Frame[] frames=Frame.getFrames();
423 for (Frame frame : frames) {
426 fireLookAndFeelChanged();
429 private void patchFileChooserStrings(final UIDefaults defaults) {
430 if (!defaults.containsKey(ourFileChooserTextKeys [0])) {
431 // Alloy L&F does not define strings for names of context menu actions, so we have to patch them in here
432 for (String key : ourFileChooserTextKeys) {
433 defaults.put(key, IdeBundle.message(key));
438 private void restoreOriginalFontDefaults(UIDefaults defaults) {
439 UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel();
440 HashMap<String, Object> lfDefaults = myStoredDefaults.get(lf);
441 if (lfDefaults != null) {
442 for (String resource : ourPatcheableFontResources) {
443 defaults.put(resource, lfDefaults.get(resource));
448 private void storeOriginalFontDefaults(UIDefaults defaults) {
449 UIManager.LookAndFeelInfo lf = getCurrentLookAndFeel();
450 HashMap<String, Object> lfDefaults = myStoredDefaults.get(lf);
451 if (lfDefaults == null) {
452 lfDefaults = new HashMap<String, Object>();
453 for (String resource : ourPatcheableFontResources) {
454 lfDefaults.put(resource, defaults.get(resource));
456 myStoredDefaults.put(lf, lfDefaults);
460 private boolean shouldPatchLAFFonts() {
461 //noinspection HardCodedStringLiteral
462 return getCurrentLookAndFeel().getName().startsWith("IDEA") || UISettings.getInstance().OVERRIDE_NONIDEA_LAF_FONTS;
465 private static void updateUI(Window window){
466 if(!window.isDisplayable()){
469 SwingUtilities.updateComponentTreeUI(window);
470 Window[] children=window.getOwnedWindows();
471 for (Window aChildren : children) {
477 * Repaints all displayable window.
479 public void repaintUI(){
480 Frame[] frames=Frame.getFrames();
481 for (Frame frame : frames) {
486 private static void repaintUI(Window window){
487 if(!window.isDisplayable()){
491 Window[] children=window.getOwnedWindows();
492 for (Window aChildren : children) {
493 repaintUI(aChildren);
497 private static void installCutCopyPasteShortcuts(InputMap inputMap, boolean useSimpleActionKeys){
498 String copyActionKey = useSimpleActionKeys ? "copy" : DefaultEditorKit.copyAction;
499 String pasteActionKey = useSimpleActionKeys ? "paste" : DefaultEditorKit.pasteAction;
500 String cutActionKey = useSimpleActionKeys ? "cut" : DefaultEditorKit.cutAction;
501 // Ctrl+Ins, Shift+Ins, Shift+Del
502 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),copyActionKey);
503 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,KeyEvent.SHIFT_MASK|KeyEvent.SHIFT_DOWN_MASK),pasteActionKey);
504 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,KeyEvent.SHIFT_MASK|KeyEvent.SHIFT_DOWN_MASK),cutActionKey);
505 // Ctrl+C, Ctrl+V, Ctrl+X
506 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),copyActionKey);
507 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),pasteActionKey);
508 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X,KeyEvent.CTRL_MASK|KeyEvent.CTRL_DOWN_MASK),DefaultEditorKit.cutAction);
511 @SuppressWarnings({"HardCodedStringLiteral"})
512 private static void initInputMapDefaults(UIDefaults defaults){
513 // Make ENTER work in JTrees
514 InputMap treeInputMap = (InputMap)defaults.get("Tree.focusInputMap");
515 if(treeInputMap!=null){ // it's really possible. For examle, GTK+ doesn't have such map
516 treeInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"toggle");
518 // Cut/Copy/Paste in JTextAreas
519 InputMap textAreaInputMap=(InputMap)defaults.get("TextArea.focusInputMap");
520 if(textAreaInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
521 installCutCopyPasteShortcuts(textAreaInputMap, false);
523 // Cut/Copy/Paste in JTextFields
524 InputMap textFieldInputMap=(InputMap)defaults.get("TextField.focusInputMap");
525 if(textFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
526 installCutCopyPasteShortcuts(textFieldInputMap, false);
528 // Cut/Copy/Paste in JPAsswordField
529 InputMap passwordFieldInputMap=(InputMap)defaults.get("PasswordField.focusInputMap");
530 if(passwordFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
531 installCutCopyPasteShortcuts(passwordFieldInputMap, false);
533 // Cut/Copy/Paste in JTables
534 InputMap tableInputMap=(InputMap)defaults.get("Table.ancestorInputMap");
535 if(tableInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
536 installCutCopyPasteShortcuts(tableInputMap, true);
540 @SuppressWarnings({"HardCodedStringLiteral"})
541 private void initFontDefaults(UIDefaults defaults) {
542 defaults.put("Tree.ancestorInputMap", null);
543 int uiFontSize = myUiSettings.FONT_SIZE;
544 String uiFontFace = myUiSettings.FONT_FACE;
545 FontUIResource font = new FontUIResource(uiFontFace, Font.PLAIN, uiFontSize);
546 FontUIResource font1 = new FontUIResource("Serif", Font.PLAIN, uiFontSize);
547 FontUIResource font3 = new FontUIResource("Monospaced", Font.PLAIN, uiFontSize);
549 for (String fontResource : ourPatcheableFontResources) {
550 defaults.put(fontResource, font);
553 defaults.put("PasswordField.font", font3);
554 defaults.put("TextArea.font", font3);
555 defaults.put("TextPane.font", font1);
556 defaults.put("EditorPane.font", font1);
557 defaults.put("TitledBorder.font", font);
560 private static final class IdeaLookAndFeelInfo extends UIManager.LookAndFeelInfo{
561 public IdeaLookAndFeelInfo(){
562 super(IdeBundle.message("idea.default.look.and.feel"), IDEA_LAF_CLASSNAME);
565 public boolean equals(Object obj){
566 return (obj instanceof IdeaLookAndFeelInfo);
569 public int hashCode(){
570 return getName().hashCode();
574 private static final class MyComparator implements Comparator{
575 public int compare(Object obj1,Object obj2){
576 String name1=((UIManager.LookAndFeelInfo)obj1).getName();
577 String name2=((UIManager.LookAndFeelInfo)obj2).getName();
578 return name1.compareToIgnoreCase(name2);
582 private static final class IdeaLaf extends MetalLookAndFeel{
583 protected void initComponentDefaults(UIDefaults table) {
584 super.initComponentDefaults(table);
585 initInputMapDefaults(table);
586 initIdeaDefaults(table);
589 protected void initSystemColorDefaults(UIDefaults table) {
590 super.initSystemColorDefaults(table);
592 table.put("control", new ColorUIResource(236, 233, 216));
593 table.put("controlHighlight", new ColorUIResource(255, 255, 255));
594 table.put("controlShadow", new ColorUIResource(172, 167, 153));
598 @SuppressWarnings({"HardCodedStringLiteral"})
599 private static void initIdeaDefaults(UIDefaults defaults) {
600 defaults.put("Menu.maxGutterIconWidth", 18);
601 defaults.put("MenuItem.maxGutterIconWidth", 18);
602 // TODO[vova,anton] REMOVE!!! INVESTIGATE??? Borland???
603 defaults.put("MenuItem.acceleratorDelimiter", "-");
605 defaults.put("TitledBorder.titleColor",IdeaBlueMetalTheme.primary1);
606 ColorUIResource col = new ColorUIResource(230, 230, 230);
607 defaults.put("ScrollBar.background", col);
608 defaults.put("ScrollBar.track", col);
610 // Border scrollPaneBorder = new BorderUIResource(new BegBorders.ScrollPaneBorder());
611 // defaults.put("ScrollPane.border", scrollPaneBorder);
612 defaults.put("TextField.border", BegBorders.getTextFieldBorder());
613 defaults.put("PasswordField.border", BegBorders.getTextFieldBorder());
614 Border popupMenuBorder = new BegPopupMenuBorder();
615 defaults.put("PopupMenu.border", popupMenuBorder);
616 defaults.put("ScrollPane.border", BegBorders.getScrollPaneBorder());
618 defaults.put("ButtonUI", BegButtonUI.class.getName());
619 defaults.put("ComboBoxUI", BegComboBoxUI.class.getName());
620 defaults.put("RadioButtonUI", BegRadioButtonUI.class.getName());
621 defaults.put("CheckBoxUI", BegCheckBoxUI.class.getName());
622 defaults.put("TabbedPaneUI", BegTabbedPaneUI.class.getName());
623 defaults.put("TableUI", BegTableUI.class.getName());
624 defaults.put("TreeUI", BegTreeUI.class.getName());
625 // defaults.put("ScrollPaneUI", BegScrollPaneUI.class.getName());
627 defaults.put("TabbedPane.tabInsets", new Insets(0, 4, 0, 4));
628 defaults.put("ToolTip.background", new ColorUIResource(255, 255, 231));
629 defaults.put("ToolTip.border", new ColoredSideBorder(Color.gray, Color.gray, Color.black, Color.black, 1));
630 defaults.put("Tree.ancestorInputMap", null);
631 defaults.put("FileView.directoryIcon", IconLoader.getIcon("/nodes/folder.png"));
632 defaults.put("FileChooser.upFolderIcon", IconLoader.getIcon("/nodes/upFolder.png"));
633 defaults.put("FileChooser.newFolderIcon", IconLoader.getIcon("/nodes/newFolder.png"));
634 defaults.put("FileChooser.homeFolderIcon", IconLoader.getIcon("/nodes/homeFolder.png"));
635 defaults.put("OptionPane.errorIcon", IconLoader.getIcon("/general/errorDialog.png"));
636 defaults.put("OptionPane.informationIcon", IconLoader.getIcon("/general/informationDialog.png"));
637 defaults.put("OptionPane.warningIcon", IconLoader.getIcon("/general/warningDialog.png"));
638 defaults.put("OptionPane.questionIcon", IconLoader.getIcon("/general/questionDialog.png"));
639 defaults.put("Tree.openIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeOpen.gif"));
640 defaults.put("Tree.closedIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeClosed.gif"));
641 defaults.put("Tree.leafIcon", LookAndFeel.makeIcon(WindowsLookAndFeel.class, "icons/TreeLeaf.gif"));
642 defaults.put("Tree.expandedIcon", com.sun.java.swing.plaf.windows.WindowsTreeUI.ExpandedIcon.createExpandedIcon());
643 defaults.put("Tree.collapsedIcon", com.sun.java.swing.plaf.windows.WindowsTreeUI.CollapsedIcon.createCollapsedIcon());
644 defaults.put("Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
651 "control INSERT", "copy",
652 "shift INSERT", "paste",
653 "shift DELETE", "cut",
654 "RIGHT", "selectNextColumn",
655 "KP_RIGHT", "selectNextColumn",
656 "LEFT", "selectPreviousColumn",
657 "KP_LEFT", "selectPreviousColumn",
658 "DOWN", "selectNextRow",
659 "KP_DOWN", "selectNextRow",
660 "UP", "selectPreviousRow",
661 "KP_UP", "selectPreviousRow",
662 "shift RIGHT", "selectNextColumnExtendSelection",
663 "shift KP_RIGHT", "selectNextColumnExtendSelection",
664 "shift LEFT", "selectPreviousColumnExtendSelection",
665 "shift KP_LEFT", "selectPreviousColumnExtendSelection",
666 "shift DOWN", "selectNextRowExtendSelection",
667 "shift KP_DOWN", "selectNextRowExtendSelection",
668 "shift UP", "selectPreviousRowExtendSelection",
669 "shift KP_UP", "selectPreviousRowExtendSelection",
670 "PAGE_UP", "scrollUpChangeSelection",
671 "PAGE_DOWN", "scrollDownChangeSelection",
672 "HOME", "selectFirstColumn",
673 "END", "selectLastColumn",
674 "shift PAGE_UP", "scrollUpExtendSelection",
675 "shift PAGE_DOWN", "scrollDownExtendSelection",
676 "shift HOME", "selectFirstColumnExtendSelection",
677 "shift END", "selectLastColumnExtendSelection",
678 "ctrl PAGE_UP", "scrollLeftChangeSelection",
679 "ctrl PAGE_DOWN", "scrollRightChangeSelection",
680 "ctrl HOME", "selectFirstRow",
681 "ctrl END", "selectLastRow",
682 "ctrl shift PAGE_UP", "scrollRightExtendSelection",
683 "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
684 "ctrl shift HOME", "selectFirstRowExtendSelection",
685 "ctrl shift END", "selectLastRowExtendSelection",
686 "TAB", "selectNextColumnCell",
687 "shift TAB", "selectPreviousColumnCell",
688 //"ENTER", "selectNextRowCell",
689 "shift ENTER", "selectPreviousRowCell",
690 "ctrl A", "selectAll",
691 //"ESCAPE", "cancel",
697 private static class OurPopupFactory extends PopupFactory {}