0

JavaFX Platform.runLater() nedir ? Nasıl kullanılır ?

Merhaba arkadaşlar yine güzel bir konuyu anlatmak üzere bir sayfa açmış bulunmaktayım. Bilindiği gibi çok uzun zaman alan işlemleri JavaFX main thread’de çalıştırmak uygun bir durum değil ? sebebi ise bildiğiniz gibi çok uzun süren bir işlem arayüzü kilitleyecek ve kullanıcının program bozuk deyip kapatmasına yani kullanamamasına sebep olacaktır. Tabi bu hiç de istediğimiz bir durum değildir. Peki ne yapalım. ? Eğer bir işlem uzun sürüyorsa bunu arka planda çalıştıralım ta ki programımız kilitlenmiş havasına girip kapatılmaya sebep olmasın. Javafx Concurrent Framwork konusu aslında bu konuyu başdan aşağı işlemiş. Orada demiştik eğer böyle bir işiniz varsa ve arka planda yeni bir Thread  nesnesi oluşturun bu nesne sizin için arkaplanda işlemleri yapar demiştik. Pekiiii? Şimdi bir thread oluşturdum ama benim oluşturduğum thread bir background thread, ben işlemleri yaptım ama birde “UI Thread” (Javafx Application Thread) deki bir label’e işlemlerim ile ilgili bilgi yazdırmak istiyorum. Yani bir background thread’den UI thread’e veri aktarmak istiyorum. Bunun için  Task<> nesnesini oluşturulabilir ancak biraz uzun olabilir. yani yeni sınf aç , …..,  property leri hazırlamak updateler vb. . İşte bu durumlarda pratik kullanım açısından kullanılabilecek yapı Platform.runLater(Runnable runnable) dir. Yani Task<> ‘ın pratik kullanımı yada daha küçük işlemlerde ( komplex olmayan) kullanılan versiyonu diyebiliriz.  Bu şekilde de UI thread’e bilgi aktarabiliriz. 

Adımlar yazacak olursak

  • Öncelikle uzun bir işleminiz varsa yeni bir thread oluşturun ve işleminizi arka plana taşıyın 
  • UI thread ‘de bulunan bir elemana erişecek ve ona bilgi gönderecekseniz 
  • Platform.runLater(new Runnable(){  public void run(){ ana threaddeki elamana burdan bilgi aktarın. }});
  • oluşturduğunuz thread’i çalıştırın . 

Şimdi task ve Platform.runLater() kullanım farklarını gösterir bir kod paylaşalım.

final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
    for (int i = 1; i <= 1000000; i++) {
        final int counter = i;
        Platform.runLater(new Runnable() {
            @Override public void run() {
                bar.setProgress(counter / 1000000.0);
            }
        });
    }
}).start();
Task task = new Task<Void>() {
    @Override public Void call() {
        static final int max = 1000000;
        for (int i = 1; i <= max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

Evet iksininde kullanımı ile ilgili örnekler karşımızda . Dediğim gibi daha komplex işlerde Task<> tercih edilir. Daha küçük işlerde Platform.runLater() kullanılır. Platform.runLater(); de aynen Task gibi  Javafx main  Thread’ e ulaşıp bilgi gönderebilir.

Şimdi başka bir örnek kulanım daha paylaşalım.

örnek: 3

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class CounterApp extends Application {

    private int count = 0;
    private final Text text = new Text(Integer.toString(count));

    private void incrementCount() {
        count++;
        text.setText(Integer.toString(count));
    }

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();
        root.getChildren().add(text);

        Scene scene = new Scene(root, 200, 200);

        // Uzun süren işlemler her zaman ayrı bir thread'de yapılmalıdır
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                Runnable updater = new Runnable() {

                    @Override
                    public void run() {
                        incrementCount();
                    }
                };

                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                    }

                    // Bu metod ile UI deki bir metodu tetikliyoruz.
                    Platform.runLater(updater);
                }
            }

        });
        
        thread.setDaemon(true);
        thread.start();

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

yine başka bir örnek daha 

örnek 4:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;



public class Main extends Application {



    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox root=new VBox();
        root.setSpacing(10);
        root.setPadding(new Insets(30,30,10,10));


        TextField textField=new TextField();
        Label label=new Label("Sayaç");
        HBox hBox=new HBox(10,label,textField);
        hBox.setAlignment(Pos.CENTER);

        Button button=new Button("Başlat");
        Region spacer=new Region();
        HBox hBox1=new HBox(10,spacer,button);
        hBox1.setHgrow(spacer, Priority.ALWAYS);
        hBox1.setAlignment(Pos.CENTER);

        button.setOnAction(event -> {

            Thread thread=new Thread(new Runnable() {
                @Override
                public void run() {

                    for(int i=0; i<100;i++){

                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        final int counter=i;
                        Platform.runLater(()->{

                            textField.setText(String.valueOf(counter));

                        });
                    }

                }
            });

            thread.setDaemon(true);
            thread.start();

        });





        root.getChildren().addAll(hBox,hBox1);

        Scene scene=new Scene(root,250,300);
        scene.getStylesheets().add("myStyle.css");
        primaryStage.setScene(scene);
        primaryStage.setTitle("Platform Run Örneği");
        primaryStage.show();




    }




}

Örnek 5 progressbar kullanarak. buraya şu notu düşelim progressbar 0-1 aralığında değerler alarak progress’e yansıtır ona göre değerleri ayarlamak lazım. 

 /* private void incrementCount() {
            // start metodunun dışında tanımladığımız metod
            count++;
            textField.setText(Integer.toString(count));
        }*/

             button.setOnAction(event -> {


                 Thread thread=new Thread(new Runnable() {
                     @Override
                     public void run() {

                         for(double i=1; i<101;i++){

                             final  double j=i;
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                   textField.setText(String.valueOf(j)); // ekrana basılacak textfield
                                   bar.setProgress(j/100);   // progressbar
                                }
                            });

                             try {
                                 Thread.sleep(100);
                             } catch (InterruptedException e) {
                                 e.printStackTrace();
                             }

                         }


                     }
                 });

                 thread.start();


                });

 

 

konuyu yeterince aydınlatacak örnekler olmuştur inşallah.

admin

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir