tags:

views:

169

answers:

2

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.

+1  A: 

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.

basszero
I want to be able to get the contents of the text area using a socket connection. But, yes, you're right—I can just copy the contents to a variable whenever the text area is changed, and fetch from there.
Joe Freeman
Doesn't make sense to me to keep two copies of the data. I think your original solution is simpler.
camickr
We could probably still provide a better answer with more details. Assuming this is some sort of client-server setup, is one side polling the other to get the text? What is the sequence of events?
basszero
Textbox, button. Clicking button starts server (new thread). Client connects, server responds with contents of textbox.
Joe Freeman
The user can change the text after the server has started. When you refer to 'listener style', do you mean listening for changes and keeping a copy of the data? I'm inclined to agree with camickr.
Joe Freeman
+2  A: 

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.

racc
Ah, so basically just storing the value into an object property rather than a local variable? That should do the trick :)
Joe Freeman
So up vote me then please?? :D (it's my first answered question cmon)
racc
And yes it is probably a more elegant solution, because you abstract out task of saving the text out to another class...
racc