From 5c0de9aa1c05d00e1d7bee7e5db7a4471a6e2bc5 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 30 Apr 2020 13:38:23 +0200 Subject: [PATCH] macOS: Fixed NPE if using `JMenuBar` in `JInternalFrame` and macOS screen menu bar is enabled (issue #90) --- CHANGELOG.md | 2 ++ .../main/java/com/formdev/flatlaf/FlatLaf.java | 7 ++++++- .../com/formdev/flatlaf/ui/FlatMenuBarUI.java | 5 +++++ .../flatlaf/testing/FlatInternalFrameTest.java | 16 +++++++++++++++- .../flatlaf/testing/FlatInternalFrameTest.jfd | 8 +++++++- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef75c5d8..3ce18399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ FlatLaf Change Log - Show mnemonics always when a menu bar is active or a popup menu is visible. - Hide mnemonics if window is deactivated (e.g. Alt+Tab to another window). (issue #43) +- macOS: Fixed NPE if using `JMenuBar` in `JInternalFrame` and macOS screen menu + bar is enabled (with `-Dapple.laf.useScreenMenuBar=true`). (issue #90) ## 0.33 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index cb090b23..a184f428 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -38,6 +38,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; @@ -306,9 +307,13 @@ public abstract class FlatLaf UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults ); // use Aqua MenuBarUI if Mac screen menubar is enabled - if( SystemInfo.IS_MAC && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) + if( SystemInfo.IS_MAC && Boolean.getBoolean( "apple.laf.useScreenMenuBar" ) ) { defaults.put( "MenuBarUI", "com.apple.laf.AquaMenuBarUI" ); + // add defaults necessary for AquaMenuBarUI + defaults.put( "MenuBar.backgroundPainter", BorderFactory.createEmptyBorder() ); + } + // initialize text antialiasing putAATextInfo( defaults ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java index 8a509a19..fb399699 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java @@ -49,6 +49,11 @@ public class FlatMenuBarUI return new FlatMenuBarUI(); } + /* + * WARNING: This class is not used on macOS. + * Do not add any functionality here. + */ + @Override protected void installKeyboardActions() { super.installKeyboardActions(); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java index 4c2a7567..3e1af100 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java @@ -53,6 +53,14 @@ public class FlatInternalFrameTest if( iconCheckBox.isSelected() ) internalFrame.setFrameIcon( new FlatFileViewFloppyDriveIcon() ); + if( menuBarCheckBox.isSelected() ) { + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu( "I'm a Menu Bar" ); + menu.add( new JMenuItem( "Menu Item" ) ); + menuBar.add( menu ); + internalFrame.setJMenuBar( menuBar ); + } + JPanel panel = new JPanel() { private final Color color = new Color( (int) (Math.random() * 0xffffff) | 0x20000000, true ); @@ -93,6 +101,7 @@ public class FlatInternalFrameTest iconifiableCheckBox = new JCheckBox(); maximizableCheckBox = new JCheckBox(); iconCheckBox = new JCheckBox(); + menuBarCheckBox = new JCheckBox(); titleLabel = new JLabel(); titleField = new JTextField(); createFrameButton = new JButton(); @@ -152,6 +161,10 @@ public class FlatInternalFrameTest iconCheckBox.setText("Frame icon"); paletteContentPane.add(iconCheckBox, "cell 0 2"); + //---- menuBarCheckBox ---- + menuBarCheckBox.setText("Menu Bar"); + paletteContentPane.add(menuBarCheckBox, "cell 1 2"); + //---- titleLabel ---- titleLabel.setText("Frame title:"); paletteContentPane.add(titleLabel, "cell 0 3"); @@ -163,7 +176,7 @@ public class FlatInternalFrameTest paletteContentPane.add(createFrameButton, "cell 1 4,alignx right,growx 0"); } desktopPane.add(palette, JLayeredPane.PALETTE_LAYER); - palette.setBounds(15, 25, 220, 185); + palette.setBounds(15, 25, 275, 185); } add(desktopPane, "cell 0 0,width 600,height 600"); // JFormDesigner - End of component initialization //GEN-END:initComponents @@ -180,6 +193,7 @@ public class FlatInternalFrameTest private JCheckBox iconifiableCheckBox; private JCheckBox maximizableCheckBox; private JCheckBox iconCheckBox; + private JCheckBox menuBarCheckBox; private JLabel titleLabel; private JTextField titleField; private JButton createFrameButton; diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd index e74e2a14..e8d8bb9b 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd @@ -56,6 +56,12 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "menuBarCheckBox" + "text": "Menu Bar" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "titleLabel" "text": "Frame title:" @@ -77,7 +83,7 @@ new FormModel { }, new FormLayoutConstraints( null ) { "x": 15 "y": 25 - "width": 220 + "width": 275 "height": 185 "layer": 100 } )