IDEA-61847 (warn user on problematic L&F)
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Sat, 27 Nov 2010 13:38:52 +0000 (16:38 +0300)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Sat, 27 Nov 2010 13:40:06 +0000 (16:40 +0300)
platform/platform-api/src/com/intellij/ide/ui/LafManager.java
platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java
platform/platform-impl/src/com/intellij/ide/ui/HeadlessLafManagerImpl.java
platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java
platform/platform-resources-en/src/messages/IdeBundle.properties

index 638e783a4f8ccdacec5cf0bc58a419113ff6f509..db9be2bb4d0ce3cefb71150f1f44d757f43d720c 100644 (file)
@@ -43,6 +43,8 @@ public abstract class LafManager {
    */
   public abstract boolean isUnderQuaquaLookAndFeel();
 
+  public abstract boolean checkLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo);
+
   public abstract void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo);
 
   public abstract void updateUI();
index f3334c7b8c8ff30cf37b4db6d694e8cc313f04e4..196f69314acb7ad4cce637fe99df9237525f30ba 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.wm.ex.WindowManagerEx;
 import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -47,13 +48,12 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
 
   public JComponent createComponent() {
     myComponent = new MyComponent();
+
     DefaultComboBoxModel aModel = new DefaultComboBoxModel(UIUtil.getValidFontNames(false));
     myComponent.myFontCombo.setModel(aModel);
-
     myComponent.myFontSizeCombo.setModel(new DefaultComboBoxModel(UIUtil.getStandardFontSizes()));
-
     myComponent.myFontSizeCombo.setEditable(true);
-//    myComponent.myLafComboBox=new JComboBox(LafManager.getInstance().getInstalledLookAndFeels());
+
     myComponent.myLafComboBox.setModel(new DefaultComboBoxModel(LafManager.getInstance().getInstalledLookAndFeels()));
     myComponent.myLafComboBox.setRenderer(new MyLafComboBoxRenderer(myComponent.myLafComboBox.getRenderer()));
 
@@ -70,6 +70,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
     });
 
     myComponent.myAlphaModeRatioSlider.setSize(100, 50);
+    @SuppressWarnings({"UseOfObsoleteCollectionType"})
     Dictionary<Integer, JLabel> dictionary = new Hashtable<Integer, JLabel>();
     dictionary.put(new Integer(0), new JLabel("0%"));
     dictionary.put(new Integer(50), new JLabel("50%"));
@@ -89,7 +90,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
 
     myComponent.myTransparencyPanel.setVisible(WindowManagerEx.getInstanceEx().isAlphaModeSupported());
 
-
     return myComponent.myPanel;
   }
 
@@ -105,7 +105,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
       try {
         _fontSize = Integer.parseInt(temp);
       }
-      catch (NumberFormatException ex) {
+      catch (NumberFormatException ignore) {
       }
       if (_fontSize <= 0) {
         _fontSize = settings.FONT_SIZE;
@@ -137,8 +137,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
       shouldUpdateUI = true;
     }
     settings.OVERRIDE_NONIDEA_LAF_FONTS = myComponent.myOverrideLAFFonts.isSelected();
-
-
     settings.MOVE_MOUSE_ON_DEFAULT_BUTTON = myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected();
 
     update |= settings.DISABLE_MNEMONICS != myComponent.myDisableMnemonics.isSelected();
@@ -148,8 +146,11 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
     settings.SHOW_ICONS_IN_QUICK_NAVIGATION = myComponent.myHideIconsInQuickNavigation.isSelected();
 
     if (!Comparing.equal(myComponent.myLafComboBox.getSelectedItem(), lafManager.getCurrentLookAndFeel())) {
-      update = shouldUpdateUI = true;
-      lafManager.setCurrentLookAndFeel((UIManager.LookAndFeelInfo)myComponent.myLafComboBox.getSelectedItem());
+      UIManager.LookAndFeelInfo lafInfo = (UIManager.LookAndFeelInfo)myComponent.myLafComboBox.getSelectedItem();
+      if (lafManager.checkLookAndFeel(lafInfo)) {
+        update = shouldUpdateUI = true;
+        lafManager.setCurrentLookAndFeel(lafInfo);
+      }
     }
 
     if (myComponent.myTooltipMode.getSelectedItem() != null && !myComponent.myTooltipMode.getSelectedItem().equals(Registry.stringValue("ide.tooltip.mode"))) {
@@ -261,22 +262,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
     return isModified;
   }
 
-  private static boolean isModified(JTextField textField, int value) {
-    try {
-      int fieldValue = Integer.parseInt(textField.getText().trim());
-      return fieldValue != value;
-    }
-    catch (NumberFormatException e) {
-      return false;
-    }
-  }
-
-  private static boolean isModified(JToggleButton checkBox, boolean value) {
-    return checkBox.isSelected() != value;
-  }
-
   public void disposeUIResources() {
-//    if (myComponent == null)
     myComponent = null;
   }
 
@@ -306,7 +292,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
 
     @Override
     public void customize(final JList list, final String value, final int index, final boolean selected, final boolean cellHasFocus) {
-      String s = (String)value;
+      String s = value;
       if (s != null && s.length() > 1) {
         s = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
       }
@@ -315,7 +301,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
   }
 
   private static class MyComponent {
-    JPanel myPanel;
+    private JPanel myPanel;
     private JComboBox myFontCombo;
     private JComboBox myFontSizeCombo;
     private JCheckBox myAnimateWindowsCheckBox;
@@ -335,13 +321,11 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
     private JCheckBox myOverrideLAFFonts;
     private JLabel myIDEALafFont;
 
-
     private JCheckBox myHideIconsInQuickNavigation;
     private JCheckBox myCbDisplayIconsInMenu;
     private JCheckBox myDisableMnemonics;
     private JComboBox myTooltipMode;
 
-
     public MyComponent() {
       ActionListener updater = new ActionListener() {
         public void actionPerformed(ActionEvent e) {
@@ -370,7 +354,9 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
     }
   }
 
+  @NotNull
   public String getId() {
+    //noinspection ConstantConditions
     return getHelpTopic();
   }
 
index d47adc806bc6b559ac816a27cdb4355084635eed..991961d4b57cfa3255e4f7c5a34bb7f83726bbe4 100644 (file)
@@ -43,6 +43,10 @@ public class HeadlessLafManagerImpl extends LafManager implements ApplicationCom
     return false;
   }
 
+  public boolean checkLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
+    return true;
+  }
+
   public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
   }
 
index 53318d0f3efb478228ae4171361c6512771c8bea..0e2daf65af47cafb0faa2eee015a912771855125 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.ide.ui;
 import com.intellij.CommonBundle;
 import com.intellij.ide.IdeBundle;
 import com.intellij.idea.StartupUtil;
+import com.intellij.notification.*;
 import com.intellij.openapi.application.ApplicationNamesInfo;
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.diagnostic.Logger;
@@ -114,6 +115,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
   @NonNls private static final String ELEMENT_LAF = "laf";
   @NonNls private static final String ATTRIBUTE_CLASS_NAME = "class-name";
 
+  private String myLastWarning = null;
+
   /**
    * invoked by reflection
    *
@@ -169,7 +172,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
   }
 
   public void initComponent() {
-    setCurrentLookAndFeel(findLaf(myCurrentLaf.getClassName())); // setup default LAF or one specfied by readExternal.
+    setCurrentLookAndFeel(findLaf(myCurrentLaf.getClassName())); // setup default LAF or one specified by readExternal.
     updateUI();
   }
 
@@ -227,18 +230,18 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
 
   /**
    * @return default LookAndFeelInfo for the running OS. For Win32 and
-   * Linux the method returns Alloy LAF or IDEA LAF if first not found, for Mac OS X it returns Aqua
-   * RubyMine uses Native L&F for linux as well
+   *         Linux the method returns Alloy LAF or IDEA LAF if first not found, for Mac OS X it returns Aqua
+   *         RubyMine uses Native L&F for linux as well
    */
-  private UIManager.LookAndFeelInfo getDefaultLaf(){
-    if(SystemInfo.isMac) {
-      UIManager.LookAndFeelInfo laf=findLaf(UIManager.getSystemLookAndFeelClassName());
-      LOG.assertTrue(laf!=null);
+  private UIManager.LookAndFeelInfo getDefaultLaf() {
+    if (SystemInfo.isMac) {
+      UIManager.LookAndFeelInfo laf = findLaf(UIManager.getSystemLookAndFeelClassName());
+      LOG.assertTrue(laf != null);
       return laf;
     }
     else if (SystemInfo.isLinux && ApplicationNamesInfo.getInstance().getLowercaseProductName().equals("Rubymine")) {
-      UIManager.LookAndFeelInfo laf=findLaf(UIManager.getSystemLookAndFeelClassName());
-      LOG.assertTrue(laf!=null);
+      UIManager.LookAndFeelInfo laf = findLaf(UIManager.getSystemLookAndFeelClassName());
+      LOG.assertTrue(laf != null);
       return laf;
     }
     else {
@@ -249,14 +252,19 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
           return defaultLaf;
         }
       }
-      return findLaf(IDEA_LAF_CLASSNAME);
+      UIManager.LookAndFeelInfo ideaLaf = findLaf(IDEA_LAF_CLASSNAME);
+      if (ideaLaf != null) {
+        return ideaLaf;
+      }
     }
+    throw new IllegalStateException("No default look&feel found");
   }
 
   /**
    * Finds LAF by its class name.
    * will be returned.
    */
+  @Nullable
   private UIManager.LookAndFeelInfo findLaf(String className){
     for (UIManager.LookAndFeelInfo laf : myLafs) {
       if (Comparing.equal(laf.getClassName(), className)) {
@@ -308,6 +316,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
     }
     myCurrentLaf=lookAndFeelInfo;
 
+    checkLookAndFeel(lookAndFeelInfo, false);
+
     // The following code is a trick! By default Swing uses lightweight and "medium" weight
     // popups to show JPopupMenu. The code below force the creation of real heavyweight menus.
     // It dramatically increases speed of popups.
@@ -431,6 +441,39 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
     return rec.getLocation();
   }
 
+  @Override
+  public boolean checkLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) {
+    return checkLookAndFeel(lookAndFeelInfo, true);
+  }
+
+  private boolean checkLookAndFeel(final UIManager.LookAndFeelInfo lafInfo, final boolean confirm) {
+    String message = null;
+
+    if (lafInfo.getName().contains("GTK") && SystemInfo.isLinux && !SystemInfo.isJavaVersionAtLeast("1.6.0_12")) {
+      message = IdeBundle.message("warning.problem.laf.1");
+    }
+
+    if (message != null) {
+      if (confirm) {
+        final String[] options = {IdeBundle.message("confirm.set.look.and.feel"), CommonBundle.getCancelButtonText()};
+        final int result = Messages.showDialog(message, CommonBundle.getWarningTitle(), options, 1, Messages.getWarningIcon());
+        if (result == 0) {
+          myLastWarning = message;
+          return true;
+        }
+        return false;
+      }
+
+      if (!message.equals(myLastWarning)) {
+        Notifications.Bus.notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "L&F Manager", message, NotificationType.WARNING,
+                                                  NotificationListener.URL_OPENING_LISTENER));
+        myLastWarning = message;
+      }
+    }
+
+    return true;
+  }
+
   /**
    * Updates LAF of all windows. The method also updates font of components
    * as it's configured in <code>UISettings</code>.
index 94f6c57750c25cc053d15241a2ae62fe3d7fdd66..6bc3bbcc9a09c26413be968673ff8e25b95c0323 100644 (file)
@@ -639,11 +639,13 @@ label.font.size=Size:
 combobox.look.and.feel=&Look and feel:
 checkboox.cyclic.scrolling.in.lists=Cyclic scrolling in list
 checkbox.position.cursor.on.default.button=<html>Automatically position mouse cursor<br> on default button</html>
-checkbox.use.antialiased.font.in.editor=Use antialiased font
+checkbox.use.antialiased.font.in.editor=Use anti-aliased font
 
 # this string must start with "IDEA"
 idea.default.look.and.feel=IDEA (4.5 default)
+confirm.set.look.and.feel=&Set look and feel
 error.cannot.set.look.and.feel=Cannot set {0} look and feel
+warning.problem.laf.1=<html><body>GTK+ look and feel is known to be problematic on a JDK prior to 1.6 b12.<br>Please choose another look and feel, or upgrade your JDK. <a href="http://bugs.sun.com/view_bug.do?bug_id=6624717">More info...</a></body></html>
 error.adding.action.without.icon.to.toolbar=You are adding an action without icon to the toolbar. The default icon will be added to this action.
 title.unable.to.add.action.without.icon.to.toolbar=Unable to add action without icon to the toolbar
 error.please.specify.new.name.for.schema=Please, specify new name for scheme ''{0}''.