2

我当前的代码如下所示:

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

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

最终数组的使用似乎有点小技巧。有没有更优雅的解决方案?

我已经做了很多搜索,但我似乎无法找到任何可以做到这一点的东西,这让我感到惊讶。虽然我不断遇到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

我发现在我 99% 的 Swing 代码中,我经常访问 JTextArea 以响应用户操作(用户已键入、单击按钮、关闭窗口等)。所有这些事件都通过始终在 EDT 上执行的事件侦听器进行处理。

你能在你的用例中提供更多细节吗?

基于用例的更新:用户可以在服务器启动后更改文本吗?如果是,那么您可以使用前面提到的侦听器样式。请务必注意并发性。如果用户无法更改文本,请将文本传递给服务器线程以响应按钮单击(将在 EDT 上)并禁用文本框。

最后更新:

如果客户端连接是持久的并且服务器继续发送更新,您可以使用侦听器模型。如果不是,则数据的两个副本可能是多余的。无论哪种方式,我认为您最终将拥有更多的线程工作(除非您使用选择器),而不是担心复制一个数据值。

我想你现在有很多信息,祝你好运。

于 2009-11-07T21:29:34.237 回答
0

我遇到了同样的需求,即通过调用我的应用程序中的 javascript 引擎来获取 swing 组件的值。我将以下实用方法拍打在一起。

/**
 * 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 回答