Question

I have a class, which decorates JTextComponent from Swing. Methods that it contains can be called from any thread, so I have to ensure, that code which works with JTextComponent will be performed by AWT thread.

The second requirement is, that thread which calls whole method will be "waiting" until AWT thread will be done with the task.

public String getSelectedText() {
        Callable c = new Callable() {
            @Override
            public Object call() throws Exception {
                if (area.getSelectedText() == null) {
                    return "";
                }
                return area.getSelectedText();
            }
        };

        if (Thread.currentThread().getName().contains("AWT")) {
            return (String)c.call();
        }
        else {
            FutureTask task = new FutureTask(c);

            SwingUtilities.invokeLater(task);

            while (!task.isDone()) {
                //waiting
            }
            try {
                return (String)task.get();
            }
            catch (InterruptedException | ExecutionException ex) {
                return "";
            }
        }
    }

The code is working well for me, but there is still one problem. If anybody, who'll want to use my class, renames the AWT thread, then it falls in a deadlock.

Is there any way to unambiguously indentify the AWT thread and avoid this issue?

Thank you

Was it helpful?

Solution

Instead of testing the name, you should check whether the thread is the event dispatch thread:

if (EventQueue.isDispatchThread()) {
    // do stuff...
}

Note that even though you are using AWT, you can also call

if (SwingUtilities.isEventDispatchThread()) {
    // do stuff...
}

and get exactly the same thing.

OTHER TIPS

You're looking for SwingUtilities.isEventDispatchThread()

Also, instead of looping actively until the task is done, you should call SwingUtilities.invokeAndWait().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top