سؤال

بلدي الرمز الحالي يبدو وكأنه هذا:

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

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

استخدام صفيف نهائي يبدو وكأنه قليل من الاختراق. هل هناك حل أكثر أناقة؟

لقد فعلت الكثير من البحث، لكنني لا يبدو لي أن أجد أي شيء للقيام بذلك، مما يفاجئني. على الرغم من أنني استمرت في المجيء SwingWorker, ، لكنني لست متأكدا من أن هذا مناسب في هذه الحالة؟

أنا أفترض أن JTextArea.getText() ليس آمنة للخيط.

شكرا.

هل كانت مفيدة؟

المحلول

يمكن حل جميع المشكلات عن طريق إضافة طبقة أخرى من غير مباشر (باستثناء عندما يكون لديك الكثير من الطبقات: 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، لكنك تحصل على الفكرة. ثم تصبح مكالمة Swindutiles الخاصة بك فقط:

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

يمكنك استرداد النص المحفوظ من كائن Savehere الخاص بك.

نصائح أخرى

أجد أنه في 99٪ من رمز البديل الذي أقوم به غالبا إلى jtextarea استجابة لإجراء مستخدم (قام المستخدم بكيت مكتفا، والنقر فوق زر، أغلق نافذة، إلخ). يتم التعامل مع كل هذه الأحداث من خلال مستمعي الأحداث التي يتم تنفيذها دائما على EDT.

هل يمكنك تقديم المزيد من التفاصيل في حالة استخدامك؟

تحديث بناء على حالة الاستخدام: هل يمكن للمستخدم تغيير النص بعد بدء تشغيل الخادم؟ إذا كانت الإجابة بنعم، فيمكنك استخدام نمط المستمع المذكور سابقا. تأكد من أن تكون حذرا مع التزامن الخاص بك. إذا لم يتمكن المستخدم من تغيير النص، فقم بتمرير النص إلى مؤشر ترابط الخادم استجابة للزر النقر (والذي سيكون على EDT) وتعطيل مربع النص.

اخر تحديث:

إذا كانت اتصالات العميل مستمرة وتستمر الخادم في إرسال التحديثات التي يمكنك استخدامها نموذج المستمع. إذا لم يكن الأمر كذلك، فقد يكون نسختين من البيانات زائدة عن الحاجة. في كلتا الحالتين، أعتقد أنك سوف تنتهي بمزيد من عمل الخيوط (ما لم تستخدم المختارين) على يدك من القلق بشأن نسخ قيمة بيانات واحدة.

أعتقد أنك حصلت على عدد كبير من المعلومات الآن، حظا سعيدا.

واجهت نفس الحاجة، للحصول على قيمة مكون التأرجح، ولكن من مكالمات محرك جافا سكريبت داخل طلبي. صفعت معا طريقة الأداة المساعدة التالية.

/**
 * 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());

يحرر: تغيير الطريقة للقيام بها منشور آمن

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top