فريق البرنامج المساعد لتكوين مكونات JavaFX في تطبيق سطح المكتب

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


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


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


قد يكون هذا مستمعًا لمجموعة من الأطفال:


private final ListChangeListener changeListener = (ListChangeListener<Node>) (ListChangeListener.Change<? extends Node> c) -> { if (c.next()) { c.getAddedSubList().forEach(this::applySettingsForNodeAndAddListenerForItsChild); } }; 

سيكون رمز المعالجة لكل عقدة معدلة:


 private void applySettingsForNodeAndAddListenerForItsChild(Node n) { if (!checkApplySettings(n)) { apply(n); ObservableList<Node> children = getChildren(n); if (children != null) { addListnerForUpdateChildren(children); } markNodePropertyApplied(n); } } 

وهذا هو الرمز الذي يطلق على البرنامج المساعد نفسه مباشرة ، والذي يتم تسجيله على هذا النوع من المكونات:


 public Node apply(Node node) { List<SettingsPlugin> settingsPlugins = settingsMap.get(Node.class); if (settingsPlugins != null) { for (SettingsPlugin plugin : settingsPlugins) { node = plugin.apply(node, userSettings.getSettings()); } } List<SettingsPlugin> settingList = settingsMap.get(node.getClass()); if (settingList != null) { for (SettingsPlugin plugin : settingList) { node = plugin.apply(node, userSettings.getSettings()); } } return node; } 

هنا واجهة البرنامج المساعد نفسه:


 public interface SettingsPlugin { public Node apply(Node node, Map<String, Object> userSettings); } 

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


في الآونة الأخيرة ، أرسم تشبيهاً بقدرات المنصات لتطبيقات سطح المكتب والويب. سيكون من المثير للاهتمام معرفة كيف يمكن تنفيذ هذه الوظيفة على أطر مختلفة.

Source: https://habr.com/ru/post/ar422693/


All Articles