شرح الكلاس TreeView في javafx

شرح الكلاس  TreeView

الكلاس TreeView يستخدم لإضافة قائمة شجرية ( Tree ) في واجهة المستخدم.
هذه القائمة تظهر ما بداخلها عند النقر عليه.

المقصود من كلمة شجرية هو أن كل كائن بداخلها يمكنه أيضاً إحتواء عدد غير محدد من الكائنات بداخله, و كل كائن يظهر ما بداخله عند النقر عليه.



مميزات الـ TreeView

  • يضيف Scroll Bar أفقي و عامودي بشكل تلقائي عند الحاجة.

  • إمكانية تعديل القيم مباشرةً عليه مع ضمان أن يكون نوع البيانات المدخل صحيح.

  • توفير أكثر من طريقة لتعديل القيم بشكل مباشر عليه.

  • لا يحتل مساحة كبيرة في النافذة, حيث أنه بإمكان المستخدم النقر على أي عنصر في القائمة ليرى ما بداخله و يمكنه أن ينقر عليه من جديد لإخفاء ما بداخله.

  • يمكن وضع أيقونات للعناصر.



بناء الكلاس TreeView

@DefaultProperty(value="root")
public class TreeView<T>
extends Control
	


طريقة التعامل مع ال TreeView

أول شيء عليك فعله هو إنشاء كائن من الكلاس TreeView لأنك بحاجة له لتحدد المكان الذي ستظهر فيه الـ Tree و لتحدد أيضاً نوع البيانات التي تريد تخزينها بداخله.

في الـ TreeView يمكنك إضافة العدد الذي تريده من الـ TreeItem أو الـ CheckBoxTreeItem.

لجعل أي TreeItem أو CheckBoxTreeItem في الـ TreeView قابل للتعديل يجب استدعاء الدالة setEditable() من كائن الـ TreeView و تمرير القيمة true لها.
بعدها يجب إستدعاء الدالة setCellFactory() و تمرير كائن لها يحدد كيف يمكن تعديل قيمة أي TreeItem أو CheckBoxTreeItem.

في حال أردت وضع أيقونة للـ TreeItem أو للـ CheckBoxTreeItem, يفضل أن يكون حجمها 16×16 بيكسل.



مصطلحات TreeView

المصطلح معناه
Root Node تعني أعلا كائن يظهر في الـ Tree.
Parent Node تعني كائن يحتوي على كائن أو أكثر بداخله, و هو يظهرهم عند النقر عليه.
Leaf Node تعني كائن لا يحتوي على كائن بداخله.

كونستركتورات الكلاس TreeView

الجدول التالي يحتوي على كونستركتورات الكلاس TreeView.

الكونستركتور مع تعريفه
public TreeView() ينشئ كائن من الكلاس TreeView يمثل Tree فارغة.
public TreeView(TreeItem<T> root) ينشئ كائن من الكلاس TreeView يمثل Tree تحتوي على كائنات.
مكان الباراميتر root نضع كائن من إحدى الكلاسات التي تنفذ الإنترفيس TreeNode و الذي بدوره يمثل الـ Root Node للـ Tree.

دوال الكلاس TreeView

الجدول التالي يحتوي على دوال الكلاس TreeView الأكثر إستخداماً.

الدالة مع تعريفها
public final void setTranslateX(double value) تستخدم لتحديد مكان كائن الـ TreeView الذي قام باستدعائها أفقياً.
مكان الباراميتر value نضع رقم يمثل كم Pixel سيتم إزاحته من اليسار إلى اليمين.
public final void setTranslateY(double value) تستخدم لتحديد مكان كائن الـ TreeView الذي قام باستدعائها عامودياً.
مكان الباراميتر value نضع رقم يمثل كم Pixel سيتم إزاحته من الأعلى إلى الأسفل.
public void setPrefSize(double prefWidth, double prefHeight) تستخدم لتحديد حجم كائن الـ TreeView الذي قام باستدعائها.

  • مكان الباراميتر prefWidth نضع رقم يمثل عرض الـ TreeView بالـ Pixel.

  • مكان الباراميتر prefHeight نضع رقم يمثل طول الـ TreeView بالـ Pixel.

public final void setDisable(boolean value) تستخدم لجعل كائن الـ TreeView الذي قام باستدعائها يبدو غير مفعّل, أي يصبح لونه باهتاً و غير قابل للنقر عليه.
مكان الباراميتر value نضع القيمة true لجعله غير مفعّل.
public final void setRoot(TreeItem<T> value) تستخدم لتعيين أول عنصر في كائن الـ TreeView و الذي يقال له Item Root.
مكان الباراميتر value يمكنك تمرير كائن من الكلاس TreeItem أو من الكلاس CheckBoxTreeItem لأنه يرث منه.
public final TreeItem<T> getRoot() تستخدم للحصول على أول عنصر في كائن الـ TreeView و الذي يقال له Item Root.
الكائن الذي ترجعه يمكن عبارة عن كائن من الكلاس TreeItem أو من الكلاس CheckBoxTreeItem لأنه يرث منه.
public final void setEditable(boolean value) تستخدم لجعل المستخدم قادر على تحديث قيم كائن الـ TreeView الذي قام باستدعائها.
مكان الباراميتر value نضع القيمة true لجعله المستخدم قادر على تحديث القيم بداخله.

ملاحظة: تحتاج بعدها أيضاً إلى إستدعاء الدالة setCellFactory() من كائن الـ TreeView لتحدد كيف يستطيع المستخدم تحديث القيم. لا تقلق, شرحنا هذا بتفصيل في الأمثلة.
public final void setStyle(String value) تستخدم لتعديل تصميم كائن الـ TreeView الذي قام بإستدعائها.
مكان الباراميتر value يمكنك تمرير إسم و قيمة أي خاصية تريد تعديلها في كائن الـ TreeView بأسلوب لغة CSS لإظهاره بالشكل الذي تريده.

أمثلة شاملة على الكلاس TreeView


 طريقة إنشاء كائن من الكلاس TreeView

المثال التالي يعلمك طريقة إنشاء كائن من الكلاس TreeView و إضافته في النافذة.

مثال

Main.java
      import javafx.application.Application;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.stage.Stage;

      public class Main extends Application {

      @Override
      public void start(Stage stage) {

      // TreeView في الـ Root Item و الذي سنضعه كـ TreeItem هنا قمنا بإنشاء كائن من الكلاس
      TreeItem<String> rootItem = new TreeItem<> ("Root");

      // كأول عنصر فيها rootItem يمثل القائمة الشجرية التي نريد إضافتها في النافذة و وضعنا فيها الكائن TreeView هنا قمنا بإنشاء كائن من الكلاس
      TreeView<String> treeView = new TreeView<(rootItem);

      // rootItem تحت الكائن TreeItem هنا قمنا بإضافة ثلاث كائنات
      rootItem.getChildren().add(new TreeItem("Item 0"));
      rootItem.getChildren().add(new TreeItem("Item 1"));
      rootItem.getChildren().add(new TreeItem("Item 2"));

      // rootItem الثالث بالنسبة للكائن TreeItem تحت الكائن TreeItem هنا قمنا بإضافة كائنين
      rootItem.getChildren().get(2).getChildren().add(new TreeItem("Item 2-0"));
      rootItem.getChildren().get(2).getChildren().add(new TreeItem("Item 2-1"));

      // في النافذة و جعلنا حجمها يساوي حجم النافذة لأننا لا ننوي إضافة شيء آخر في النافذة treeView هنا قمنا بتحديد حجم الـ
      treeView.setPrefSize(400, 250);

      // في النافذة treeView هنا قمنا بتحديد مكان ظهور الكائن
      treeView.setTranslateX(0);
      treeView.setTranslateY(0);

      // في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
      Group root = new Group();

      // root في الكائن treeView هنا قمنا بإضافة الكائن
      root.getChildren().add(treeView);

      // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
      Scene scene = new Scene(root, 400, 250);

      // هنا وضعنا عنوان للنافذة
      stage.setTitle("JavaFX TreeView");

      // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
      stage.setScene(scene);

      // هنا قمنا بإظهار النافذة
      stage.show();

      }

      // هنا قمنا بتشغيل التطبيق
      public static void main(String[] args) {
      launch(args);
      }

      }
    

ستظهر لك النافذة التالية عند التشغيل.


 طريقة وضع أيقونة للـ TreeView

المثال التالي يعلمك طريقة وضع أيقونة للـ TreeView بالإضافة لجعله مفتوحاً بشكل إفتراضي عند تشغيل التطبيق.

مثال

Main.java
      import javafx.application.Application;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.scene.image.Image;
      import javafx.scene.image.ImageView;
      import javafx.stage.Stage;

      public class Main extends Application {

      // و التي سنقصد بها الشركة Root Item الذي يمثل الـ TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكائن الـ
      public ImageView getRootIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/building-icon.png")));
      }

      // يمثل قسم في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getDepartmentIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/department-icon.png")));
      }

      // يمثل موظف في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getUserMaleIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/user-male-icon.png")));
      }

      // يمثل موظفة في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getUserFemaleIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/user-female-icon.png")));
      }

      @Override
      public void start(Stage stage) {

      // getRootIcon() و مررنا له أيقونة المبنى التي سترجعها الدالة TreeView في الـ Root Item و الذي سنضعه كـ TreeItem هنا قمنا بإنشاء كائن من الكلاس
      TreeItem<String> rootItem = new TreeItem<>("Harmash", getRootIcon());

      // getDepartmentIcon() كل كائن منهم سنجعله يمثل إسم قسم في الشركة و بجانبه أيقونة القسم التي ترجعها الدالة .TreeView هنا قمنا بإنشاء 3 كائنات
      TreeItem dep_1 = new TreeItem("Research & Development", getDepartmentIcon());
      TreeItem dep_2 = new TreeItem("Accounting & Finance", getDepartmentIcon());
      TreeItem dep_3 = new TreeItem("Marketing", getDepartmentIcon());

      // كل كائن منهم سنجعله يمثل إسم موظف/موظفة في الشركة و TreeView هنا قمنا بإنشاء 6 كائنات
      // getUserFemaleIcon() و الدالة getUserMaleIcon() بجانبه أيقونة تمثل جنسه و التي ترجعها
      TreeItem user_1 = new TreeItem("Mhamad Harmush", getUserMaleIcon());
      TreeItem user_2 = new TreeItem("Youssef Jabber", getUserMaleIcon());
      TreeItem user_3 = new TreeItem("Hala Hassan", getUserFemaleIcon());
      TreeItem user_4 = new TreeItem("Rola Masri", getUserFemaleIcon());
      TreeItem user_5 = new TreeItem("Rim Ibrahim", getUserFemaleIcon());
      TreeItem user_6 = new TreeItem("Nader Bakir", getUserMaleIcon());

      // يظهر عند تشغيل البرنامج ( dep_3 و dep_2 و dep_1 أي الكائنات) rootItem موضوع مباشرةً تحت الـ TreeItem هنا جعلنا كل كائن
      rootItem.setExpanded(true);

      // كأول عنصر فيها rootItem يمثل القائمة الشجرية التي نريد إضافتها في النافذة و وضعنا فيها الكائن TreeView هنا قمنا بإنشاء كائن من الكلاس
      TreeView<String> treeView = new TreeView<>(rootItem);

      // الذي يمثل الشركة rootItem التي تمثل أقسام في الشركة تحت الكائن TreeItem هنا قمنا بإضافة كائنات الـ
      rootItem.getChildren().add(dep_1);
      rootItem.getChildren().add(dep_2);
      rootItem.getChildren().add(dep_3);

      // التي تمثل أقسام في الشركة TreeItem التي تمثل موظفين و موظفات تحت كائنات الـ TreeItem هنا قمنا بإضافة كائنات الـ
      dep_1.getChildren().add(user_1);
      dep_1.getChildren().add(user_2);
      dep_1.getChildren().add(user_3);
      dep_2.getChildren().add(user_4);
      dep_2.getChildren().add(user_5);
      dep_3.getChildren().add(user_6);

      // في النافذة treeView هنا قمنا بتحديد حجم الـ
      treeView.setPrefSize(400, 250);

      // في النافذة treeView هنا قمنا بتحديد مكان ظهور الكائن
      treeView.setTranslateX(0);
      treeView.setTranslateY(0);

      // في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
      Group root = new Group();

      // root في الكائن treeView هنا قمنا بإضافة الكائن
      root.getChildren().add(treeView);

      // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
      Scene scene = new Scene(root, 400, 250);

      // هنا وضعنا عنوان للنافذة
      stage.setTitle("JavaFX TreeView");

      // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
      stage.setScene(scene);

      // هنا قمنا بإظهار النافذة
      stage.show();

      }

      // هنا قمنا بتشغيل التطبيق
      public static void main(String[] args) {
      launch(args);
      }

      }
    

ستظهر لك النافذة التالية عند التشغيل.


 طريقة   إضافة و حذف و تعديل بيانات الـ TreeView

المثال التالي يعلمك طريقة جعل المستخدم قادر على إضافة و حذف و تعديل بيانات الـ TreeView بطريقة إحترافية.

مثال

EditableItem.java
      import javafx.event.ActionEvent;
      import javafx.scene.control.ContextMenu;
      import javafx.scene.control.MenuItem;
      import javafx.scene.control.TextField;
      import javafx.scene.control.TreeCell;
      import javafx.scene.control.TreeItem;
      import javafx.scene.image.Image;
      import javafx.scene.image.ImageView;
      import javafx.scene.input.KeyCode;
      import javafx.scene.input.KeyEvent;

      // متطورة TreeItem و بالتالي أصبح إنشاء كائن منه يعني إنشاء TreeCell هنا قمنا بتعريف كلاس يرث من الكلاس
      public class EditableItem extends TreeCell<String> {

      // يمثل قسم في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getDepartmentIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/department-icon.png")));
      }

      // يمثل موظف في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getUserMaleIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/user-male-icon.png")));
      }

      // يمثل موظفة في الشركة TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكل كائن
      public ImageView getUserFemaleIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/user-female-icon.png")));
      }

      // TreeItem في كل مرة يريد فيها المستخدم أن يقوم بتعديل نص TextField لأننا سنظهر textField هنا قمنا بتعريف كائن
      private TextField textField;

      // الذي يمثل الشركة Root Item هنا قمنا بتعريف القائمة التي سنظهرها عندما ينقر المستخدمم بزر الفأرة الأيمن على الـ
      private final ContextMenu menuForRootItem = new ContextMenu();

      // هنا قمنا بتعريف القائمة التي سنظهرها عندما ينقر المستخدمم بزر الفأرة الأيمن على أي قسم موجود في الشركة
      private final ContextMenu menuForAnyDepartment = new ContextMenu();

      // هنا قمنا بتعريف القائمة التي سنظهرها عندما ينقر المستخدمم بزر الفأرة الأيمن على أي مستخدم موجود بداخل قسم
      private final ContextMenu menuForAnyUser = new ContextMenu();

      // الكونستركتور
      public EditableItem() {
      // هنا قمنا بتعريف عناصر القائمة التي تظهر عند النقر بزر الفأرة الأيمن على الشركة
      MenuItem addNewDepartment = new MenuItem("Add new department");
      MenuItem deleteAllDepartments = new MenuItem("Delete all departments");

      // هنا قمنا بتعريف عناصر القائمة التي تظهر عند النقر بزر الفأرة الأيمن على أي قسم
      MenuItem addNewMale = new MenuItem("Add a male employee");
      MenuItem addNewFemale = new MenuItem("Add a female employee");
      MenuItem deleteAllEmployees = new MenuItem("Delete all employees");
      MenuItem deleteDepartment = new MenuItem("Delete department");

      // هنا قمنا بتعريف عنصر القائمة الذي يظهر عند النقر بزر الفأرة الأيمن على أي موظف أو موظفة
      MenuItem deleteUser = new MenuItem("Delete User");

      // فيها menuForRootItem هنا قمنا بإضافة عناصر على القائمة
      menuForRootItem.getItems().addAll(addNewDepartment, deleteAllDepartments);

      // فيها menuForRootDepartment هنا قمنا بإضافة العناصر عناصر القائمة
      menuForAnyDepartment.getItems().addAll(addNewMale, addNewFemale, deleteAllEmployees, deleteDepartment);

      // فيها menuForRootItem هنا قمنا بإضافة عنصر على القائمة
      menuForAnyUser.getItems().addAll(deleteUser);

      // addNewDepartment هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      addNewDepartment.setOnAction((ActionEvent t) -> {
      TreeItem newDepartment = new TreeItem<>("New Department", getDepartmentIcon());
      getTreeItem().getChildren().add(newDepartment);
      newDepartment.setExpanded(true);
      });

      // deleteAllDepartments هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      deleteAllDepartments.setOnAction((ActionEvent t) -> {
      getTreeItem().getChildren().remove(0, getTreeItem().getChildren().size());
      });

      // addNewMale هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      addNewMale.setOnAction((ActionEvent t) -> {
      TreeItem newDepartment = new TreeItem<>("New Employee", getUserMaleIcon());
      getTreeItem().getChildren().add(newDepartment);
      });

      // addNewFemale هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      addNewFemale.setOnAction((ActionEvent t) -> {
      TreeItem newDepartment = new TreeItem<>("New Employee", getUserFemaleIcon());
      getTreeItem().getChildren().add(newDepartment);
      });

      // deleteAllEmployees هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      deleteAllEmployees.setOnAction((ActionEvent t) -> {
      getTreeItem().getChildren().remove(0, getTreeItem().getChildren().size());
      });

      // deleteDepartment هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      deleteDepartment.setOnAction((ActionEvent t) -> {
      getTreeItem().getParent().getChildren().remove(getTreeItem());
      });

      // deleteUser هنا قمنا بتحديد ما سيحدث عند النقر على العنصر
      deleteUser.setOnAction((ActionEvent t) -> {
      getTreeItem().getParent().getChildren().remove(getTreeItem());
      });

      }

      // بداخله بعد TreeItem أو ترجع نص فارغ في حال كان لا يحتوي على EditableItem هنا قمنا بتعريف دالة ترجع نص الـ
      // و هذا يعني أنه في حال كان قد تم إنشاؤه فإننا لن نفقد القيمة الموجودة فيه
      private String getString() {
      return getItem() == null ? "" : getItem();
      }

      // EditableItem عند النقر على الـ TextField هنا قمنا بتعريف الدالة التي تنشئ
      private void createTextField() {
      // getString() فيه و الذي ترجعه الدالة EditableItem و تمرير النص الذي كان ظاهراً على الـ TextField هنا سيتم إنشاء الـ
      textField = new TextField(getString());
      // EditableItem هنا قمنا بفحص كل حرف يدخله المستخدم عند تعديل نص الـ
      textField.setOnKeyReleased((KeyEvent t) -> {
      // سيتم حفظ التعديلات Enter إذا قام المستخدم بالنقر على الزر
      if (t.getCode() == KeyCode.ENTER) {
      commitEdit(textField.getText());
      }
      // سيتم إلغاء التعديلات Esc إذا قام المستخدم بالنقر على الزر
      else if (t.getCode() == KeyCode.ESCAPE) {
      cancelEdit();
      }
      });
      }

      // TextField التي تنشئ createTextField() سيتم إستدعاء الدالة EditableItem هنا قلنا أنه عند تعديل نص الـ
      @Override
      public void startEdit() {
      super.startEdit();
      if (textField == null) {
      createTextField();
      }
      setText(null);
      setGraphic(textField);
      textField.selectAll();
      }

      // سيتم إعادة النص الذي كان موجوداً من  قبل EditableItem هنا قلنا أنه عند إلغاء تعديل نص الـ
      @Override
      public void cancelEdit() {
      super.cancelEdit();
      setText((String) getItem());
      setGraphic(getTreeItem().getGraphic());
      }

      // بأي شكلٍ كان EditableItem هنا قمنا بتحديد ما سيحدث عند محاولة تعديل الـ
      @Override
      public void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);
      // TreeView في حال تم إلغاؤه قلنا أنه سيتم مسحه من الـ
      if (empty) {
      setText(null);
      setGraphic(null);
      }
      // في حال تم التفاعل معه بأي طريقة
      else {
      // مكانه ثم تحديث النافذة لإظهار النص الجديد TextField في حال كان يتم تعديل نصه سيتم وضع النص الذي تم إدخاله في الـ
      if (isEditing()) {
      if (textField != null) {
      textField.setText(getString());
      }
      setText(null);
      setGraphic(textField);
      }
      // في حال تم النقر عليه بواسطة زر الفأرة الأيمن
      else {
      // سيتم تحديث النافذة لضمان أن يتم إظهاره بشكل صحيح
      setText(getString());
      setGraphic(getTreeItem().getGraphic());

      // TreeView ثم سيتم إظهار القائمة الخاصة بالشركة إذا تم النقر على أول شيء في الـ
      if (getTreeItem().getParent() == null) {
      setContextMenu(menuForRootItem);
      }
      // TreeView أو سيتم إظهار القائمة الخاصة بالأقسام إذا تم النقر على أي شيء موضوع تحت الشركة في الـ
      else if( getTreeItem().getParent().getParent() == null) {
      setContextMenu(menuForAnyDepartment);
      }
      // TreeView أو سيتم إظهار القائمة الخاصة بالموظفين و المظفات إذا تم النقر على أي شيء موضوع تحت أي قسم في الـ
      else if( getTreeItem().getParent().getParent().getParent() == null) {
      setContextMenu(menuForAnyUser);
      }
      }
      }
      }

      }

    

Main.java
      import javafx.application.Application;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.scene.image.Image;
      import javafx.scene.image.ImageView;
      import javafx.stage.Stage;

      public class Main extends Application {

      // و التي سنقصد بها الشركة Root Item الذي يمثل الـ TreeItem هنا قمنا بتعريف دالة ترجع الأيقونة التي سنضعها لكائن الـ
      public ImageView getRootIcon() {
      return new ImageView(new Image(getClass().getResourceAsStream("images/building-icon.png")));
      }

      @Override
      public void start(Stage stage) {

      // getRootIcon() و مررنا له أيقونة المبنى التي سترجعها الدالة TreeView في الـ Root Item و الذي سنضعه كـ TreeItem هنا قمنا بإنشاء كائن من الكلاس
      TreeItem<String> rootItem = new TreeItem<>("Root Item", getRootIcon());

      // يمثل القائمة الشجرية التي نريد إضافتها في النافذة TreeView هنا قمنا بإنشاء كائن من الكلاس
      TreeView<String> treeView = new TreeView<>(rootItem);

      // يظهر عند تشغيل البرنامج rootItem موضوع مباشرةً تحت الـ TreeItem هنا جعلنا كل كائن
      rootItem.setExpanded(true);

      // في النافذة listView هنا قمنا بتحديد حجم الـ
      treeView.setPrefSize(400, 250);

      // في النافذة listView هنا قمنا بتحديد مكان ظهور الكائن
      treeView.setTranslateX(0);
      treeView.setTranslateY(0);

      // قابل للتعديل treeView هنا جعلنا محتوى الـ
      treeView.setEditable(true);

      // EditableItem سيتم تعديله سيتم معاملته على أنه كائن من الكلاس treeView هنا قلنا أن أي شيء بداخل الـ
      treeView.setCellFactory( 
      (TreeView<String> p) -> new EditableItem()
      );

      // في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
      Group root = new Group();

      // root في الكائن listView هنا قمنا بإضافة الكائن
      root.getChildren().add(treeView);

      // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
      Scene scene = new Scene(root, 400, 250);

      // هنا وضعنا عنوان للنافذة
      stage.setTitle("JavaFX TreeView");

      // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
      stage.setScene(scene);

      // هنا قمنا بإظهار النافذة
      stage.show();

      }

      // هنا قمنا بتشغيل التطبيق
      public static void main(String[] args) {
      launch(args);
      }

      }
    

ستظهر لك النافذة التالية عند التشغيل.



 طريقة إضافة CheckBoxTreeItem بداخل الـ TreeView

المثال التالي يعلمك طريقة إضافة CheckBoxTreeItem بداخل الـ TreeView.
بالإضافة إلى طريقة معرفة كل CheckBoxTreeItem تم تحديده بداخل الـ TreeView عند النقر على Button.

مثال

Main.java
      import javafx.application.Application;
      import javafx.event.ActionEvent;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.CheckBoxTreeItem;
      import javafx.scene.control.TextArea;
      import javafx.scene.control.TreeView;
      import javafx.scene.control.cell.CheckBoxTreeCell;
      import javafx.stage.Stage;

      public class Main extends Application {

      @Override
      public void start(Stage stage) {

      // هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة
      CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<>("Add Features");
      Button button = new Button("Display Selected");
      TextArea textArea = new TextArea();

      // يمثل القائمة الشجرية التي نريد إضافتها في النافذة TreeView هنا قمنا بإنشاء كائن من الكلاس
      TreeView<String> treeView = new TreeView<>(rootItem);

      // TreeItem و ليس مجموعة CheckBoxTreeCell سنضيف بداخله فيه مجموعة treeView هنا حددنا أن كائن الـ
      treeView.setCellFactory( CheckBoxTreeCell.<String>forTreeView() );

      // rootItem تحت الكائن CheckBoxTreeCell هنا قمنا بإضافة ثلاث كائنات
      rootItem.getChildren().add(new CheckBoxTreeItem<>("Update Automatically"));
      rootItem.getChildren().add(new CheckBoxTreeItem<>("Recieve New Offers"));
      rootItem.getChildren().add(new CheckBoxTreeItem<>("Arabic Language package"));

      // يظهر عند تشغيل البرنامج rootItem موضوع مباشرةً تحت الـ CheckBoxTreeItem هنا جعلنا كل كائن
      rootItem.setExpanded(true);

      // textArea هنا جعلنا المستخدم غير قادر على إدخال نص من لوحة المفاتيح بداخل الـ
      textArea.setEditable(false);

      // هنا قمنا بتحديد حجم الأشياء التي سنضيفها في النافذة
      treeView.setPrefSize(400, 100);
      button.setPrefSize(200, 30);
      textArea.setPrefSize(400, 60);

      // هنا قمنا بتحديد مكان ظهور الأشياء التي سنضيفها في النافذة
      treeView.setTranslateX(0);
      treeView.setTranslateY(0);
      button.setTranslateX(100);
      button.setTranslateY(130);
      textArea.setTranslateX(0);
      textArea.setTranslateY(190);        

      // في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
      Group root = new Group();

      // root هنا قمنا بإضافة جميع الأشياء في الكائن
      root.getChildren().add(treeView);
      root.getChildren().add(button);
      root.getChildren().add(textArea);

      // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
      Scene scene = new Scene(root, 400, 250);

      // هنا وضعنا عنوان للنافذة
      stage.setTitle("JavaFX TreeView");

      // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
      stage.setScene(scene);

      // هنا قمنا بإظهار النافذة
      stage.show();

      // button هنا قمنا بتحديد ما سيحدث عند النقر على الكائن
      button.setOnAction((ActionEvent e) -> {

      // لأننا سنضع فيه نص أي شيء يقوم المستخدم بتحديده. أي بوضع علامة صح عليه String في كل مرة سيتم إنشاء
      String selectedItems = "";

      // selectedItems سيتم إضافة نصه على المتغير rootItem إذا قام المستخدم بوضع بتحديد أول خيار تحت الـ
      if(((CheckBoxTreeItem)rootItem.getChildren().get(0)).isSelected())
      selectedItems += rootItem.getChildren().get(0).getValue() + "\n";

      // selectedItems سيتم إضافة نصه على المتغير rootItem إذا قام المستخدم بوضع بتحديد ثاني خيار تحت الـ
      if(((CheckBoxTreeItem)rootItem.getChildren().get(1)).isSelected())
      selectedItems += rootItem.getChildren().get(1).getValue() + "\n";

      // selectedItems سيتم إضافة نصه على المتغير rootItem إذا قام المستخدم بوضع بتحديد ثالث خيار تحت الـ
      if(((CheckBoxTreeItem)rootItem.getChildren().get(2)).isSelected())
      selectedItems += rootItem.getChildren().get(2).getValue();

      // selectedItems سيتم وضع النص التالي في المتغيرrootItem إذا لم يقم المستخدم بتحديد أي خيار تحت الـ
      if (selectedItems.equals(""))
      selectedItems = "No Feature is Selected!";

      // textArea كنص للكائن selectedItems في الأخير سيتم وضع النص المخزن في المتغير
      textArea.setText(selectedItems);
      });

      }

      // هنا قمنا بتشغيل التطبيق
      public static void main(String[] args) {
      launch(args);
      }

      }
    

ستظهر لك النافذة التالية عند التشغيل.


كورس تعلم javaFX عربي