سؤال

لدي واجهة مستخدم مبنية داخل JFrame. يبدأ أحد الأزرار مكالمة تشغيل طويلة (لا تزال داخل نفس عملية Java)، وخلال تنفيذها، يتم تجميد UI.

أحسب، وجعلها واضحة أن الأمور لا تزال تعمل، يمكنني عرض شريط التقدم، ربما في منبثقة منبثقة، بحيث يمكن إظهار المستخدم محدثا لما يفعله البرنامج.

لذلك أنا أخلق jdialog جديد، مضيفا jprogressbar لذلك، وتحديثه كأشياء تحدث. المشكلة هي أن محتوى الحوار هذا لا يتم تحديثه. التغييرات التي أتيح لها عنوانها على الفور، وأي شيء أخرجه إلى وحدة التحكم، ولكن لا شيء في UI نفسه.

هل هناك أمر يمكنني إصداره لإجبار إعادة رسم؟

إليك جوهر هذا القسم:

  killWindow = new JDialog();
  killWindow.setUndecorated(true);
  killWindow.setTitle("stopping tests - 0 of " + numActive);
  killProgress = new JProgressBar(0, numActive);
  killWindow.add(killProgress);
  killProgress.setStringPainted(true);
  killWindow.pack();
  killWindow.setLocationRelativeTo(frame);
  killWindow.setVisible(true);

ثم، ونحن نقدم ...:

  killProgress.setValue(++killedTests);                    // not seen!
  killProgress.setString("Killing test on " + nickname()); // not seen!
  log("Killed another test, " + killedTests + " so far");  // visible in real time
  killWindow.setTitle("stopping tests - " + killedTests +
                      " of " + killProgress.getMaximum()); // visible in real time

ماذا ينقصني؟ حاولت googling والبحث هنا على ذلك، ولم أر شيئا واضحا؟

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

المحلول

عليك إجراء مهمة التشغيل الطويلة في مؤشر ترابط آخر.

هناك هذا الموضوع يسمى "TOT Event إرسال الموضوع" المسؤول عن تحديث مكونات UI. إذا كان مشغولا في أداء مهمة التشغيل الطويلة متعود تحديث واجهة المستخدم (ولا تحديث لك الحوار).

قد تفكر في استخدام flowudities. أو أ swingworker..

من Swingworker. توثيق ها هي عينة

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
   @Override
   public String doInBackground() {
       return findTheMeaningOfLife();
   }

   @Override
   protected void done() {
       try { 
           label.setText(get());
       } catch (Exception ignore) {
       }
   }
}

(new MeaningOfLifeFinder()).execute();

عن طريق تشغيل مهمتك الطويلة في مؤشر ترابط مختلف، فأنت تسمح ل ToT Event إرسال مؤشر ترابط لإظهار واجهة مستخدم استجابة.

قد نلقي نظرة على هذا "درس من جافا التعليمي"لفهم تحسين هذه المفاهيم.

نصائح أخرى

يبدو أنك قد تقوم بتشغيل مهمتك التشغيلية الطويلة في مؤشر ترابط الأحداث (EDT). ألق نظرة على SwingWorker. إذا كنت تستخدم 1.6 إنه مبني في:

http://java.sun.com/javase/6/docs/api/javax/swing/swingworker.html.

إذا لم يكن الأمر كذلك، يمكنك العثور على مزيد من المعلومات في:

http://en.wikipedia.org/wiki/swingworker.

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