What is a look and feel that is compatible with MAC?
Asked Answered
S

1

5

I'm trying to set a look and feel for my application so it can be multi platform, but when I run it on a Mac, the buttons don't load correctly, and the size of the frame is disproportional. It works fine on Windows.

Here's how I'm setting the look and feel in the startup of the application

private static void setFrameTheme() throws Exception {
    try {
       UIManager.setLookAndFeel(
                     UIManager.getCrossPlatformLookAndFeelClassName());
    } catch (final Exception e) {
        UIManager.setLookAndFeel(UIManager
                .getCrossPlatformLookAndFeelClassName());

    }
}

But I get this error on the Mac

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at com.apple.laf.AquaMenuPainter.paintMenuBarBackground(AquaMenuPainter.java:145)
        at com.apple.laf.AquaMenuBarUI.paint(AquaMenuBarUI.java:71)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
        at javax.swing.JComponent.paintComponent(JComponent.java:778)
        at javax.swing.JComponent.paint(JComponent.java:1054)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5226)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
        at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
        at javax.swing.JComponent.paint(JComponent.java:1040)
        at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
        at java.awt.Container.paint(Container.java:1967)
        at java.awt.Window.paint(Window.java:3877)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:819)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
        at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at com.apple.laf.AquaMenuPainter.paintMenuBarBackground(AquaMenuPainter.java:145)
        at com.apple.laf.AquaMenuBarUI.paint(AquaMenuBarUI.java:71)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
        at javax.swing.JComponent.paintComponent(JComponent.java:778)
        at javax.swing.JComponent.paint(JComponent.java:1054)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
        at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5167)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4978)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
        at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
Slider answered 21/4, 2014 at 16:5 Comment(2)
You say you're "setting the look and feel in the startup of the application," but when exactly is setFrameTheme() being called?Superscription
When the frame loads. It works fine for windows users, but just not MacSlider
M
3

Personally, I always default the L&F to the system default one. It works nice on all platform and gives a decent look on all platforms.

Now, if you want one that stays the same everywhere, use the default Java one: Metal. Nimbus and CDE/Motif also gives the same look everywhere.

Small demo example code:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;

public class TestLaf {

    protected void initUI() {
        final JFrame frame = new JFrame(TestLaf.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JComboBox<LookAndFeelInfo> laf = new JComboBox<LookAndFeelInfo>();
        LookAndFeelInfo selected = null;
        for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
            laf.addItem(lafInfo);
            if (lafInfo.getName().equals(UIManager.getLookAndFeel().getName())) {
                selected = lafInfo;
            }
        }
        laf.setSelectedItem(selected);
        laf.setRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                if (value != null) {
                    LookAndFeelInfo lafInfo = (LookAndFeelInfo) value;
                    setText(lafInfo.getName());
                } else {
                    setText("");
                }
                return this;
            }
        });
        laf.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String className = laf.getModel().getElementAt(laf.getSelectedIndex()).getClassName();
                System.err.println("Changing to " + className);
                try {
                    UIManager.setLookAndFeel(className);
                    SwingUtilities.updateComponentTreeUI(frame.getRootPane());
                } catch (ClassNotFoundException e1) {
                    e1.printStackTrace();
                } catch (InstantiationException e1) {
                    e1.printStackTrace();
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace();
                } catch (UnsupportedLookAndFeelException e1) {
                    e1.printStackTrace();
                }
            }
        });
        frame.add(laf);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestLaf().initUI();
            }
        });
    }
}
Mohun answered 21/4, 2014 at 16:42 Comment(2)
I was using Nimbus prior to this and still got the same error; I even tried Metal. How do I get the default LAF for the system?Slider
@Kieran For your error: it's impossible to tell what's wrong with so little information. Please post a complete short example reproducing the error. For the default L&F, it is the first line of my main() method in my example.Mohun

© 2022 - 2024 — McMap. All rights reserved.