باستخدام وضع خيوط Swingworker
من المهم جدًا أن يستخدم مطورو التأرجح التزامن بعناية. يستخدم برنامج التأرجح الجيد آليات التزامن لإنشاء واجهات المستخدم التي لا تفقد الاستجابة - بغض النظر عن نوع تفاعل المستخدم ، يمكن للبرنامج دائمًا الاستجابة له. لإنشاء برنامج سريع الاستجابة ، يجب على المطورين تعلم كيفية استخدام MultiThreading في إطار التأرجح.
سوف يتعامل مطور التأرجح مع الأنواع التالية من المواضيع:
(1) مؤشرات الترابط الأولية ، ستنفذ هذه المواضيع رمز تطبيق التهيئة.
(2) مؤشر ترابط إرسال الحدث ، يتم تنفيذ جميع رموز معالجة الأحداث هنا. يجب أن تنفذ معظم التعليمات البرمجية التي تتفاعل مع إطار التأرجح هذا الموضوع أيضًا.
(3) سلاسل العمال ، المعروفة أيضًا باسم خيوط الخلفية ، ستقوم بجميع المهام التي تستغرق وقتًا طويلاً.
لا يحتاج المطورون إلى إنشاء هذه المواضيع بشكل صريح في الكود الخاص بهم: يتم توفيرها بواسطة وقت التشغيل أو إطار العمل. تتمثل مهمة المطورين في استخدام هذه المواضيع لإنشاء برامج تأرجح مستجيبة ومستمرة.
مثل جميع البرامج الأخرى التي تعمل على منصات Java ، يمكن لبرنامج التأرجح إنشاء مؤشرات ترابط إضافية ومجمعات خيوط ، والتي تتطلب استخدام النهج الذي سيتم تقديمه في هذه المقالة. هذه المقالة ستقدم المواضيع الثلاثة أعلاه. ستشمل مناقشة سلسلة مواضيع العمال استخدام فئة Javax.swing.swingworker. تحتوي هذه الفئة على العديد من الميزات المفيدة ، بما في ذلك التواصل والتعاون بين مهام مؤشر ترابط العمال ومهام مؤشرات الترابط الأخرى.
1. الموضوع الأولي
يقوم كل برنامج بإنشاء سلسلة من المواضيع في بداية منطق التطبيق. في برنامج قياسي ، لا يوجد سوى مؤشر ترابط واحد: سيتصل هذا الموضوع بالطريقة الرئيسية في الفصل الرئيسي للبرنامج. في التطبيق ، يكون مؤشر الترابط الأولي مُنشئًا لكائن Applet ، والذي سيطلق على طريقة init ؛ قد يتم تنفيذ هذه الإجراءات في مؤشر ترابط واحد ، أو في مؤشرات ترابط مختلفة أو ثلاثة ، كل ذلك يعتمد على التنفيذ المحدد لمنصة Java. في هذه المقالة ، نسمي هذا النوع من مؤشرات الترابط الأولية.
في برنامج التأرجح ، لا يوجد الكثير مما يجب القيام به في الخيط الأولي. تتمثل مهمتهم الأساسية في إنشاء كائن قابل للتشغيل يقوم بتهيئة واجهة المستخدم الرسومية ويقوم بتنظيم الكائنات المستخدمة لتنفيذ الأحداث في مؤشر ترابط إرسال الحدث. بمجرد إنشاء واجهة المستخدم الرسومية ، سيتم تشغيل البرنامج بشكل أساسي بواسطة أحداث واجهة المستخدم الرسومية ، كل منها سيؤدي إلى تنفيذ حدث في سلسلة إرسال الحدث. يمكن أن يقوم رمز البرنامج بتنظيم مهام إضافية للمواضيع التي تعتمد على الأحداث (شريطة تنفيذها بسرعة حتى لا تتداخل مع معالجة الأحداث) أو إنشاء مؤشرات ترابط العمال (تستخدم لأداء المهام المستهلكة للوقت).
تتمثل مهمة إنشاء واجهة المستخدم الرسومية الأولية لتنسيق واجهة المستخدم الرسومية عن طريق الاتصال بـ javax.swing.swingutilities.invokelater أو javax.swing.swingutilities.invokeandwait. تأخذ كلتا الطريقتين معلمة فريدة: يتم استخدام Runnable لتحديد مهام جديدة. الفرق الوحيد بينهما هو: invokerlater فقط ينظم المهمة والعودة ؛ سوف تنتظر InvokeAndWait حتى يتم تنفيذ المهمة قبل العودة.
انظر المثال التالي:
swingutability.invokelater (new RunNable ()) {public void run () {createAndShowGui () ؛ }} في Applet ، يجب وضع مهمة إنشاء واجهة المستخدم الرسومية في طريقة init واستخدام InvokeAndWait ؛ خلاف ذلك ، ستكون العملية الأولية ممكنة قبل إنشاء واجهة المستخدم الرسومية ، مما قد يسبب مشاكل. في حالات أخرى ، عادة ما تكون مهام إنشاء واجهة المستخدم الرسومية الأولية هي الأخيرة في الخيط الأولي الذي يتم تنفيذه ، لذلك يستخدم كلاهما Invokelater أو InvokeAndWait.
لماذا لا يقوم الخيط الأولي بإنشاء واجهة المستخدم الرسومية مباشرة؟ لأنه يجب تنفيذ جميع التعليمات البرمجية المستخدمة لإنشاء وتفاعل مع مكونات التأرجح في مؤشر ترابط إرسال الحدث. سيتم مناقشة هذا القيد أدناه.
2. موضوع توزيع الأحداث
يتم تنفيذ رمز المعالجة لحدث الأرجوحة في مؤشر ترابط خاص ، والذي يسمى موضوع إرسال الحدث. يتم تنفيذ معظم التعليمات البرمجية التي تستدعي طريقة التأرجح في هذا الموضوع. هذا ضروري لأن معظم الأشياء المتأرجحة هي "غير آمنة للرواية".
يمكنك التفكير في تنفيذ التعليمات البرمجية على أنها تنفيذ سلسلة من المهام القصيرة في مؤشر ترابط إرسال الحدث. تسمى معظم المهام بطرق معالجة الأحداث ، مثل ActionListener.ActionPerformed. سيتم تنظيم المهام المتبقية بواسطة رمز البرنامج ، باستخدام Invokelater أو InvokeAndWait. يجب أن تكون المهام في سلسلة إرسال الحدث قادرة على تنفيذها بسرعة. خلاف ذلك ، سيتم تراكم الأحداث غير المجهزة وستصبح واجهة المستخدم "استجابة".
إذا كنت بحاجة إلى تحديد ما إذا كان يتم تنفيذ رمزك في مؤشر ترابط الإرسال ، فاستدعاء javax.swing.swingutilities.iseventDispatchThread.
3. خيوط العمال ورجال الأرجوحة
عندما يحتاج برنامج التأرجح إلى أداء مهمة طويلة ، عادة ما يتم ذلك باستخدام مؤشر ترابط العامل. يتم تنفيذ كل مهمة في مؤشر ترابط عامل ، وهو مثيل لفئة Javax.swing.swingworker. فئة Swingworker هي فئة مجردة. يجب عليك تحديد فئاتها الفرعية لإنشاء كائن Swingworker ؛ عادة ما استخدم فئات داخلية مجهولة للقيام بذلك.
يوفر Swingworker بعض ميزات الاتصال والتحكم:
(1) يمكن للفئة الفرعية من Swingworker تحديد طريقة ، تم. عند اكتمال مهمة الخلفية ، سيتم تسميتها تلقائيًا بواسطة مؤشر ترابط إرسال الحدث.
(2) فئة Swingworker تنفذ java.util.concurrent.future. تتيح هذه الواجهة مهام الخلفية لتوفير قيمة إرجاع إلى مؤشرات الترابط الأخرى. توفر الطرق في هذه الواجهة أيضًا الوظائف التي تسمح بالتراجع عن مهام الخلفية وتحديد ما إذا كانت مهام الخلفية قد اكتملت أو إلغاء.
(3) يمكن أن توفر مهام الخلفية نتائج وسيطة عن طريق استدعاء Swingworker.publish ، وسيقوم مؤشر ترابط إرسال الحدث بهذه الطريقة.
(4) يمكن لمهام الخلفية تحديد خصائص الربط. ستؤدي التغييرات في سمة الربط إلى إحداث أحداث ، وسيقوم مؤشر ترابط إرسال الحدث باستدعاء معالج الحدث للتعامل مع هذه الأحداث التي تم تشغيلها.
4. مهام الخلفية البسيطة
فيما يلي مثال ، هذه المهمة بسيطة للغاية ، لكنها مهمة تستغرق وقتًا طويلاً. TumbleTem Applet يستورد سلسلة من ملفات الصور. إذا تم استيراد ملفات الصور هذه من خلال الخيط الأولي ، فسيكون هناك تأخير قبل ظهور واجهة المستخدم الرسومية. إذا تم استيراد ملفات الصور هذه في مؤشر ترابط إرسال الحدث ، فقد يفشل واجهة المستخدم الرسومية مؤقتًا في الاستجابة.
لحل هذه المشكلات ، تقوم فئة TumbleTem بإنشاء وتنفيذ مثيل لفئة Stringworker عند تهيئته. يتم تنفيذ طريقة doinbackground لهذا الكائن في مؤشر ترابط العامل ، ويستورد الصورة إلى صفيف صورة ، وإرجاع إشارة إليه. ثم يتم تنفيذ الطريقة التي تم إجراؤها في مؤشر ترابط إرسال الحدث ، واحصل على المرجع الذي تم إرجاعه ، ووضعه في IMGs المتغير العضو لفئة Applet. يسمح القيام بذلك لفئة TumbleTem بإنشاء واجهة المستخدم الرسومية على الفور دون الحاجة إلى انتظار استيراد الصورة لإكماله.
يحدد رمز العينة التالي وينفذ كائن Swingworker.
Swingworker Worker = New Swingworker <imageicon [] ، void> () {Override Public ImageIcon [] doInbackground () {Final ImageIcon [] innerimgs = new imageicon [nimgs] ؛ لـ (int i = 0 ؛ i <nimgs ؛ i ++) {innerimgs [i] = loadImage (i+1) ؛ } إرجاع innerimgs ؛ } Override public void done () {// قم بإزالة ملصق "Loading Images". الرسوم المتحركة. removeall () ؛ loopslot = -1 ؛ حاول {imgs = get () ؛ } catch (interruptedException تجاهل) {} catch (java.util.concurrent.executionException e) {string why = null ؛ السبب القابل للتسمية = e.getCause () ؛ if (cause! = null) {لماذا = cause.getMessage () ؛ } آخر {لماذا = e.getMessage () ؛ } system.err.println ("خطأ استرداد خطأ:" + لماذا) ؛ }}}} ؛ يجب على جميع الفئات الفرعية الموروثة من Swingworker تنفيذ Doinbackground ؛ تنفيذ الطريقة التي تم القيام بها اختياري.
لاحظ أن Swingworker هو فئة نموذجية مع معلمتين. تحدد معلمة النوع الأول نوع الإرجاع من Doinbackground. إنه أيضًا نوع من طريقة GET ، والتي يمكن استدعاؤها بواسطة مؤشرات ترابط أخرى للحصول على قيمة الإرجاع من DoInbackground. تحدد معلمة النوع الثاني نوع النتيجة الوسيطة. هذا المثال لا يعيد النتيجة الوسيطة ، لذلك يتم تعيينه على الفراغ.
باستخدام طريقة GET ، يمكنك استخدام المرجع إلى الكائن IMGs (تم إنشاؤه في مؤشر ترابط العامل) في مؤشر ترابط إرسال الحدث. هذا يسمح بمشاركة الكائنات بين المواضيع.
هناك بالفعل طريقتان لإرجاع الكائن بواسطة فئة Doinbackground.
(1) لا توجد معلمات لاستدعاء swingworker.get. إذا لم يتم إكمال مهمة الخلفية ، فسيتم حظر طريقة GET حتى تكمل.
(2) استدعاء swingworker.get مع المعلمات لتحديد المهلة. إذا لم يتم إكمال مهمة الخلفية ، فقم بحظرها حتى تكتمل - ما لم تنتهي مهلة المهلة ، وفي هذه الحالة ، سيلقي GET java.util.concurrent.timeoutexception.
5. المهام ذات النتائج الوسيطة
من المفيد أن توفر مهمة عمل خلفية عمل نتائج وسيطة. يمكن لمهام الواجهة الخلفية استدعاء طريقة swingworker.publish للقيام بذلك. هذه الطريقة تقبل العديد من المعلمات. يجب أن تكون كل معلمة محددة بواسطة معلمة النوع الثاني من Swingworker.
يمكن تجاوز Swingworker.Process لحفظ النتائج التي توفرها طريقة النشر. تسمى هذه الطريقة من خلال موضوع إرسال الحدث. عادة ما يتم جمع مجموعة النتائج من طريقة النشر بواسطة طريقة العملية.
دعنا نلقي نظرة على الأمثلة التي توفرها filpper.java. يولد هذا البرنامج سلسلة من الاختبارات المنطقية العشوائية java.util.random من خلال مهمة خلفية. إنها مثل تجربة رمي العملة المعدنية. للإبلاغ عن نتائجها ، تستخدم مهمة الخلفية كائن Flippair.
فئة ثابتة فئة FLIPPAIR {برؤوس طويلة نهائية ، إجمالي ؛ flippair (رؤوس طويلة ، إجمالي طويل) {this.heads = heads ؛ this.total = المجموع ؛ }} الرؤوس تمثل نتيجة حقيقية. يمثل المجموع إجمالي عدد الرميات.
برنامج الخلفية هو مثيل لـ Filptask:
Fliptask من الفئة الخاصة يمتد Swingworker <void ، flippair> {
نظرًا لأن المهمة لا تُرجع النتيجة النهائية ، فليس هناك حاجة لتحديد المعلمة النوع الأول ، استخدم void. بعد كل "رمي" ، تنشر مكالمات المهمة:
OverRideProtected void doinbackground () {long heads = 0 ؛ إجمالي طويل = 0 ؛ عشوائي عشوائي = جديد عشوائي () ؛ بينما (! iScancelled ()) {Total ++ ؛ if (random.nextBoolean ()) {heads ++ ؛ } publish (New Flippair (Heads ، Total)) ؛ } إرجاع فارغ ؛} منذ أن تسمى النشر غالبًا ، سيتم جمع العديد من قيم Flippair قبل أن تسمى طريقة العملية بواسطة مؤشر ترابط الإرسال ؛ تركز العملية فقط على المجموعة الأخيرة من القيم التي يتم إرجاعها في كل مرة ، وتستخدمها لتحديث واجهة المستخدم الرسومية:
عملية void المحمية (قائمة الأزواج) {flippair pair = pairs.get (pairs.size () - 1) ؛ HeadStext.settext (string.format ("٪ d" ، pair.heads)) ؛ TotalText.settext (string.format ("٪ d" ، pair.total)) ؛ devtext.settext (string.format ("٪. 6. إلغاء مهمة الخلفية
استدعاء Swingworker.cancel لإلغاء مهمة خلفية تنفيذ. يجب أن تكون المهمة متسقة مع آلية التراجع الخاصة بها. هناك طريقتان للقيام بذلك:
(1) عند استلام المقاطعة ، سيتم إنهاءها.
(2) استدعاء Swingworker.iscanceled. إذا استدعاء Swingworker إلغاء ، فسيتم إرجاع الطريقة بشكل صحيح.
7. ربط السمات وطرق الحالة
يدعم Swingworker الخصائص المربوطة ، والتي تكون مفيدة للغاية عند التواصل مع مؤشرات الترابط الأخرى. يوفر خصائص ملزمة: التقدم والدولة. يمكن استخدام التقدم والدولة لتحريك مهام معالجة الأحداث في مؤشرات ترابط الإرسال.
من خلال تنفيذ مستمع تغيير الممتلكات ، يمكن للبرنامج إجراء تغييرات في التقدم أو الحالة أو خصائص الربط الأخرى.
7.1 المتغير المرتبط بالتقدم
متغير ربط التقدم هو متغير عدد صحيح مع نطاق من 0 إلى 100. لقد حدد مسبقًا أساليب Setter (Switchworker.setProgress المحمية) و Getter (The Publicworker.getProgress).
7.2 المتغير المربوطة بالدولة
تعكس التغييرات في متغيرات ربط الحالة عملية تغيير كائن Swingworker خلال دورة حياته. يحتوي هذا المتغير على نوع تعداد من Workworker.StateValue. القيم الممكنة هي:
(1) معلق
تستمر هذه الحالة لفترة من الوقت لمعرفة من إنشاء الكائن الذي تسمى طريقة doinbackground.
(2) بدأ
تستمر هذه الحالة للحظة قبل استدعاء طريقة doinbackground حتى يتم استدعاء الطريقة التي تم القيام بها.
(3) تم
سيبقى الوقت المتبقي الكائن في هذه الحالة.
إذا كنت بحاجة إلى إرجاع قيمة الحالة الحالية ، فيمكنك استدعاء Swingworker.getState.
7.3status طرق
يمكن لطريقتان توفرهما الواجهة المستقبلية أيضًا الإبلاغ عن حالة مهام الخلفية. إذا تم إلغاء المهمة ، فإن عودة iscancelled true. علاوة على ذلك ، إذا تم الانتهاء من المهمة ، أي إما أن يتم إكمالها بشكل طبيعي أو تم إلغاؤها ، فإن iSdone يعيد صحيحًا.
باستخدام حاوية المستوى الأعلى
يوفر Swing 3 فئات الحاويات ذات المستوى الأعلى: JFrame ، Jdialog ، Japplet. عند استخدام هذه الفئات الثلاث ، يجب أن تنتبه إلى النقاط التالية:
(1). من أجل عرضه على الشاشة ، يجب أن يكون كل مكون واجهة المستخدم الرسومية جزءًا من التسلسل الهرمي المحتوي. التسلسل الهرمي للتضمين هو بنية شجرة للمكون ، والحاوية ذات المستوى الأعلى هي جذرها.
(2). لا يمكن تضمين كل مكون واجهة المستخدم الرسومية إلا مرة واحدة. إذا كان المكون موجودًا بالفعل في حاوية ثم يحاول إضافته إلى حاوية جديدة ، فسيتم إزالة المكون من الحاوية الأولى وإضافته إلى الحاوية الثانية.
(3). يحتوي كل حاوية من المستوى الأعلى على جزء محتوى. بشكل عام ، ستحتوي لوحة المحتوى هذه (بشكل مباشر أو غير مباشر) على جميع المكونات البصرية ل Gui من المستوى الأعلى.
(4). يمكنك إضافة شريط قائمة إلى الحاوية العلوية. عادةً ما يتم وضع شريط القائمة هذا في الحاوية العليا ، ولكن خارج لوحة المحتوى.
1. الحاويات ذات المستوى الأعلى والتسلسلات الهرمية للتضمين
يحتوي كل برنامج يستخدم مكون التأرجح على حاوية واحدة على الأقل من المستوى الأعلى. هذه الحاوية ذات المستوى الأعلى هي العقدة الجذرية التي تحتوي على التسلسل الهرمي-سيحتوي هذا التسلسل الهرمي على جميع مكونات التأرجح التي ستظهر في هذه الحاوية ذات المستوى الأعلى.
عادةً ما يكون للتطبيق المنفصل المستند إلى واجهة المستخدم الرسومية Swing Swing التسلسل الهرمي على الأقل ، وعقدة الجذر الخاصة به هي JFRAME. على سبيل المثال ، إذا كان للتطبيق نافذة واحدة وصناديق حوار ، فسيحتوي التطبيق على ثلاثة مستويات إدراج ، أي سيكون هناك ثلاث حاويات ذات مستوى أعلى. يأخذ التسلسل الهرمي للاحتواء JFrame كعقدة الجذر الخاصة به ، واثنين من التسلسلات الهرمية الأخرى للاحتواء لها JDialog كعقدة الجذر.
يحتوي التطبيق القائم على مكونات التأرجح على التسلسل الهرمي على الأقل لإدراج واحد ، ويمكن تحديد أنه يجب إجراء أحدها مع japplet كعقدة الجذر الخاصة به. على سبيل المثال ، التطبيق مع مربع حوار ، سيكون له مستويين إدراجين. سيتم وضع المكون في نافذة المتصفح في التسلسل الهرمي للاحتواء ، وعقدة الجذر الخاصة به هي كائن Japplet. سيكون لمربع الحوار تسلسل هرمي يحتوي على ، وعقدة الجذر الخاصة به هي كائن JDialog.
2. إضافة مكونات إلى لوحة المحتوى
تتمثل عملية الكود التالية في الحصول على لوحة محتوى الإطار في المثال أعلاه وإضافة تسمية صفراء:
frame.getContentPane (). add (YellowLabel ، BorderLayout.Center) ؛
كما هو موضح في الكود ، يجب عليك أولاً العثور على لوحة المحتوى الخاصة بالحاوية ذات المستوى الأعلى وتنفيذها من خلال طريقة getContentPane. لوحة المحتوى الافتراضية هي حاوية وسيطة بسيطة ، ترث من JComponent ، باستخدام BorderLayout كمدير للوحة.
تخصيص لوحة المحتوى أمر بسيط - قم بإعداد مدير لوحة أو إضافة حدود. تجدر الإشارة هنا إلى أن طريقة getContentPane ستعيد كائن حاوية ، وليس كائن JComponent. هذا يعني أنه إذا كنت بحاجة إلى الاستفادة من بعض وظائف JComponent ، فيجب عليك أيضًا كتابة تحويل قيمة الإرجاع أو إنشاء مكونك الخاص كوحة المحتوى. مثالنا عادة ما يستخدم الطريقة الثانية. لأن الطريقة الثانية أكثر وضوحا وأكثر وضوحا. هناك طريقة أخرى نستخدمها أحيانًا وهي ببساطة إضافة مكون محدد ذاتيًا إلى لوحة المحتوى لتغطية لوحة المحتوى بالكامل.
إذا قمت بإنشاء لوحة المحتوى الخاصة بك ، فاحرص على التأكد من أنها غير شفافة. سيكون jpanel غير شفاف خيارًا جيدًا. لاحظ أنه بشكل افتراضي ، تتم إدارة تخطيط JPanel باعتباره FlowLayout ، وقد ترغب في استبداله بمدير تخطيط آخر.
لكي يكون المكون لوحة محتوى ، تحتاج إلى استخدام طريقة setContentPane في الحاوية ذات المستوى الأعلى ، على سبيل المثال:
// قم بإنشاء لوحة وإضافة مكونات إلى it.jpanel contentPane = new jpanel (new BorderLayout ()) ؛ contentPane.setBorder (someBorder) ؛ contentPane.add (somecomponent ، borderlayout.center) pane.//contentpane.setopaque(true) ؛ toplevelcontainer.setContentPane(contentpane) ؛
ملاحظة: لا تستخدم حاويات شفافة كوحدات محتوى ، مثل JScrollpane و JSplitPane و JTabbedPane. سوف تتسبب لوحة المحتوى الشفافة في الخلط بين المكونات. على الرغم من أنه يمكنك جعل أي مكون مترجح شفاف غير شفاف من خلال طريقة setopaque (الحقيقية) ، إلا أنه لن يبدو صحيحًا عندما يتم تعيين بعض المكونات لتكون غير شفافة تمامًا. على سبيل المثال ، لوحة علامة.
3. إضافة شريط قائمة
من الناحية النظرية ، يمكن أن تحتوي كل حاوية من المستوى الأعلى على شريط قائمة. لكن الحقائق تبين أن شريط القائمة يظهر فقط في الإطار أو التطبيق. لإضافة شريط قائمة إلى الحاوية ذات المستوى الأعلى ، تحتاج إلى إنشاء كائن JMenubar ، وتجميع بعض القوائم ، ثم اتصل بالطريقة setjmenubar. يضيف مثيل Topleveldemo شريط قائمة إلى إطاره من خلال الكود التالي.
frame.setjmenubar (cyanmenubar) ؛
4. جزء الجذر
تعتمد كل حاوية من المستوى الأعلى على حاوية وسيطة ضمنية تسمى حاوية الجذر. تدير حاوية الجذر هذه لوحة المحتوى وشريط القائمة ، جنبًا إلى جنب مع حاوية أخرى أو أكثر (انظر جزء الطبقات ، وما إلى ذلك). لا تحتاج عادة إلى معرفة استخدام حاوية جذر المكون المتأرجح. ومع ذلك ، إذا كنت ترغب في اعتراض انقر فوق الماوس أو الرسم على مكونات متعددة ، فأنت بحاجة إلى معرفة حاوية الجذر.
تم وصف ما ورد أعلاه حول لوحة المحتوى وشريط القائمة الاختياري ، ولن يتكرر هنا. المكونان الآخران الموجودان في حاوية الجذر هما لوحة التصميم واللوحة الزجاجية. تحتوي لوحة التصميم مباشرة على لوحة القائمة ولوحة المحتوى ، وتسمح لك بفرز المكونات الأخرى التي تمت إضافتها بواسطة إحداثيات Z. عادةً ما تستخدم الألواح الزجاجية لاعتراض إجراءات الإدخال التي تحدث في الطبقة العليا ويمكن أيضًا استخدامها للرسم على مكونات متعددة.