[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[albireo-dev] Re: AwtEnvironment & customizability
|
Hi Gordon,
I wrote:
> I'll therefore try to move out to a separate class LookAndFeelHandler all
> the policy, i.e. all the calls that should be customizable and deal with
> look&feel.
Done now, through the appended patch.
One thing I'm not comfortable with is that the default L&F choice is
LAFChoiceNativeSystemForceGtk, which is exactly the same as you did.
The reason is that on the Linux system I happen to be using (openSUSE with KDE
desktop), the Gtk look&feel of Swing is not well supported: At the beginning
I get an error message in the console:
/opt/gnome/share/themes/Qt/gtk-2.0/gtkrc:5: Engine "qtengine" is unsupported, ignoring
and the resulting look is
- very ugly,
- different from the look of the Eclipse/JFace GUI.
(See attached screenshots.)
On RedHat Linux machines with GNOME desktop the JDK is configured to launch
in Gtk look&feel by default, and I haven't heard complaints that it looks
bad. So in this case I have no objection against using Gtk look&feel by
default.
But when the JDK does not open it up by default, I'd prefer to respect that
choice. You wrote in comments:
// Java makes metal the system look and feel if running under a
// non-gnome Linux desktop. Fix that here, if the RCP itself is
// running
// with the GTK windowing system set.
but in some cases it is not a fix - it makes things worse.
So I'm for changing the default from
LAFChoiceNativeSystemForceGtk
to
LAFChoiceNativeSystem.
In view of the bug that you found and reported
https://bugs.eclipse.org/bugs/show_bug.cgi?id=126931
I think we must even make it
LAFChoiceNativeSystemAvoidGtk
when running under JDK 1.6.
I just retested this bug, by running our sample application under JDK 1.6.
First try: the application showed a window that terminated immediately.
Second try: the application showed its window,
the AWT part was empty instead of showing a JTable,
a message "Xlib: unexpected async reply (sequence 0x6b2)!"
appeared in the console,
and my entire display was blocked (moving the mouse worked,
but clicking anywhere did not show any reaction - the worst
thing that can happen to a user under X).
Bruno
Index: src/org/eclipse/albireo/core/AwtEnvironment.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/AwtEnvironment.java,v
retrieving revision 1.2
diff -c -3 -r1.2 AwtEnvironment.java
*** src/org/eclipse/albireo/core/AwtEnvironment.java 23 Jan 2008 20:49:32 -0000 1.2
--- src/org/eclipse/albireo/core/AwtEnvironment.java 25 Jan 2008 15:36:24 -0000
***************
*** 17,26 ****
import java.util.HashMap;
import java.util.Map;
- import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
- import org.eclipse.albireo.internal.Platform;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
--- 17,24 ----
***************
*** 48,54 ****
* {@link #getInstance(Display)} method.
*/
public final class AwtEnvironment {
- private static final String GTK_LOOK_AND_FEEL_NAME = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"; //$NON-NLS-1$
// Map from Display to AwtEnvironment.
// This does not need to be a WeakHashMap: Display instances don't go away
--- 46,51 ----
***************
*** 127,161 ****
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
! setSystemLookAndFeel();
}
});
} catch (InterruptedException e) {
SWT.error(SWT.ERROR_FAILED_EXEC, e);
} catch (InvocationTargetException e) {
! SWT.error(SWT.ERROR_FAILED_EXEC, e);
}
this.display = display;
}
! protected void setSystemLookAndFeel() {
assert EventQueue.isDispatchThread(); // On AWT event thread
if (!isLookAndFeelInitialized) {
isLookAndFeelInitialized = true;
try {
! String systemLaf = UIManager.getSystemLookAndFeelClassName();
! String xplatLaf = UIManager.getCrossPlatformLookAndFeelClassName();
!
! // Java makes metal the system look and feel if running under a
! // non-gnome Linux desktop. Fix that here, if the RCP itself is
! // running
! // with the GTK windowing system set.
! if (xplatLaf.equals(systemLaf) && Platform.isGtk()) {
! systemLaf = GTK_LOOK_AND_FEEL_NAME;
! }
! UIManager.setLookAndFeel(systemLaf);
} catch (ClassNotFoundException e) {
SWT.error(SWT.ERROR_NOT_IMPLEMENTED, e);
} catch (InstantiationException e) {
--- 124,148 ----
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
! setLookAndFeel();
}
});
} catch (InterruptedException e) {
SWT.error(SWT.ERROR_FAILED_EXEC, e);
} catch (InvocationTargetException e) {
! SWT.error(SWT.ERROR_FAILED_EXEC, e.getTargetException());
}
this.display = display;
}
! static private void setLookAndFeel() {
assert EventQueue.isDispatchThread(); // On AWT event thread
if (!isLookAndFeelInitialized) {
isLookAndFeelInitialized = true;
try {
! LookAndFeelHandler.getInstance().setLookAndFeel();
} catch (ClassNotFoundException e) {
SWT.error(SWT.ERROR_NOT_IMPLEMENTED, e);
} catch (InstantiationException e) {
*** /dev/null 2006-05-02 08:46:16.000000000 +0200
--- src/org/eclipse/albireo/core/LookAndFeelHandler.java 2008-01-25 16:38:07.000000000 +0100
***************
*** 0 ****
--- 1,160 ----
+ /*******************************************************************************
+ * Copyright (c) 2007-2008 SAS Institute Inc., ILOG S.A.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * SAS Institute Inc. - initial API and implementation
+ * ILOG S.A. - initial API and implementation
+ *******************************************************************************/
+ package org.eclipse.albireo.core;
+
+ import java.awt.EventQueue;
+
+ import javax.swing.UIManager;
+ import javax.swing.UnsupportedLookAndFeelException;
+
+ import org.eclipse.albireo.internal.Platform;
+
+ /**
+ * This class deals with the customization of the look&feel
+ * of Swing components embedded inside SWT.
+ * <p>
+ * It is customizable through the "replaceable singleton" design pattern.
+ */
+ public class LookAndFeelHandler {
+
+ // ========================================================================
+ // Accessors
+
+ /**
+ * This look&feel choice denotes the default Swing look&feel.
+ * It may be platform dependent.
+ */
+ public static final String LAFChoiceSwingDefault = "swing.defaultlaf";
+
+ /**
+ * This look&feel choice denotes the cross-platform Swing
+ * look&feel.
+ * It is not platform dependent.
+ * @see javax.swing.UIManager#getCrossPlatformLookAndFeelClassName()
+ */
+ public static final String LAFChoiceCrossPlatform = "swing.crossplatformlaf";
+
+ /**
+ * This look&feel choice denotes the Swing look&feel
+ * that best approximates the system look&feel.
+ * It is platform dependent.
+ * @see javax.swing.UIManager#getSystemLookAndFeelClassName()
+ */
+ public static final String LAFChoiceNativeSystem = "swing.systemlaf";
+
+ /**
+ * This look&feel choice denotes the Swing look&feel
+ * that best approximates the system look&feel, except that
+ * the Gtk look&feel is used instead of the cross-platform
+ * look&feel if SWT is based on Gtk.
+ * (This typically affects Linux systems with KDE desktop.)
+ * It is platform dependent.
+ */
+ public static final String LAFChoiceNativeSystemForceGtk = "swing.systemlaf+gtk";
+
+ /**
+ * This look&feel choice denotes the Swing look&feel
+ * that best approximates the system look&feel, except that
+ * the Gtk look&feel is avoided.
+ * (This typically affects Linux systems with Gtk desktop.)
+ * It is platform dependent.
+ */
+ public static final String LAFChoiceNativeSystemNoGtk = "swing.systemlaf-gtk";
+
+ private String lafChoice = LAFChoiceNativeSystemForceGtk;
+
+ /**
+ * Returns the look&feel choice. It can be a class name or one
+ * the shorthands defined in this class.
+ */
+ public String getLAFChoice() {
+ return lafChoice;
+ }
+
+ /**
+ * Specifies which look&feel should be used.
+ * @param choice Either a class name, such as
+ * <code>"javax.swing.plaf.metal.MetalLookAndFeel"</code>,
+ * <code>"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"</code>,
+ * <code>"com.sun.java.swing.plaf.gtk.GTKLookAndFeel"</code>,
+ * <code>"com.sun.java.swing.plaf.motif.MotifLookAndFeel"</code>,
+ * <code>"apple.laf.AquaLookAndFeel"</code>,
+ * or one of the shorthands
+ * {@link #LAFChoiceSwingDefault},
+ * {@link #LAFChoiceCrossPlatform},
+ * {@link #LAFChoiceNativeSystem},
+ * {@link #LAFChoiceNativeSystemForceGtk},
+ * {@link #LAFChoiceNativeSystemNoGtk}.
+ */
+ public void setLAFChoice(String choice) {
+ lafChoice = choice;
+ }
+
+ // ========================================================================
+ // Overridable API
+
+ private static final String GTK_LOOK_AND_FEEL_NAME = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"; //$NON-NLS-1$
+
+ /**
+ * Sets the desired look&feel.
+ * @see #setLAFChoice(String)
+ */
+ public void setLookAndFeel()
+ throws ClassNotFoundException,
+ InstantiationException,
+ IllegalAccessException,
+ UnsupportedLookAndFeelException {
+ assert EventQueue.isDispatchThread(); // On AWT event thread
+
+ String laf = getLAFChoice();
+ if (LAFChoiceSwingDefault.equals(laf)) {
+ return;
+ } else if (LAFChoiceCrossPlatform.equals(laf)) {
+ laf = UIManager.getCrossPlatformLookAndFeelClassName();
+ } else if (LAFChoiceNativeSystem.equals(laf)) {
+ laf = UIManager.getSystemLookAndFeelClassName();
+ } else if (LAFChoiceNativeSystemForceGtk.equals(laf)) {
+ laf = UIManager.getSystemLookAndFeelClassName();
+ if (Platform.isGtk()
+ && laf.equals(UIManager.getCrossPlatformLookAndFeelClassName())) {
+ laf = GTK_LOOK_AND_FEEL_NAME;
+ }
+ } else if (LAFChoiceNativeSystemNoGtk.equals(laf)) {
+ laf = UIManager.getSystemLookAndFeelClassName();
+ if (GTK_LOOK_AND_FEEL_NAME.equals(laf))
+ laf = UIManager.getCrossPlatformLookAndFeelClassName();
+ }
+
+ UIManager.setLookAndFeel(laf);
+ }
+
+ // ========================================================================
+ // Singleton design pattern
+
+ private static LookAndFeelHandler theHandler = new LookAndFeelHandler();
+
+ /**
+ * Returns the currently active singleton of this class.
+ */
+ public static LookAndFeelHandler getInstance() {
+ return theHandler;
+ }
+
+ /**
+ * Replaces the singleton of this class.
+ * @param instance An instance of this class or of a customized subclass.
+ */
+ public static void setInstance(LookAndFeelHandler instance) {
+ theHandler = instance;
+ }
+
+ }

