Return Value from InvokeAndWait

725 Views Asked by At

I have a Java GUI application in which the view should provide a function which asks the user to choose a path for example. The function should be blocking until the user selected the path (or also if the user cancelled).

As the function is not called in the context of the EDT Thread I use invokeAndWait. It looks something like this, where path is a private member of the view:

private String path;

public String getPath(String defaultPath)
{
    try{
        SwingUtilities.invokeAndWait( () -> {
             // Ask here the user for the path
             path = new PathSelector(defaultPath).getPath();
        }
    } catch (InvocationTargetException e) {
        return "";
    } catch (InterruptedException e) {
        return "";
    }
    return path;
}

My problem was how to pass the path, which is selected in the EDT context, to the function which was initially called and return it there. The following line is already blocking:

path = new PathSelector(defaultPath).getPath();

For the moment I solved it with a private member path, but actually I don't like this solution, cause path is more a temporary variable and has actually nothing to do with the class itself. Searching for another solution for this, I came across the SwingWorker but I couldn't figure out how I could solve with this my 'problem'.

An other idea is maybe to create an object which has a string as member with getter and setter to set this string and pass a reference of this object which could set the string member in the EDT and get it back in the getPath function to return it.

Has anyone a smoother solution?

1

There are 1 best solutions below

0
On BEST ANSWER

As nobody comes up with another solution, the best one that I could find out by myself is this: I create a simple object which contains the string to return. So I have a reference in both task contexts which I can use. I somebody has some comments to improve this solution, I'm open for it.

This is the class which holds the string.

public class StringCover {
  private String string = "";

  public String getString() {
    return string;
  }

  public void setString(String string) {
    this.string = string;
  }

}

And this is the code from above with this solution.

public String getPath(String defaultPath)
{
    StringCover stringCover = new StringCover();
    try{
        SwingUtilities.invokeAndWait( () -> {
             // Ask here the user for the path
             stringCover.setString(new PathSelector(defaultPath).getPath());
        }
    } catch (InvocationTargetException e) {
        stringCover.setString("");
    } catch (InterruptedException e) {
        stringCover.setString("");
    }
    return stringCover.getString();
}