English 中文(简体)
Getting the value from a Swing component from outside the EDT
原标题:
  • 时间:2009-11-07 21:17:40
  •  标签:
  • java
  • swing

My current code looks like this:

final String[] value = new String[1];

SwingUtilities.invokeAndWait(new Runnable() {
    public void run() {
        value[0] = textArea.getText();
    }
});

The use of a final array seems like a bit of a hack. Is there a more elegant solution?

I ve done a lot of searching, but I don t seem to be able to find anything to do this, which surprises me. Although I keep coming across SwingWorker, but I m not sure that s suitable in this case?

I m assuming that JTextArea.getText() isn t thread-safe.

Thanks.

最佳回答

All problems can be solved by adding another layer of indirection (except when you have too many layers :P).

public class TextSaver implements Runnable
{
    private final JTextArea textArea;
    private final ObjectToSaveText saveHere;

    public TextSaver(JTextArea textArea, ObjectToSaveText saveHere)
    {
        this.textArea = textArea;
        this.saveHere = saveHere;
    }

    @Override
    public void run()
    {
        saveHere.save(textArea.getText());
    }
}

I m not going to provide the code for ObjectToSaveText, but you get the idea. Then your SwingUtilties call just becomes:

SwingUtilities.invokeAndWait(new TextSaver(textArea, saveHere));

You can retrieve the saved text from your saveHere object.

问题回答

I find that in 99% of my Swing code that I m often accessing a JTextArea in response to a user action (the user has typed, clicked a button, closed a window, etc). All of these events are handled through event listeners which are always executed on the EDT.

Can you provide more detail in your use case?

UPDATE BASED ON USE CASE: Can the user change the text after the server has been started? If yes, then you can use the listener style mentioned previously. Make sure to be careful with your concurrency.If the user can t change the text, pass the text to the server thread in response to the button click (which will be on the EDT) and disable the text box.

LAST UPDATE:

If the client connections are persistent and the server continues to send updates you can use the listener model. If not, two copies of the data might be redundant. Either way, I think you ll end up having more threading work (unless you use selectors) on yours hands than worrying about copying one data value.

I think you ve got a plethora of info now, good luck.

I encountered the same need, to get swing component value, but from calls of a javascript engine within my application. I slapped together the following utility method.

/**
 * Executes the specified {@link Callable} on the EDT thread. If the calling
 * thread is already the EDT thread, this invocation simply delegates to
 * call(), otherwise the callable is placed in Swing s event dispatch queue
 * and the method waits for the result.
 * <p>
 * @param <V> the result type of the {@code callable}
 * @param callable the callable task
 * @return computed result
 * @throws InterruptedException if we re interrupted while waiting for the
 * event dispatching thread to finish executing doRun.run()
 * @throws ExecutionException if the computation threw an exception
 */
public static <V> V getFromEDT(final Callable<V> callable) throws InterruptedException, ExecutionException {
    final RunnableFuture<V> f = new FutureTask<>(callable);

    if (SwingUtilities.isEventDispatchThread()) {
        f.run();
    } else {
        SwingUtilities.invokeLater(f);
    }

    return f.get();
}

I m sure you can figure out how to use this, but I like to show how especially brief it is in Java 8:

String text = <String>getFromEDT(() -> textarea.getText());

Edit: changed method to do safe publication





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签