2

私の現在のコードは次のようになります。

final String[] value = new String[1];

SwingUtilities.invokeAndWait(new Runnable() {
    public void run() {
        value[0] = textArea.getText();
    }
});

final 配列の使用は、ちょっとしたハックのように思えます。よりエレガントなソリューションはありますか?

私は多くの検索を行いましたが、これを行うための何かを見つけることができないようです.これは私を驚かせます. に出くわしSwingWorkerますが、この場合に適しているかどうかわかりませんか?

JTextArea.getText()それはスレッドセーフではないと思います。

ありがとう。

4

3 に答える 3

3

すべての問題は、間接層の別の層を追加することで解決できます(層が多すぎる場合を除く: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());
    }
}

ObjectToSaveTextのコードは提供しませんが、理解できます。次に、SwingUtiltiesの呼び出しは次のようになります。

SwingUtilities.invokeAndWait(new TextSaver(textArea, saveHere));

保存したテキストは、saveHereオブジェクトから取得できます。

于 2009-11-08T02:07:19.860 に答える
1

私の Swing コードの 99% で、ユーザーのアクション (ユーザーが入力した、ボタンをクリックした、ウィンドウを閉じたなど) に応答して JTextArea にアクセスしていることがよくあります。これらのイベントはすべて、常に EDT で実行されるイベント リスナーを通じて処理されます。

ユースケースの詳細を教えてください。

ユースケースに基づく更新: サーバーの起動後にユーザーはテキストを変更できますか? はいの場合は、前述のリスナー スタイルを使用できます。ユーザーがテキストを変更できない場合は、ボタンのクリック (EDT にある) に応答してテキストをサーバー スレッドに渡し、テキスト ボックスを無効にします。

最後の更新:

クライアント接続が永続的で、サーバーが更新を送信し続ける場合は、リスナー モデルを使用できます。そうでない場合、データの 2 つのコピーは冗長である可能性があります。いずれにせよ、1 つのデータ値をコピーすることを心配するよりも、(セレクターを使用しない限り) より多くのスレッド化作業を行うことになると思います。

たくさんの情報が得られたと思います、頑張ってください。

于 2009-11-07T21:29:34.237 に答える
0

Swing コンポーネントの値を取得するという同じニーズに遭遇しましたが、アプリケーション内の JavaScript エンジンの呼び出しからです。次のユーティリティメソッドをまとめました。

/**
 * Executes the specified {@link Callable} on the EDT thread. If the calling
 * thread is already the EDT thread, this invocation simply delegates to
 * call(), otherwise the callable is placed in Swing's event dispatch queue
 * and the method waits for the result.
 * <p>
 * @param <V> the result type of the {@code callable}
 * @param callable the callable task
 * @return computed result
 * @throws InterruptedException if we're interrupted while waiting for the
 * event dispatching thread to finish executing doRun.run()
 * @throws ExecutionException if the computation threw an exception
 */
public static <V> V getFromEDT(final Callable<V> callable) throws InterruptedException, ExecutionException {
    final RunnableFuture<V> f = new FutureTask<>(callable);

    if (SwingUtilities.isEventDispatchThread()) {
        f.run();
    } else {
        SwingUtilities.invokeLater(f);
    }

    return f.get();
}

これを使用する方法を理解できると確信していますが、Java 8 での使用方法が特に簡単であることを示したいと思います。

String text = <String>getFromEDT(() -> textarea.getText());

編集:安全な公開を行う方法を変更

于 2015-07-01T08:17:51.993 に答える