JavaFX طريقة ربط الـ ProgressIndicator بمهمة معينة

المثال التالي يعلمك طريقة تغيير شكل الـ ProgressIndicator ليبدو كـ Indeterminate Progress Indicator ثم كـ Determinate Progress Indicator بالإعتماد على الكلاس Task.
سنستخدم الكلاس Task لجعل شكل الـ ProgressIndicator يكتمل خلال ثانيتين.


مثال

LoginTask.java
import javafx.concurrent.Task;

// و هذا يعني أنه عند إنشاء كائن م هذا الكلاس سيتم تنفيذ مهمة معينة Task هنا قمنا بإنشاء كلاس يرث من الكلاس
public class LoginTask extends Task<Boolean>{

	// في هذه الدالة نقوم بتحديد ما سيحدث عند إنشاء كائن من هذا الكلاس
    @Override
    protected Boolean call() throws Exception {
		// هنا قلنا أنه سيتم إيقاف تنفيذ هذه المهمة لمدة ثانيتين
        Thread.sleep(2000);
		// الذي سنربطه بكائن من هذا الكلاس يظهر مكتملاً ProgressIndicator بعد إنقضاء الثانيتين سنجعل قيمة الـ
        updateProgress(1, 1);
		// و هذا ليس له أي أثر على البرنامج Boolean لأننا قمنا بتعريفها كـ true هنا جعلنا الدالة ترجع القيمة
        return true;
    }
        
}
		

Main.java
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage stage) {

        // هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة
        Label label_1 = new Label("User");
        Label label_2 = new Label("Password");
        TextField textField = new TextField();
        PasswordField passwordField = new PasswordField();
        Button button = new Button("Login");
        ProgressIndicator progressIndicator = new ProgressIndicator(-1);

		// button و label_2 و label_1 هنا قمنا بتغيير حجم خط الكائنات
        label_1.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
        label_2.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
        button.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");

		// button لأنني ننوي إظهاره بعد النقر على الكائن progressIndicator هنا قمنا بإخفاء الكائن
        progressIndicator.setVisible(false);

        // هنا قمنا بتحديد مكان ظهور الأشياء التي سنضيفها في النافذة
        label_1.setTranslateX(80);
        label_1.setTranslateY(40);
        textField.setTranslateX(165);
        textField.setTranslateY(40);
        label_2.setTranslateX(80);
        label_2.setTranslateY(85);
        passwordField.setTranslateX(165);
        passwordField.setTranslateY(85);
        button.setTranslateX(80);
        button.setTranslateY(130);
        progressIndicator.setTranslateX(100);
        progressIndicator.setTranslateY(190);

        // هنا قمنا بتحديد حجم الأشياء التي سنضيفها في النافذة
        label_1.setPrefSize(80, 30);
        textField.setPrefSize(160, 30);
        label_2.setPrefSize(80, 30);
        passwordField.setPrefSize(160, 30);
        button.setPrefSize(245, 35);
        progressIndicator.setPrefWidth(200);

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

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

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

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

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

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

		
		// progressIndicator هنا قمنا بتحديد ما سيحدث في كل مرة يتم فيها تغيير قيمة الكائن
        progressIndicator.progressProperty().addListener((obs, oldValue, newValue) -> {
			// Done تحته بدل النص Login Succefully هنا قلنا أنه في حال أصبحت قيمته تساوي 1 - أي في حال إكتمل - سيتم وضع النص
            if (newValue.doubleValue() >= 1.0) {
                Text doneText = (Text) progressIndicator.lookup(".percentage");
                doneText.setText("Login Succefully");
            }
        });

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

			// سيتم إظهاره تنبيه passwordField أو الكائن textField في حال لم يقم المستخدم بإدخال أي قيمة في الكائن
            if (textField.getText().equals("") || passwordField.getText().equals(""))
			{
                Alert alert = new Alert(AlertType.WARNING);
                alert.setTitle("Missing Information");
                alert.setHeaderText("Missing Information");
                alert.setContentText("User name & password are required!");
                alert.show();
            }

			// passwordField أو الـ textField في حال قام المستخدم بإدخال أي قيمة في الـ
            else
			{
				// progressIndicator سيتم إظهار الكائن
				progressIndicator.setVisible(true);
				// LoginTask بعدها سيتم إنشاء كائن من الكلاس
                LoginTask task = new LoginTask();
				// task بالكائن progressIndicator بعدها سيتم ربط أداء الكائن
                progressIndicator.progressProperty().bind(task.progressProperty());
				// خاص Thread بداخل LoginTask الموجودة في الكلاس call() في الأخير سيتم تنفيذ المهمة المعرفة بداخل الدالة
                new Thread(task).start();
            }

        });

    }

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

}
		

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

طريقة ربط ال ProgressIndicator بمهمة معينة في javafx

الدورات

أدوات مساعدة

أقسام الموقع

دورات
مقالات كتب مشاريع أسئلة