سؤال

قرأت أن جميع الكود الذي يبني مكونات التأرجح والمقابض يجب أن يتم تشغيله بواسطة مؤشر ترابط إرسال الحدث. أفهم كيف يتم تحقيق ذلك باستخدام SwingUtilities.invokeLater() طريقة. النظر في الرمز التالي حيث يتم تهيئة واجهة المستخدم الرسومية في main الطريقة نفسها

public class GridBagLayoutTester extends JPanel implements ActionListener {   
    public GridBagLayoutTester() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        JButton button = new JButton("Testing");
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        button.addActionListener(this);
        add(button, gbc);
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("event handler code");
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("GridBagLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new GridBagLayoutTester(), BorderLayout.CENTER);
        frame.setSize(800, 600);
        frame.pack();
        frame.setVisible(true);
        System.out.println("Exiting");
    }   
}

كيف يعمل هذا الرمز بشكل مثالي؟ نحن ننشأ JFrame والاتصال بمجموعة من الأساليب الأخرى في الموضوع الرئيسي. أنا لا أفهم أين يأتي EDT بالضبط إلى الصورة هنا (ما هو الكود الذي تنفذه؟). مُنشئ GridBagLayoutTester يتم استدعاء الفصل أيضًا من main الطريقة التي تعني أن EDT لا يقوم بتشغيله.

بالمختصر

  1. متى يتم بدء EDT؟ (هل يبدأ JVM EDT مع الطريقة الرئيسية إذا تم بدء تشغيل EDT أثناء تشغيل هذا الرمز؟)
  2. هل رمز معالج الحدث للزر يتم تشغيله على EDT؟
هل كانت مفيدة؟

المحلول

يعمل الرمز تمامًا لأنك تقوم ببناء الإطار في الخيط الرئيسي ، قبل أن تتاح EDT فرصة التفاعل معه. من الناحية الفنية ، يجب ألا تفعل هذا على الإطلاق ، ولكن من الناحية الفنية يمكنك في ظل هذا الظرف المحدد لأنه لا يمكنك التفاعل مع JFrame حتى يصبح مرئيًا.

النقطة الرئيسية التي يجب معرفتها هي أن مكونات التأرجح ليست آمنة. هذا يعني أنه لا يمكن تعديلها من أكثر من موضوع واحد في نفس الوقت. يتم حل هذا من خلال التأكد من أن جميع التعديلات تأتي من EDT.

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

يتم تشغيل EDT تلقائيًا ويتم ربطه عن كثب في تنفيذ النظام. يتم التعامل معه بشكل جيد داخل JVM. عادةً ما يرتبط بخيط واحد في نظام Windowing الذي يتولى تفاعل المستخدم. بالطبع ، هذا يعتمد تمامًا على التنفيذ. الشيء الجميل هو أنه لا داعي للقلق بشأن هذا. عليك فقط أن تعرف - إذا كنت تتفاعل مع أي مكونات التأرجح ، فقم بذلك على EDT.

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

فيما يلي مقتطفان من التعليمات البرمجية التي أستخدمها بشكل متكرر عند كتابة البرمجة المتأرجحة التي تتعامل مع EDT:

void executeOffEDT() {
  if (SwingUtilities.isEventDispatchThread()) {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        OutsideClass.this.executeOffEDTInternal();
      }
    };
    new Thread(r).start();
  } else {
    this.executeOffEDTInternal();
  }
}

void executeOnEDT() {
  if (SwingUtilities.isEventDispatchThread()) {
    this.executeOnEDTInternal();
  } else {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        OutsideClass.this.executeOnEDTInternal();
      }
    };
    SwingUtilities.invokeLater(r);
  }
}

نصائح أخرى

يتم استدعاء مؤشر ترابط الإرسال ، كما يوحي الاسم ، بواسطة Swing في كل مرة يحتاج فيها الحدث إلى معالجة الحدث.

في المثال الذي قدمته ، سيقوم زر "الاختبار" تلقائيًا باستدعاء طريقة ActionPerformed عندما يحتاج حدث الإجراء إلى معالجة. لذلك ، سيتم استدعاء محتوى طريقة ActionPerformed بواسطة مؤشر ترابط إرسال الحدث.

للإجابة على سؤالك النهائي:

  • يتم تشغيل EDT تلقائيًا عند تحميل إطار العمل. ليس عليك أن تهتم ببدء هذا الموضوع ، فإن JRE يتعامل مع هذه المهمة لك.
  • يتم تشغيل رمز معالج الأحداث بواسطة EDT. يتم تجميع جميع الأحداث التي تنشئها واجهة التأرجح ويكون EDT مسؤولاً عن تنفيذها.

1) لا أعرف إذا كان في new JFrame أو في setVisible لكنه يهيئ عند الطلب وهذا ما لا ينهي نهاية الطريقة الرئيسية (عبر مؤشر ترابط العملية الرئيسية) العملية. تم إطلاق EDT وهو في حلقة محظورة في انتظار الحدث التالي.

2) بالتأكيد. تتلقى هذه الحلقة من OS الحدث ، والعثور على Jbutton وأخبرها أن الحدث قد تم إطلاقه. الزر ثم يتصل بالمستمعين. كل ما يحدث في EDT.

يمكنك مراجعة رمز التأرجح الذي تتصل به عندما تريد قتل العملية (أو إغلاق النافذة الرئيسية) للنظر في المكان الذي يتم فيه إنهاء EDT ... يمكن أن يعطيك فكرة (سأفعل ذلك لاحقًا! :)

تم بدء تشغيل موضوع EDT بعد ذلك أولاً setVisible(true); إذا لم يتم البدء بالفعل ، OFC. أو إذا اتصلت SwingUtilities.invokeAndWait() أو SwingUtilities.invokeLater() طُرق.

نرى http://www.leepoint.net/javabasics/gui/gui-commentary/guicom-main-thread.html

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