如何在EDT中运行Swing输入对话框并获取返回值?
How to Retrieve the JOptionPane Input Value When Using EventQueue.invokeAndWait()
Got it, let's break down how to solve this problem. The core issue is that Runnable.run() is a void method, so you can't directly return the input value from the EDT thread to your non-EDT trigger thread. Here's a clean, thread-safe way to capture that value:
Use an AtomicReference to Store the Result
Since anonymous inner classes can only access variables that are final or effectively final, we need a mutable container that can hold the input value. AtomicReference is perfect here—it's thread-safe and works seamlessly with the EDT/non-EDT interaction.
Here's the complete code example:
import java.awt.EventQueue; import java.util.concurrent.atomic.AtomicReference; import javax.swing.JOptionPane; import java.lang.reflect.InvocationTargetException; // ... your existing chat app code ... // In your non-EDT thread (server notification handler) AtomicReference<String> usernameRef = new AtomicReference<>(); try { EventQueue.invokeAndWait(() -> { // This code runs safely on the EDT String username = JOptionPane.showInputDialog(null, "Choose your username:"); usernameRef.set(username); }); } catch (InterruptedException | InvocationTargetException e) { // Handle exceptions appropriately (log, notify user, etc.) e.printStackTrace(); } // Access the value from your non-EDT thread String selectedUsername = usernameRef.get(); if (selectedUsername != null) { // User submitted a username, proceed with your chat logic System.out.println("User selected username: " + selectedUsername); } else { // User canceled the dialog, handle this edge case System.out.println("User canceled username selection."); }
Why This Works
AtomicReference<String>acts as a shared, thread-safe holder for the input value. We initialize it in the non-EDT thread, then the EDT thread sets its value once the user interacts with the dialog.EventQueue.invokeAndWait()blocks the non-EDT thread until theRunnablecompletes on the EDT, so once it returns, you can safely callusernameRef.get()to retrieve the value.- We handle the checked exceptions thrown by
invokeAndWait()—these occur if the waiting thread is interrupted, or if an error occurs inside the EDT-run code.
Critical Notes
- Never call
invokeAndWait()from the EDT itself—this will cause a deadlock, as the EDT will wait for itself to finish the task. Always confirm your trigger code runs on a non-EDT thread (like your server notification handler). - If the user clicks "Cancel" or closes the dialog,
JOptionPane.showInputDialog()returnsnull—make sure your code accounts for this to avoid null pointer exceptions or unexpected behavior.
内容的提问来源于stack exchange,提问作者Constantin Müller
相关产品推荐
相关产品推荐

