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

شرح الكلاس Pagination

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

الأمر المميز في الـ Pagination أنه يمكنك وضع العدد الذي تريده من الصفحات و سيقوم بترقيم هذه الصفحات بشكل تلقائي لجعل المستخدم قادر على التنقل بين الصفحات بكل سهولة من خلال النقر على رقم الصفحة بدون أن تكتب أي كود لذلك.
بالنسبة لمحتوى هذه الصفحات, يمكنك وضع ما شئت.

بمجرد أن تنشئ كائن من الكلاس Pagination و تضيفه في النافذة, ستحصل على الواجهة التالية.

شرح الكلاس  Pagination


طريقة التعامل مع الكلاس Pagination

لتحديد كيف سيتجزء المحتوى الذي ستعرضه بداخل كائن الـ Pagination على عدة صفحات, يجب أن تفعل Override لدالة إسمها setPageFactory() و تمرر لها كائن يطبق إنترفيس إسمه Callback و يفعل بداخله Override للدالة call() المسؤولة في الواقع عن توليد محتوى الصفحات التي يتم النقر على أرقامها.

لا تقلق أبداً, شرحنا هذا الأمر بتفصيل ممل في الأمثلة.


بناء الكلاس Pagination

@DefaultProperty(value="pages")
public class Pagination
extends Control
	

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

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

الكونستركتور مع تعريفه
public Pagination() ينشئ كائن من الكلاس Pagination يمثل حاوية فيها عدد غير محدد من الصفحات.
public Pagination(int pageCount) ينشئ كائن من الكلاس Pagination يمثل حاوية فيها عدد محدد من الصفحات.
مكان الباراميتر pageCount نضع رقم يحدد عدد الصفحات التي سيتم وضعها بداخل الحاوية.
public Pagination(int pageCount, int pageIndex) ينشئ كائن من الكلاس Pagination يمثل حاوية فيها عدد محدد من الصفحات مع تحديد الصفحة التي ستظهر مفتوحة فيه بشكل إفتراضي عند تشغيل التطبيق.
مكان الباراميتر pageCount نضع رقم يحدد عدد الصفحات التي سيتم وضعها بداخل الحاوية.
مكان الباراميتر pageIndex نضع رقم Index الصفحة التي نريدها أن تظهر مفتوحة بشكل إفتراضي عن تشغيل التطبيق.

ملاحظة: كل صفحة في كائن الـ Pagination يتم إعطاءها رقم Index إبتداءاً من الرقم 0.
إذاً رقم Index الصفحة الاولى برمجياً هو 0 و ليس 1 كما يظهر أمام المستخدم.

دوال الكلاس Pagination

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

الدالة مع تعريفها
public final void setPageCount(int value) تستخدم لتحديد عدد صفحات كائن الـ Pagination الذي قام باستدعائها.
مكان الباراميتر value نضع رقم يحدد عدد صفحاته.
public final int getPageCount() ترجع عدد صحيح يمثل عدد الصفحات الموجودة في كائن الـ Pagination الذي قام باستدعائها.
public final void setCurrentPageIndex(int value) تستخدم لتحديد الصفحة التي نريدها أن تظهر مفتوحة بشكل إفتراضي في كائن الـ Pagination الذي قام باستدعائها عند تشغيل البرنامج.
مكان الباراميتر value نضع رقم Index الصفحة التي نريدها أن تظهر مفتوحة.
تذكر: رقم Index الصفحة الاولى برمجياً هو 0 و ليس 1 كما يظهر أمام المستخدم.
public final int getCurrentPageIndex() ترجع عدد صحيح يمثل رقم Index الصفحة المفتوحة حالياً في كائن الـ Pagination الذي قام باستدعائها.
public final void setPageFactory(Callback<Integer,Node> value) تستخدم لبناء شكل كل صفحة في كائن الـ Pagination الذي قام باستدعائها و لتحديد محتواها أيضاً.
مكان الباراميتر value نضع كائن يفعل Override للإنترفيس Callback يحدد كيف سيتم جلب و عرض محتوى كل صفحة.

ملاحظة: محتوى الصفحة يتم توليده من جديد في كل مرة يتم فيها فتح الصفحة.
public final void setStyle(String value) تستخدم لتعديل تصميم كائت الـ Pagination الذي قام بإستدعائها.
مكان الباراميتر value يمكنك تمرير إسم و قيمة أي خاصية تريد تعديلها في كائن الـ Pagination بأسلوب لغة CSS لإظهاره بالشكل الذي تريده.
public ObservableList<String> getStyleClass() ترجع كائن نوعه ObservableList يحتوي على كلاس الـ CSS المستخدم من قبل كائن الـ Pagination الذي قام بإستدعائها.
هذه الدالة بدورها تتيح لك تغيير كلاس الـ CSS الإفتراضي الذي يستخدمه كائن الـ Pagination من أجل عرضه بشكل مختلف.
public final void setTranslateX(double value) تستخدم لتحديد مكان الـ Pagination الذي قام باستدعائها أفقياً.
مكان الباراميتر value نضع رقم يمثل كم Pixel سيتم إزاحته من اليسار إلى اليمين. public final void setTranslateY(double value) تستخدم لتحديد مكان الـ Pagination الذي قام باستدعائها عامودياً.
مكان الباراميتر value نضع رقم يمثل كم Pixel سيتم إزاحته من الأعلى إلى الأسفل. public void setPrefSize(double prefWidth, double prefHeight) تستخدم لتحديد حجم الـ Pagination الذي قام باستدعائها.
  • مكان الباراميتر prefWidth نضع رقم يمثل عرض الـ Pagination بالـ Pixel.

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

أمثلة شاملة

 طريقة إضافة Pagination

المثال التالي يعلمك طريقة إنشاء كائن من الكلاس Pagination و إضافته في النافذة.
ستتعلم أيضاً كيف تقوم بتغيير لون خلفيته و لون حدوده.


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

Main.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.stage.Stage;
import javafx.scene.layout.AnchorPane;

public class Main extends Application {

    @Override
    public void start(Stage stage) {
        
        // في النافذة Root Node و الذي ننوي جعله الـ AnchorPane هنا قمنا بإنشاء كائن من الكلاس
        AnchorPane root = new AnchorPane();
        
		// root الذي نريد إضافته في الكائن Pagination يمثل الـ Pagination هنا قمنا بإنشاء كائن من الكلاس
        Pagination pagination = new Pagination();
        
		// أبيض و جعلنا لون حدوده رمادي فاتح pagination هنا جعلنا لون خلفية الكائن
        pagination.setStyle("-fx-background-color:white; -fx-border-color: lightgray;");
        
        // من كل الجهات بمقدار 20 بيكسل ( root الذي سيوضع بداخله ( أي الكائن AnchorPane عن كائن الـ pagination هنا قمنا بتحديد مكان بعد الكائن
        AnchorPane.setTopAnchor(pagination, 20.0);
        AnchorPane.setRightAnchor(pagination, 20.0);
        AnchorPane.setLeftAnchor(pagination, 20.0);
        AnchorPane.setBottomAnchor(pagination, 20.0);

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

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

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

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

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

}

		

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

طريقة إضافة Pagination في javafx

 طريقة حساب عدد صفحات الـPagination بشكل تلقائي

المثال التالي يعلمك طريقة وضع VBox بداخل Pagination مع حساب عدد الصفحات بشكل تلقائي.
فعلياً, سنعرض في الـPagination أسماء أنواع الخطوط الموجودة في جهاز المستخدم.


مثال طريقة وضع VBox بداخل Pagination مع حساب عدد الصفحات بشكل تلقائي

Main.java
import java.util.ArrayList;
import java.util.Arrays;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Pagination;
import javafx.stage.Stage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;

public class Main extends Application {
    
    // خصصناه لتخزين عدد العناصر التي نريد إظهارها في كل صفحة itemsPerPage المتغير
    int itemsPerPage = 7;
    
    // getFonts() وضعنا فيه جميع أسماء الخطوط التي سنظهرها في الصفحات و التي حصلنا عليها من الدالة ArrayList عبارة عن dataList الكائن
    ArrayList<String> dataList = getFonts();

    
    // ArrayList هنا قمنا بتعريف دالة ترجع أسماء الخطوط الموجودة على جهاز المستخدم ككائن نوعه
    public ArrayList<String> getFonts()
    {
        return new ArrayList(Arrays.asList(Font.getFamilies().toArray(new String[]{})));
    }


    // بناءاً على عدد أسماء الخطوط التي سنظهرها فيه Pagination هنا قمنا بتعريف دالة ترجع عدد الصفحات التي يجب أن تكون موجودة في الكائن
    public int getNumberOfPages()
    {
        // totalItems في المتغير dataList هنا قمنا بتخزين عدد الخطوط المخزنة في الكائن
        double totalItems = dataList.size();
        
        // الشرطين التاليين يرجعان عدد الصفحات التي يجب إنشائها نسبةً لعدد العناصر التي سيتم وضعها في كل صفحة
        if(totalItems%itemsPerPage == 0)
            return (int)(totalItems/itemsPerPage);
        else
            return (int)(totalItems/itemsPerPage) + 1;
    }
 
    
    // pagination هنا قمنا بإنشاء دالة خاصة لإنشاء و ترتيب محتوى كل صفحة سيتم إضافتها في الكائن
    public VBox createPage(int pageIndex)
    {
        // VBox محتوى كل صفحة سنعرضه بداخل حاوية نوعها
        VBox vBox = new VBox(5);
        
        // dataList إسم الخط التالي الذي يجب أن يتم جلبه من الكائن index سنستخدمه لمعرفة nextItemIndex المتغير
        int nextItemIndex = pageIndex * itemsPerPage;
        
        // لا يساوي بعد عدد العناصر التي نريد وضعها في كل صفحة vBox طالما أن عدد العناصر الموضوعة في الكائن
        while(vBox.getChildren().size() < itemsPerPage) {
            try {
				// و يوضع له كنص dataList و سيتم جلب إسم خط جديد من الكائن Label سيتم إنشاء
                Label label = new Label(dataList.get(nextItemIndex));
                label.setStyle("-fx-padding: 0 0 0 5;");
				
				// حتى يظهر في الصفحة vBox في الكائن label بعدها سيتم إضافة الكائن
                vBox.getChildren().add(label);

                // dataList من أجل جلب إسم الخط التالي من الكائن nextItemIndex هنا قمنا بإضافة 1 على قيمة المتغير
                nextItemIndex++;
            }
            catch(Exception e) {
                break;
            }
        }
        
        // الذي أصبح يحتوي على كل العناصر التي يجب عرضها في الصفحة vBox في الأخير سيتم إرجاع الكائن
        return vBox;
    }
 
    
    @Override
    public void start(Stage stage) {
        
        // في النافذة Root Node و الذي ننوي جعله الـ AnchorPane هنا قمنا بإنشاء كائن من الكلاس
        AnchorPane root = new AnchorPane();
        
        // root الذي نريد إضافته في الكائن Pagination يمثل الـ Pagination هنا قمنا بإنشاء كائن من الكلاس
        Pagination pagination = new Pagination();
        
        // التي سترجع عدد الصفحات التي يجب إنشاءها getNumberOfPages() و مررنا الدالة pagination هنا قمنا بتحديد عدد صفحات الكائن
        pagination.setPageCount(getNumberOfPages());
        
        // حتى تقوم بتوليد محتوى كل صفحة فيه createPage() و مررنا لها الدالة setPageFactory() هنا قمنا باستدعاء الدالة
        pagination.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
        
        // أبيض و جعلنا لون حدوده رمادي فاتح pagination هنا جعلنا لون خلفية الكائن
        pagination.setStyle("-fx-background-color:white; -fx-border-color: lightgray;");
        
        // من كل الجهات بمقدار 20 بيكسل ( root الذي سيوضع بداخله ( أي الكائن AnchorPane عن كائن الـ pagination هنا قمنا بتحديد مكان بعد الكائن
        AnchorPane.setTopAnchor(pagination, 20.0);
        AnchorPane.setRightAnchor(pagination, 20.0);
        AnchorPane.setLeftAnchor(pagination, 20.0);
        AnchorPane.setBottomAnchor(pagination, 20.0);

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

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

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

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

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

}
		

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

طريقة عرض محتوى VBox بداخل Pagination في javafx

 طريقة عرض رسائل بداخل Pagination

المثال التالي يعلمك طريقة وضع كل عنصر في الـ VBox الموضوع في كل صفحة بداخل VBox خاص.
ملاحظة: هذا الأسلوب يستخدم عند توفير خاصية البحث في التطبيق أو عند عرض الرسائل بشكل مرتب على عدة صفحات.


مثال طريقة وضع كل عنصر في الـ VBox الموضوع في كل صفحة بداخل VBox خاص.

Main.java
import java.util.ArrayList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.Pagination;
import javafx.stage.Stage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;

public class Main extends Application {
	
	// خصصناه لتخزين عدد العناصر التي نريد إظهارها في كل صفحة itemsPerPage المتغير
    int itemsPerPage = 3;
	
	// getSearchResult() وضعنا فيه جميع عناوين الرسائل التي سنظهرها في الصفحات و التي حصلنا عليها من الدالة ArrayList عبارة عن dataList الكائن
    ArrayList<String> dataList = getSearchResult();

	
	// ArrayList هنا قمنا بتعريف دالة ترجع عناوين الرسائل ككائن نوعه
    public ArrayList<String> getSearchResult()
	{
		ArrayList<String> titles = new ArrayList();
        titles.add("Title 1");
        titles.add("Title 2");
        titles.add("Title 3");
        titles.add("Title 4");
        titles.add("Title 5");
        titles.add("Title 6");
        titles.add("Title 7");
        titles.add("Title 8");
        return titles;
    }
    
	// بناءاً على عدد الرسائل التي سنظهرها فيه Pagination هنا قمنا بتعريف دالة ترجع عدد الصفحات التي يجب أن تكون موجودة في الكائن
    public int getNumberOfPages()
	{
		// totalItems هنا قمنا بتخزين عدد عناوين الرسائل في المتغير
        double totalItems = dataList.size();
        
		// تساوي 0 totalItems ستكون قيمة dataList إذا كان لا يوجد أي رسائل أصلاً في الكائن
		// pagination لهذا السبب سنرجع القيمة 1 حتى يتم إنشاء صفحة واحدة فقط في الكائن
        if(totalItems == 0)
            return 1;
        
		// الشرطين التاليين يرجعان عدد الصفحات التي يجب إنشائها نسبةً لعدد العناصر التي سيتم وضعها في كل صفحة
        if(totalItems%itemsPerPage == 0)
            return (int)(totalItems/itemsPerPage);
        else
            return (int)(totalItems/itemsPerPage) + 1;
    }
 
	
	// pagination هنا قمنا بإنشاء دالة خاصة لإنشاء و ترتيب محتوى كل صفحة سيتم إضافتها في الكائن
    public VBox createPage(int pageIndex)
	{
        // VBox محتوى كل صفحة سنعرضه بداخل حاوية نوعها
        VBox vBox = new VBox();
        
		// dataList العنوان التالي الذي يجب أن يتم جلبه من الكائن index سنستخدمه لمعرفة nextItemIndex المتغير
        int nextItemIndex = pageIndex * itemsPerPage;
        
		// لا يساوي بعد عدد العناصر التي نريد وضعها في كل صفحة vBox طالما أن عدد العناصر الموضوعة في الكائن
        while(vBox.getChildren().size() < itemsPerPage) {
            try {
				// من أجل عرض العنوان و النبذة عن كل رسالة فوق بعض مع تعديل تصميمه الإفتراضي VBox سيتم إنشاء كائن
				// من أجل إظهار خط لونه رمادي فاتح في أسفله و وضع هامش بين الأشياء التي نضيفها فيها بمقدار 5 بيكسل
                VBox elementBox = new VBox();
                elementBox.setStyle(
                        "-fx-border-width: 0 0 1 0;"
                        + "-fx-border-color: #f1f1f1;"
                        + "-fx-padding: 5px;"
                );
        
				// Label و النبذة عن الرسالة سنضعها بداخل كائن Hyperlink عنوان الرسالة سنضعه بداخل كائن
				// dataList من الكائن Label و Hyperlink و سيتم جلب النص الذي سيوضع على الكائنين
                Hyperlink link = new Hyperlink(dataList.get(nextItemIndex));
                Label text = new Label("Description for "+ link.getText());

				// vBox في الكائن elementBox و من ثم وضعنا الكائن elementBox في الكائن text و link هنا قمنا بوضع الكائنين
                elementBox.getChildren().addAll(link, text);
                vBox.getChildren().add(elementBox);

				// dataList من أجل جلب العنوان التالي من الكائن nextItemIndex هنا قمنا بإضافة 1 على قيمة المتغير
                nextItemIndex++;
            }
            catch(Exception e) {
                break;
            }
        }
		
		// الذي أصبح يحتوي على كل العناصر التي يجب عرضها في الصفحة vBox في الأخير سيتم إرجاع الكائن
        return vBox;
    }
 
    
    @Override
    public void start(Stage stage) {
        
        // في النافذة Root Node و الذي ننوي جعله الـ AnchorPane هنا قمنا بإنشاء كائن من الكلاس
        AnchorPane root = new AnchorPane();
		
        // root الذي نريد إضافته في الكائن Pagination يمثل الـ Pagination هنا قمنا بإنشاء كائن من الكلاس
        Pagination pagination = new Pagination();
		
		// التي سترجع عدد الصفحات التي يجب إنشاءها getNumberOfPages() و مررنا الدالة pagination هنا قمنا بتحديد عدد صفحات الكائن
		pagination.setPageCount(getNumberOfPages());
        
        // حتى تقوم بتوليد محتوى كل صفحة فيه createPage() و مررنا لها الدالة setPageFactory() هنا قمنا باستدعاء الدالة
        pagination.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
        
        // أبيض و جعلنا لون حدوده رمادي فاتح pagination هنا جعلنا لون خلفية الكائن
        pagination.setStyle("-fx-background-color:white; -fx-border-color: lightgray;");
        
        // من كل الجهات بمقدار 20 بيكسل ( root الذي سيوضع بداخله ( أي الكائن AnchorPane عن كائن الـ pagination هنا قمنا بتحديد مكان بعد الكائن
        AnchorPane.setTopAnchor(pagination, 20.0);
        AnchorPane.setRightAnchor(pagination, 20.0);
        AnchorPane.setLeftAnchor(pagination, 20.0);
        AnchorPane.setBottomAnchor(pagination, 20.0);

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

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

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

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

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

}
		

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

طريقة عرض رسائل بداخل Pagination في javafx

دورة  javaFX