什么是与MAC兼容的外观和感觉?

时间:2014-04-21 16:05:30

标签: java swing user-interface look-and-feel

我试图为我的应用程序设置外观和感觉,因此它可以是多平台,但是当我在Mac上运行时,按钮不能正确加载,并且框架的大小是不成比例的。它在Windows上运行良好。

以下是我在应用程序启动时设置外观的方法

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

    }
}

但我在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)

1 个答案:

答案 0 :(得分:2)

就个人而言,我总是将L& F默认为系统默认值。它在所有平台上运行良好,并在所有平台上都能提供不错的外观。

现在,如果你想在任何地方保持不变,请使用默认的Java:Metal。 Nimbus和CDE / Motif在各地都有相同的外观。

小型演示示例代码:

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();
            }
        });
    }
}