From 48355e37a891f124d6868cf9d89eae2aa9bc99b8 Mon Sep 17 00:00:00 2001 From: violet-isle Date: Thu, 20 Feb 2025 11:21:14 -0500 Subject: [PATCH] Prevent hide on popup window losing focus, fixed escape key listener to close popup --- .../eocvsim/util/event/EventHandler.kt | 36 +++++++++---------- .../eocvsim/gui/DialogFactory.java | 4 +++ .../eocvsim/gui/component/PopupX.kt | 7 ++-- .../gui/dialog/source/CreateImageSource.java | 4 ++- .../gui/dialog/source/CreateSource.java | 5 ++- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Common/src/main/java/com/github/serivesmejia/eocvsim/util/event/EventHandler.kt b/Common/src/main/java/com/github/serivesmejia/eocvsim/util/event/EventHandler.kt index 870be586..f7d018cd 100644 --- a/Common/src/main/java/com/github/serivesmejia/eocvsim/util/event/EventHandler.kt +++ b/Common/src/main/java/com/github/serivesmejia/eocvsim/util/event/EventHandler.kt @@ -45,8 +45,8 @@ class EventHandler(val name: String) : Runnable { * Check if a class loader is banned */ fun isBanned(classLoader: ClassLoader): Boolean { - for(bannedClassLoader in bannedClassLoaders) { - if(bannedClassLoader.get() == classLoader) return true + for (bannedClassLoader in bannedClassLoaders) { + if (bannedClassLoader.get() == classLoader) return true } return false @@ -63,7 +63,7 @@ class EventHandler(val name: String) : Runnable { * thread-safe operation (synchronized) */ val listeners: Array - get() { + get() { synchronized(lock) { return internalListeners.toTypedArray() } @@ -82,18 +82,18 @@ class EventHandler(val name: String) : Runnable { var callRightAway = false - private val internalListeners = ArrayList() + private val internalListeners = ArrayList() private val internalOnceListeners = ArrayList() /** * Run all the listeners in this event handler */ override fun run() { - for(listener in listeners) { + for (listener in listeners) { try { runListener(listener, false) } catch (ex: Exception) { - if(ex is InterruptedException) { + if (ex is InterruptedException) { logger.warn("Rethrowing InterruptedException...") throw ex } else { @@ -105,11 +105,11 @@ class EventHandler(val name: String) : Runnable { val toRemoveOnceListeners = mutableListOf() //executing "doOnce" listeners - for(listener in onceListeners) { + for (listener in onceListeners) { try { runListener(listener, true) } catch (ex: Exception) { - if(ex is InterruptedException) { + if (ex is InterruptedException) { logger.warn("Rethrowing InterruptedException...") throw ex } else { @@ -122,7 +122,7 @@ class EventHandler(val name: String) : Runnable { } synchronized(onceLock) { - for(listener in toRemoveOnceListeners) { + for (listener in toRemoveOnceListeners) { internalOnceListeners.remove(listener) } } @@ -133,7 +133,7 @@ class EventHandler(val name: String) : Runnable { * @param listener the listener to add */ fun doOnce(listener: EventListener) { - if(callRightAway) + if (callRightAway) runListener(listener, true) else synchronized(onceLock) { internalOnceListeners.add(listener) @@ -155,7 +155,7 @@ class EventHandler(val name: String) : Runnable { internalListeners.add(listener) } - if(callRightAway) runListener(listener, false) + if (callRightAway) runListener(listener, false) return EventListenerRemover(this, listener, false) } @@ -171,7 +171,7 @@ class EventHandler(val name: String) : Runnable { * @param listener the listener to remove */ fun removePersistentListener(listener: EventListener) { - if(internalListeners.contains(listener)) { + if (internalListeners.contains(listener)) { synchronized(lock) { internalListeners.remove(listener) } } } @@ -181,7 +181,7 @@ class EventHandler(val name: String) : Runnable { * @param listener the listener to remove */ fun removeOnceListener(listener: EventListener) { - if(internalOnceListeners.contains(listener)) { + if (internalOnceListeners.contains(listener)) { synchronized(onceLock) { internalOnceListeners.remove(listener) } } } @@ -215,7 +215,7 @@ class EventHandler(val name: String) : Runnable { operator fun invoke(listener: EventListener) = doPersistent(listener) private fun runListener(listener: EventListener, isOnce: Boolean) { - if(isBanned(listener.javaClass.classLoader)) { + if (isBanned(listener.javaClass.classLoader)) { removeBannedListeners() return } @@ -224,15 +224,15 @@ class EventHandler(val name: String) : Runnable { } private fun removeBannedListeners() { - for(listener in internalListeners.toArray()) { - if(isBanned(listener.javaClass.classLoader)) { + for (listener in internalListeners.toArray()) { + if (isBanned(listener.javaClass.classLoader)) { internalListeners.remove(listener) logger.warn("Removed banned listener from ${listener.javaClass.classLoader}") } } - for(listener in internalOnceListeners.toArray()) { - if(isBanned(listener.javaClass.classLoader)) internalOnceListeners.remove(listener) + for (listener in internalOnceListeners.toArray()) { + if (isBanned(listener.javaClass.classLoader)) internalOnceListeners.remove(listener) logger.warn("Removed banned listener from ${listener.javaClass.classLoader}") } } diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/DialogFactory.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/DialogFactory.java index 5499d2d6..be048faf 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/DialogFactory.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/DialogFactory.java @@ -38,6 +38,8 @@ import com.github.serivesmejia.eocvsim.util.exception.handling.CrashReport; import io.github.deltacv.eocvsim.plugin.loader.PluginManager; + + import javax.swing.*; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; @@ -63,6 +65,7 @@ public static void createYesOrNo(Component parent, String message, String submes } invokeLater(() -> result.accept( + JOptionPane.showConfirmDialog(parent, panel, "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE @@ -97,6 +100,7 @@ public static FileChooser createFileChooser(Component parent) { public static void createSourceDialog(EOCVSim eocvSim, SourceType type, File initialFile) { + invokeLater(() -> { switch (type) { case IMAGE: diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/component/PopupX.kt b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/component/PopupX.kt index d9d7e590..25f5861a 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/component/PopupX.kt +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/component/PopupX.kt @@ -55,6 +55,7 @@ class PopupX @JvmOverloads constructor(windowAncestor: Window, window.size = panel.preferredSize + windowAncestor.requestFocusInWindow() windowAncestor.addKeyListener(object: KeyAdapter() { override fun keyPressed(e: KeyEvent?) { if(e?.keyCode == KeyEvent.VK_ESCAPE) { @@ -88,11 +89,7 @@ class PopupX @JvmOverloads constructor(windowAncestor: Window, override fun windowGainedFocus(e: WindowEvent?) {} - override fun windowLostFocus(e: WindowEvent?) { - if(closeOnFocusLost) { - hide() - } - } + override fun windowLostFocus(e: WindowEvent?) {} fun setLocation(width: Int, height: Int) = window.setLocation(width, height) diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateImageSource.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateImageSource.java index e5c44d0f..7a7a6451 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateImageSource.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateImageSource.java @@ -67,7 +67,9 @@ public CreateImageSource(JFrame parent, EOCVSim eocvSim, File initialFile) { public void initCreateImageSource() { - createImageSource.setModal(true); + createImageSource.setModal(false); + createImageSource.setFocusableWindowState(false); + createImageSource.setAlwaysOnTop(true); createImageSource.setTitle("Create image source"); createImageSource.setSize(370, 200); diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateSource.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateSource.java index 453bdc12..1e811378 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateSource.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/gui/dialog/source/CreateSource.java @@ -43,6 +43,7 @@ public CreateSource(JFrame parent, EOCVSim eocvSim) { chooseSource = new JDialog(parent); + this.parent = parent; this.eocvSim = eocvSim; @@ -55,7 +56,9 @@ private void initChooseSource() { alreadyOpened = true; - chooseSource.setModal(true); + chooseSource.setModal(false); + chooseSource.setFocusableWindowState(false); + chooseSource.setAlwaysOnTop(true); chooseSource.setTitle("Select source type"); chooseSource.setSize(300, 150);