Search code examples
javaswinguimanager

Override UIManager in java


I have a Java swing notepad project, where I used UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) to change my look and feel on my windows-10 professional. I have a Menubar and a few menus, I want to set their background colour to cyan.

I tried using

JMenuBar mb = new JMenuBar();
mb.setBackground(Color.CYAN);

Also, I tried with and without

mb.setOpaque(true);

and

mb.setOpaque(false);

but it stays white, I tried the same with other colors, but none worked.

But this works for other components such as JTextArea, but not for the menubar and menus only, but I can change the foreground color of the Menus using the mb.setForeground() method, I can change the Menubar background only if I remove the UIManager(...) line, but I need the windows look and feel for some functions in the program.

Current output: Current output

Required output: Required output

The buggy code:

import javax.swing.*;
import java.awt.*;

public class withUIM{
    private static final JTextArea pad = new JTextArea();
    private static JLabel statusBar = new JLabel("||       Ln 1, Col 1  ", JLabel.RIGHT);
    private static JFrame f = new JFrame("Overriding UIManager");

    public static void main(String[] args){
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(600, 600);
        f.setBackground(Color.decode("#00FF00"));
        statusBar.setOpaque(true);
        statusBar.setBackground(Color.decode("#00FFFF"));
        statusBar.setForeground(Color.BLACK);
        f.add(new JScrollPane(pad), BorderLayout.CENTER);
        f.add(statusBar, BorderLayout.SOUTH);
        JLabel dummy = new JLabel("  ");
        dummy.setOpaque(true);
        dummy.setBackground(Color.decode("#00FFFF"));
        JLabel dummy1 = new JLabel("  ");
        dummy1.setOpaque(true);
        dummy1.setBackground(Color.decode("#00FFFF"));
        f.add(dummy, BorderLayout.EAST);
        f.add(dummy1, BorderLayout.WEST);
        JMenuBar mb = new JMenuBar();
        mb.setOpaque(true);
        mb.setBackground(Color.decode("#00FFFF"));
        JMenu fileMenu = new JMenu("file");
        fileMenu.setOpaque(false);
        JMenu editMenu = new JMenu("edit");
        editMenu.setOpaque(false);
        JMenu formatMenu = new JMenu("format");
        formatMenu.setOpaque(false);
        JMenu viewMenu = new JMenu("view");
        viewMenu.setOpaque(false);
        JMenu helpMenu = new JMenu("help");
        helpMenu.setOpaque(false);
        mb.add(fileMenu);
        mb.add(editMenu);
        mb.add(formatMenu);
        mb.add(viewMenu);
        mb.add(helpMenu);
        f.add(mb, BorderLayout.NORTH);
        f.setVisible(true);
    }
}

Any help will be appreciated.


Solution

  • According to the documentation for method setBackground (in class javax.swing.JComponent):

    It is up to the look and feel to honor this property, some may choose to ignore it.

    So it looks like com.sun.java.swing.plaf.windows.WindowsLookAndFeel does ignore the background property.

    One option would be to create a custom look-and-feel.

    Another option would be to use com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel.

    I assume that calling setOpaque(false) for every JMenu is just you trying to solve your problem. In the code below, I got rid of those calls.

    import javax.swing.*;
    import java.awt.*;
    
    public class withUIM {
        private static final JTextArea pad = new JTextArea();
        private static JLabel statusBar = new JLabel("||       Ln 1, Col 1  ", JLabel.RIGHT);
        private static JFrame f = new JFrame("Overriding UIManager");
    
        public static void main(String[] args) {
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(600, 600);
            f.setBackground(Color.decode("#00FF00"));
            statusBar.setOpaque(true);
            statusBar.setBackground(Color.decode("#00FFFF"));
            statusBar.setForeground(Color.BLACK);
            f.add(new JScrollPane(pad), BorderLayout.CENTER);
            f.add(statusBar, BorderLayout.SOUTH);
            JLabel dummy = new JLabel("  ");
            dummy.setOpaque(true);
            dummy.setBackground(Color.decode("#00FFFF"));
            JLabel dummy1 = new JLabel("  ");
            dummy1.setOpaque(true);
            dummy1.setBackground(Color.decode("#00FFFF"));
            f.add(dummy, BorderLayout.EAST);
            f.add(dummy1, BorderLayout.WEST);
            JMenuBar mb = new JMenuBar();
            mb.setBackground(Color.decode("#00FFFF"));
            JMenu fileMenu = new JMenu("file");
            fileMenu.setBackground(Color.decode("#00FFFF"));
            JMenu editMenu = new JMenu("edit");
            editMenu.setBackground(Color.decode("#00FFFF"));
            JMenu formatMenu = new JMenu("format");
            formatMenu.setBackground(Color.decode("#00FFFF"));
            JMenu viewMenu = new JMenu("view");
            viewMenu.setBackground(Color.decode("#00FFFF"));
            JMenu helpMenu = new JMenu("help");
            helpMenu.setBackground(Color.decode("#00FFFF"));
            mb.add(fileMenu);
            mb.add(editMenu);
            mb.add(formatMenu);
            mb.add(viewMenu);
            mb.add(helpMenu);
            f.add(mb, BorderLayout.NORTH);
            f.setVisible(true);
        }
    }
    

    Screen capture:

    screen capture