0

たとえば、ビューがユーザーにパスを選択するように求める機能を提供するJava GUIアプリケーションがあります。ユーザーがパスを選択するまで (またはユーザーがキャンセルするまで)、関数はブロックされている必要があります。

関数は EDT スレッドのコンテキストで呼び出されないため、invokeAndWait を使用します。パスがビューのプライベート メンバーである場合、次のようになります。

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;
}

私の問題は、EDT コンテキストで選択されたパスを、最初に呼び出された関数に渡し、そこに返す方法でした。次の行はすでにブロックされています。

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

とりあえず私は private member で解決しましたpathが、実際にはこの解決策が好きではありません.pathは一時的な変数であり、実際にはクラス自体とは何の関係もありません. これに対する別の解決策を探していたところ、 に出会いましたSwingWorkerが、これで「問題」を解決する方法がわかりませんでした。

別のアイデアは、getter と setter を使用してメンバーとして文字列を持つオブジェクトを作成して、この文字列を設定し、このオブジェクトの参照を渡して、EDT で文字列メンバーを設定し、getPath関数でそれを返すことです。

誰かがよりスムーズな解決策を持っていますか?

4

1 に答える 1

0

誰も別の解決策を思いつかないので、私が自分で見つけることができる最良の方法はこれです: 返す文字列を含む単純なオブジェクトを作成します。したがって、使用できる両方のタスクコンテキストで参照があります。私は誰かがこのソリューションを改善するためのコメントを持っています。私はそれを受け入れます。

文字列を保持するクラスです。

public class StringCover {
  private String string = "";

  public String getString() {
    return string;
  }

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

}

これは、このソリューションを使用した上記のコードです。

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();
}
于 2015-11-07T17:41:12.703 に答える