United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7169111 : Unreadable menu bar with Ambiance theme in GTK L&F

Details
Type:
Bug
Submit Date:
2012-05-15
Status:
Resolved
Updated Date:
2013-09-26
Project Name:
JDK
Resolved Date:
2012-07-10
Component:
client-libs
OS:
linux,linux_ubuntu
Sub-Component:
javax.swing
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:
Duplicate:

Sub Tasks

Description
Using JDK 6 or 7, run any Swing app with a menu bar, e.g.

import com.sun.java.swing.plaf.gtk.GTKLookAndFeel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
public class Demo {
    public static void main(String... args) throws Exception {
        UIManager.setLookAndFeel(new GTKLookAndFeel());
        JMenuItem exitItem = new JMenuItem("Exit");
        exitItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        JMenu fileMenu = new JMenu("File");
        fileMenu.add(exitItem);
        JMenuBar bar = new JMenuBar();
        bar.add(fileMenu);
        JFrame frame = new JFrame("Demo");
        frame.setJMenuBar(bar);
        frame.setBounds(100, 100, 300, 100);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

in Ubuntu 12.04 using the default Ambiance theme. The menu bar will be visible, but the text ("File") will be in dark grey on black, nearly unreadable. The menu text is only readable when the menu is selected.

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-comp/jdk/rev/85f72a4f5f68
                                     
2012-08-14
EVALUATION

In GTK LookAndFeel we should use MenuBar widget type (and so his color and font scheme) for top level menus.
                                     
2012-06-26
WORK AROUND

Besides using a different theme, Launchpad bug suggests working around in theme file:

--- /usr/share/themes/Ambiance/gtk-2.0/gtkrc	2012-04-12 09:24:22.000000000 -0400
+++ /usr/share/themes/Ambiance/gtk-2.0/gtkrc	2012-05-15 18:16:48.115264838 -0400
@@ -335,7 +335,7 @@
 	}
 }
 
-style "menu" {
+style "menu" = "dark" {
 	xthickness = 0
 	ythickness = 0
 
No workaround yet known from the side of the Java application.
                                     
2012-05-15
PUBLIC COMMENTS

Originally reported as https://bugs.launchpad.net/ubuntu/+source/light-themes/+bug/932274 (also https://bugs.launchpad.net/ubuntu/+source/light-themes/+bug/975894 marked as duplicate).
                                     
2012-05-15
EVALUATION

Comments in Launchpad reports mostly suggest that the bug is in the JRE's handling of the theme. Somehow "menu" and "menubar" are getting mixed up?
                                     
2012-05-15
SUGGESTED FIX

The following may not be "right" but it works (at least in 12.04's Ambiance, and seems to do no harm in Radiance):

diff --git a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java
--- a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java
+++ b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java
@@ -191,7 +191,11 @@
     {
         state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
         synchronized (sun.awt.UNIXToolkit.GTK_LOCK) {
-            int rgb = nativeGetColorForState(widgetType, state,
+            int effectiveWidgetType = widgetType;
+            if (effectiveWidgetType == WidgetType.MENU.ordinal() && type == ColorType.FOREGROUND) {
+                effectiveWidgetType = WidgetType.MENU_BAR.ordinal();
+            }
+            int rgb = nativeGetColorForState(effectiveWidgetType, state,
                                              type.getID());
             return new ColorUIResource(rgb);
         }
                                     
2012-05-15
WORK AROUND

Works for the simple demo but causes CCEs (to GTKStyleFactory) in some cases:

LookAndFeel laf = UIManager.getLookAndFeel();
if (laf != null && laf.getID().equals("GTK")) {
    SynthLookAndFeel.setStyleFactory(new SynthStyleFactory() {
        final SynthStyleFactory origFactory = SynthLookAndFeel.getStyleFactory();
        @Override public SynthStyle getStyle(JComponent c, Region id) {
            if (id == Region.MENU) {
                return origFactory.getStyle(c, Region.MENU_BAR);
            }
            return origFactory.getStyle(c, id);
        }
    });
}
                                     
2012-05-15



Hardware and Software, Engineered to Work Together