SwingWorker Thread Kullanımı‏ ve Uygulama Örneği

Multi tasking işlemler için bir yol...

Multi-threading uygulamalarımızda Swing kullanacağımız zaman dikkat edilmesi gereken 2 nokta var.

1- Zaman alan işlemlerin Event Dispatch Thread üzerinde koşturulmaması gerekir. Aksi takdirde programımız işlem yaparken yanıt veremez hale gelecektir.

2- Programımızda Swing ile ilgili kullanmış olduğumuz tüm componentlerin Event Dispatch Thread üzerinden koşturulması.

 

Yukarıdaki veriler ışığında şu sonuç ortaya çıkıyor:

Programımız için Swing componentlerini kullanan bir GUI tasarladığımızda, bize en az 2 adet Thread lazım.

Birinci Thread’i uzun zaman alacak işlemlerimiz için kullanacağız, diğer Thread’imizide yani Event Dispatch Thread ‘inide tüm GUI bileşenleri için kullanacağız.

Zaman alan işlemlerimiz programın arka tarafında çalışıp, işlemini tamamladığında GUI’mizi update edecek. Ve sonuç olarak kusursuz işleyen becerekli bir programa sahip olacağız.

 

SwingWorker’ın Yapısında Bulunan Metodlar

doInBackground(): Uzun süren işlemlerin / hesaplamaların yapılacağı zaman çağırılacak thread.

done(): doInBackground() dan gelen sonuçları Event Dispatch Thread üzerinde koşturur.

execute(): SwingWorker objesinde bir threadi çalıştırmak için çağırdığımız metod.

get(): Programımız tarafından yapılan hesap işleminin tamamlanmasını bekler ve hesap işleminden çıkan sonucu döndür.

publish(): doInBackground() metodundan gelen orta sonuçları Event Dispatch Thread tarafında koşturulması için gönderir.

process (): publish() metodundan gelen orta sonuçları alır ve Event Dispatch Thread tarafında koşturulması için gönderir.

setProgress(): Thread’imizle ilgili ara değerler göndermek için kullanıyoruz. Genelde Progress bar’ı update ederken kullanıyor.

 

Şimdi basit bir örnek ile inceleyelim. Yapacağımız örneği genel olarak açıklayacak olursak; Örnektekteki programımız 2 classdan oluşuyor. Fibonacci sayılarının nasıl bulunduğunu göreceğiz. FibonacciCalculator classı swingWorker’ımızın çalışacağı alan ve GUI classıda isminden de anlaşılabileceği üzere Kullanıcı arayüzünün bulunduğu kısım. Şimdi dilerseniz kodlara ve içerisinde yorumlara göz atalım..

Class FibonacciCalculator


import java.util.concurrent.ExecutionException;
import javax.swing.JLabel;
import javax.swing.SwingWorker;

/**
 *
 * @author Ferhan Akman
 *
 * @date 24.09.2008
 *
 */

public class FibonacciCalculator extends SwingWorker {

    private final long n;
    private final JLabel resultJLabel;

    public FibonacciCalculator(long no, JLabel label) {

        n = no;
        resultJLabel = label;

    }

    //fibonacci(long number) fonksiyonnuna hesaplayacağımız elemanın sayısını yazıyoruz.
    public Object doInBackground() {

        long nthFib = fibonacci(n);
        return String.valueOf(nthFib);

    }

    /*
     doInBackground() fonksiyonundan geriye dönecek olan değer done() fonksiyonuna gelir. burada koşullara göre GUI üzerinde değişiklik yapmasını söylüyoruz. işlemimiz tamamlandığında, sonuç get() fonksiyona gelecek. biz burada resultJLabel’ına sonucu yazmasını söylüyoruz.
     */

    protected void done() {

        try {

            resultJLabel.setText((String) get());

        } catch (InterruptedException e) {

            resultJLabel.setText("işlem kullanıcı tarafından durduruldu!");

        } catch (ExecutionException e) {

            resultJLabel.setText("işlem çalışırken çalışma hatası meydana geldi!");

        }

    }

    //recursive bir fonksiyon kullanarak fibonacci sayısını hesaplıyoruz.
    private long fibonacci(long number) {
       
        if (number == 0 || number == 1) {
            return number;
        } else {
            return fibonacci(number - 1) + fibonacci(number - 2);
        }
    }

}
 

 Class GUI

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

/**
 * @author Ferhan Akman
 * @date 24.09.2008
 *
 */

public class GUI extends JFrame implements ActionListener {

     // girilen sayı kadar fibonacci getirelecek kısım
    JPanel ustPanel = new JPanel(new GridLayout(2, 2, 5, 5));
    JTextField numberJTF = new JTextField();
    JButton goJBtn = new JButton("GO");
    JLabel fibonacciJLabel = new JLabel();

    //sıradaki fibonacci sayısını bulmakta kullanacağımız alan
    JPanel altPanel = new JPanel(new GridLayout(2, 2, 5, 5));
    long n1 = 0;
    long n2 = 1;
    int count = 1;

    JLabel nJLabel = new JLabel("1. Fibonacci sayısı: ");
    JLabel nFibonacciJLabel = new JLabel(String.valueOf(n2));
    JButton nextNumberButton = new JButton(" Sıradaki Sayı");

    public GUI() {

        super("Fibonacci Numaraları Ferhan Akman ");
        JPanel panel = new JPanel(new GridLayout(2, 1, 10, 10));
        ustPanel.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "SwingWorker Çalışma Sahası"));
        goJBtn.addActionListener(this);
        ustPanel.add(new JLabel("Getirilecek Fibo. Sayısı: "));
        ustPanel.add(numberJTF);
        ustPanel.add(goJBtn);
        ustPanel.add(fibonacciJLabel);
        altPanel.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "SwingWorker Olmayan Kısım"));
        nextNumberButton.addActionListener(this);
        altPanel.add(nJLabel);
        altPanel.add(nFibonacciJLabel);
        altPanel.add(nextNumberButton);
        panel.add(ustPanel);
        panel.add(altPanel);
        setContentPane(panel);
        setVisible(true);
        setSize(455, 200); // pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void actionPerformed(ActionEvent e) {

        Object obj = e.getSource();
        JButton button = (JButton) obj;

        if (button == goJBtn) {

            long n;

            try {
                n = Long.parseLong(numberJTF.getText());
            } catch (NumberFormatException e1) {
                fibonacciJLabel.setText(" Tam sayı girin! ");
                return;
            }

            fibonacciJLabel.setText(" Hesaplanıyor… ");
            FibonacciCalculator task = new FibonacciCalculator(n, fibonacciJLabel);
            task.execute();

        }

        if (button == nextNumberButton) {

            long temp = n1 + n2;

            n1 = n2;
            n2 = temp;
            ++count;
            nJLabel.setText(count + ". Fibonacci sayısı: ");
            nFibonacciJLabel.setText(String.valueOf(n2));
        }

    }

    public static void main(String[] args) {

        GUI app = new GUI();

    }

}
 

 

SwingWorker Thread Kullanımı‏ ve Uygulama Örneği

Kaynak:

Yorumunuzu Ekleyin

Yükleniyor...