Menus: avoid that SubMenuUsabilityHelper can be installed multiple times, which can freeze the application caused pushing multiple event queues and popping wrong event queue first

(e.g. NetBeans Form Editor invokes `FlatLaf.initialize()` but not `uninitialize()`)

(PR #490; https://github.com/apache/netbeans/issues/4231)
This commit is contained in:
Karl Tauber
2022-07-12 10:33:53 +02:00
parent f460ef7685
commit 8b5a738e65
3 changed files with 29 additions and 11 deletions

View File

@@ -7,6 +7,11 @@ FlatLaf Change Log
- ComboBox: Fixed vertical alignment of text in popup list with text in combo
box in IntelliJ/Darcula themes.
- Menus: Fixed application freeze under very special conditions (invoking
`FlatLaf.initialize()` twice in NetBeans GUI builder) and using menu that has
submenus. See
[NetBeans issue #4231](https://github.com/apache/netbeans/issues/4231#issuecomment-1179611682)
for details.
- MenuItem: Fixed sometimes wrapped HTML text on HiDPI screens on Windows.
- TableHeader: Fixed exception when changing table structure (e.g. removing
column) from a table header popup menu action. (issue #532)

View File

@@ -103,7 +103,7 @@ public abstract class FlatLaf
private PopupFactory oldPopupFactory;
private MnemonicHandler mnemonicHandler;
private SubMenuUsabilityHelper subMenuUsabilityHelper;
private boolean subMenuUsabilityHelperInstalled;
private Consumer<UIDefaults> postInitialization;
private List<Function<Object, Object>> uiDefaultsGetters;
@@ -246,8 +246,7 @@ public abstract class FlatLaf
mnemonicHandler.install();
// install submenu usability helper
subMenuUsabilityHelper = new SubMenuUsabilityHelper();
subMenuUsabilityHelper.install();
subMenuUsabilityHelperInstalled = SubMenuUsabilityHelper.install();
// listen to desktop property changes to update UI if system font or scaling changes
if( SystemInfo.isWindows ) {
@@ -329,9 +328,9 @@ public abstract class FlatLaf
}
// uninstall submenu usability helper
if( subMenuUsabilityHelper != null ) {
subMenuUsabilityHelper.uninstall();
subMenuUsabilityHelper = null;
if( subMenuUsabilityHelperInstalled ) {
SubMenuUsabilityHelper.uninstall();
subMenuUsabilityHelperInstalled = false;
}
// restore default link color

View File

@@ -59,6 +59,11 @@ class SubMenuUsabilityHelper
private static final String KEY_USE_SAFE_TRIANGLE = "Menu.useSafeTriangle";
private static final String KEY_SHOW_SAFE_TRIANGLE = "FlatLaf.debug.menu.showSafeTriangle";
// Using a static field to ensure that there is only one instance in the system.
// Multiple instances would freeze the application.
// https://github.com/apache/netbeans/issues/4231#issuecomment-1179616607
private static SubMenuUsabilityHelper instance;
private SubMenuEventQueue subMenuEventQueue;
private SafeTrianglePainter safeTrianglePainter;
private boolean changePending;
@@ -74,13 +79,22 @@ class SubMenuUsabilityHelper
private Rectangle invokerBounds;
void install() {
MenuSelectionManager.defaultManager().addChangeListener( this );
static synchronized boolean install() {
if( instance != null )
return false;
instance = new SubMenuUsabilityHelper();
MenuSelectionManager.defaultManager().addChangeListener( instance );
return true;
}
void uninstall() {
MenuSelectionManager.defaultManager().removeChangeListener( this );
uninstallEventQueue();
static synchronized void uninstall() {
if( instance == null )
return;
MenuSelectionManager.defaultManager().removeChangeListener( instance );
instance.uninstallEventQueue();
instance = null;
}
@Override