Search code examples
javaswingevent-dispatch-thread

Getting the value from a Swing component from outside the EDT


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.


Solution

  • 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.