java - 我能否在 Mac OS X 上为 Swing 获得原生外观的 JPopupMenu 外观?

标签 java macos swing jpopupmenu quaqua

我正在尝试使 Swing(在 Java 7 下)中的组合框看起来像 native 组合框。原来 JPopupMenu 是用来显示组合框的选项的,所以这就变成了让 JPopupMenu 看起来足够原生的问题。

如果我使用默认的 Aqua 外观和感觉,我会得到方形边缘,这根本不正确,所以我们会立即放弃这个想法。因此,当然,人们会转向 Quaqua,它应该可以解决这类问题。

public class PopupMenuTest implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new PopupMenuTest());
    }

    @Override
    public void run() {
        try {
            UIManager.setLookAndFeel(QuaquaManager.getLookAndFeel());
            // Uncomment this for the second example
            //PopupFactory.setSharedInstance(new CustomisedScreenPopupFactory());
        } catch (Exception ignore) {}

        JComboBox<String> comboBox = new JComboBox<>();
        comboBox.setModel(new DefaultComboBoxModel<>(
            new String[] { "One", "Two", "Three" }));

        JFrame frame = new JFrame("Test");
        frame.setLayout(new FlowLayout());
        frame.add(comboBox);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

这给了我 a popup menu which does have rounded corners but has filled in the corners with black .

在上面注释掉代码的地方,我尝试在自定义屏幕弹出工厂中进行干扰。

public class CustomisedScreenPopupFactory extends PopupFactory {
    private final PopupFactory delegate;

    public CustomisedScreenPopupFactory() {
        PopupFactory delegate;
        try {
            Class<? extends PopupFactory> clazz =
                Class.forName("com.apple.laf.ScreenPopupFactory")
                    .asSubclass(PopupFactory.class);
            Constructor<? extends PopupFactory> constructor =
                clazz.getDeclaredConstructor();
            constructor.setAccessible(true); // hacks
            delegate = constructor.newInstance();
        } catch (Exception ignore) {
            delegate = new PopupFactory(); // has to be set to something
        }
        this.delegate = delegate;
    }

    @Override
    public Popup getPopup(Component owner, Component contents, int x, int y) {
        Popup popup = delegate.getPopup(owner, contents, x, y);

        try {
            Method method = Popup.class.getDeclaredMethod("getComponent");
            method.setAccessible(true);
            Component component = (Component) method.invoke(popup);
            if (component instanceof JWindow) {    // always is, so far
                JWindow window = (JWindow) component;
                JRootPane rootPane = window.getRootPane();

                // This call here is what all the rest of the boilerplate was
                // added in order to access.
                AWTUtilities.setWindowOpaque(window, false);
            }
        } catch (Exception e) {
            Logger.getLogger(getClass()).error("Couldn't customise the popup window", e);
        }

        return popup;
    }
}

这给了我 an interesting result where the black corners are gone, but so is the shadow .

问题是,我想要圆角和阴影。两者都可以吗?

顺便说一句,我注意到 IDEA 确实做得对,但我无法从他们的源代码中找出它为什么会起作用,所以我想知道这是否是因为它运行在 Java 6 而不是 Java 7 上......

最佳答案

您可以像这样匹配系统的外观:

    try{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName);
    catch(Exception e){}

这只是获得系统 L&F,无论如何,这都比外部 L&F 更原始。

希望这有帮助!

关于java - 我能否在 Mac OS X 上为 Swing 获得原生外观的 JPopupMenu 外观?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20965340/

相关文章:

java - 在同一项目中使用多种 JVM 语言

html - 用于 Objective-C 的 Web 服务器

java - JFrame 相互重叠

java - SwingWorker 和 Executor 的区别

Java 反射 : Find method usage in custom AbstractProcessor

java - 从 Intent : 中获取额外内容的问题

java - 选项面板验证

c++ - 在 macOS 上编译 C++ SDL

macos - Homebrew 从 github.com 获取超时

java - Java 组布局