4

I am trying to adjust the colors of the Nimbus Look and Feel but it is only working partially. Especially I have problems adjusting the colors of the menubar.

Here is a running example:

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;

public class JMenuColorTest extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    adjustLAF();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                JMenuColorTest test = new JMenuColorTest();
                test.setDefaultCloseOperation(EXIT_ON_CLOSE);
                test.setPreferredSize(new Dimension(400, 300));
                test.pack();
                test.setLocationRelativeTo(null);

                JMenuBar menuBar = new JMenuBar();
                JMenu menu1 = new JMenu("Menu 1");
                menu1.add(new JMenuItem("Item 1.1"));
                menu1.add(new JMenuItem("Item 1.2"));
                menu1.add(new JMenuItem("Item 1.3"));
                menuBar.add(menu1);
                JMenu menu2 = new JMenu("Menu 2");
                menu2.add(new JMenuItem("Item 2.1"));
                menu2.add(new JMenuItem("Item 2.2"));
                menu2.add(new JMenuItem("Item 2.3"));
                menuBar.add(menu2);
                test.setJMenuBar(menuBar);

                test.setVisible(true);
            }

            private void adjustLAF() throws ClassNotFoundException,
                InstantiationException, IllegalAccessException,
                UnsupportedLookAndFeelException {
                for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {

                        // Working
                        UIManager.put("control", Color.GREEN);

                        // Not working
                        UIManager.getLookAndFeelDefaults().put(
                            "MenuItem[Enabled].textForeground", Color.RED);

                        // Set the look and feel
                        UIManager.setLookAndFeel(info.getClassName());

                        // Not working
                        UIManager.put("control", Color.GREEN);

                        // Working
                        UIManager.getLookAndFeelDefaults().put(
                            "MenuItem[Enabled].textForeground", Color.RED);

                        break;
                    }
                }

            }
        });
    }
}

As you can see I am able to set background of the controls and set the foreground color of the JMenuItem. But I am not able to change the background of a JMenuItem, neither I am able to change the colors of the MenuBar. I tried a lot of keys from http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/_nimbusDefaults.html but I was not able to change the color of the menubar.

Another question is? Why do I have to call the adjusting of the colors once before setting the Look and Feel and once after setting the Look and Feel? And why do I have to call once 'UIManager.put()' and once 'UIManager.getLookAndFeelDefaults().put()'?

It seems to me that Nimbus is really buggy and not suitable for professional use. I tried to use both JDK 1.6.35 and JDK 1.7.7, but with both JDKs I could not get the system running as desired?

Any suggestions how to adjust the colors of a menubar in Nimbus LookAnd Feel?

Thanks in advance

mKorbel
  • 109,525
  • 20
  • 134
  • 319
hami
  • 443
  • 5
  • 13

2 Answers2

5

for JMenuBar to have to use Painter, to check NimbusDefault#value

MenuBar[Enabled].backgroundPainter
MenuBar[Enabled].borderPainter

rest is in answer by trashgod +1

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks for your answer. The coloring of the background now works fine. But Do you know how to set the foreground (color of the text)? 'UIManager.getLookAndFeelDefaults().put( "MenuBar.foreground", Color.CYAN)' is not working. – hami Sep 11 '12 at 14:55
  • @hami 1st code line inside `if ("Nimbus".equals(info.getName())) {` must be `UIManager.setLookAndFeel(info.getClassName());`, then after youo can to put (and all changes must be) `UIManager.getLookAndFeelDefaults().put("Xxx", "Xxx")`, maybe looks like strange but with simple logic – mKorbel Sep 11 '12 at 17:06
  • hmm sure I quite undestand this ZOO in your head (JComponent and its values) and no issue with `UIManager.getLookAndFeelDefaults().put("Menu[Enabled].textForeground", Color.GREEN); ` or `UIManager.getLookAndFeelDefaults().put("Menu[Selected].textForeground", Color.GREEN); ` – mKorbel Sep 11 '12 at 17:09
  • @mKorbel: Would this `Painter` [example](http://stackoverflow.com/a/10788379/230513) be appropriate? – trashgod Sep 11 '12 at 23:49
  • 1
    @trashgod no it isn't, because it missed GradientPaint..., only Filler :-) – mKorbel Sep 12 '12 at 04:51
  • @mKorbel when I use 1st set LAF and then call `UIManager.getLookAndFeelDefaults().put("control", Color.GREEN);` it is not working. – hami Sep 12 '12 at 07:41
  • @hami where do you need to use Nimbus#control, for why reason your need that, only questions:-),......... [please to read my another answer](http://stackoverflow.com/a/12382370/714968) , there I put everything that I know about Nimbus together – mKorbel Sep 12 '12 at 07:48
  • @mKorbel Setting the foreground of the menubar now works fine. Thanks. – hami Sep 12 '12 at 07:48
  • but you have to enlarge / change Painter from filler to GradientPaint :-) – mKorbel Sep 12 '12 at 07:51
  • 1
    @mKorbel as I read about Nimbus you should set the primary colors and probably the secondary colors to achieve a fine color theme. The colors of the components are then set automatically to a nice value. This is not working fine, but Nimbus#nimbusBase, Nimbus#nimbusBlueGray and Nimbus#control are working. But appearantly you have to call `UIManager.put` **before** you set the LAF to set the primary and secondary colors, while you have to call `UIManager.getLookAndFeelDefaults().put` **afterwards** to set the colors of the components directly. – hami Sep 12 '12 at 08:10
3

Making adjustLAF() static and invoking it before the Runnable seems to work on Mac OS X with com.apple.laf.AquaLookAndFeel.

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;

public class JMenuColorTest extends JFrame {

    public static void main(String[] args) {
                try {
                    adjustLAF();
                } catch (Exception e) {
                    e.printStackTrace();
                }

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                JMenuColorTest test = new JMenuColorTest();
                test.setDefaultCloseOperation(EXIT_ON_CLOSE);
                test.setPreferredSize(new Dimension(400, 300));
                test.pack();
                test.setLocationRelativeTo(null);

                JMenuBar menuBar = new JMenuBar();
                JMenu menu1 = new JMenu("Menu 1");
                menu1.add(new JMenuItem("Item 1.1"));
                menu1.add(new JMenuItem("Item 1.2"));
                menu1.add(new JMenuItem("Item 1.3"));
                menuBar.add(menu1);
                JMenu menu2 = new JMenu("Menu 2");
                menu2.add(new JMenuItem("Item 2.1"));
                menu2.add(new JMenuItem("Item 2.2"));
                menu2.add(new JMenuItem("Item 2.3"));
                menuBar.add(menu2);
                test.setJMenuBar(menuBar);

                test.setVisible(true);
            }

        });
    }
    private static void adjustLAF() throws ClassNotFoundException,
        InstantiationException, IllegalAccessException,
        UnsupportedLookAndFeelException {
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {

                // Working
                UIManager.put("control", Color.GREEN);

                // Not working
                UIManager.getLookAndFeelDefaults().put(
                    "MenuItem[Enabled].textForeground", Color.RED);

                // Set the look and feel
                UIManager.setLookAndFeel(info.getClassName());

                // Not working
                UIManager.put("control", Color.GREEN);

                // Working
                UIManager.getLookAndFeelDefaults().put(
                    "MenuItem[Enabled].textForeground", Color.RED);

                break;
            }
        }

    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • This worked on Windows and my example, too, but I wanted to color the background of MenuBar, like mKorbel described in his answer. – hami Sep 11 '12 at 14:53
  • @trashgod could you tell me how to change the selction color on menu. `"nimbusSelection",Color.red` I have done this but this changes the selection of color of `menuitem` but not the `menu`. – Vighanesh Gursale Jun 08 '14 at 19:37
  • Try changing `"Menu[Enabled].textForeground"`. – trashgod Jun 08 '14 at 19:57