İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır

AWT ve Swing'de Thread'ler

Arayüzde Thread Kullanma Zorunluluğu

Arayüzde (Swing, AWT v.s'de) çok kanallı progrmalama çoğu kez zorunludur. Diğer propgramlama alanlarında, örneğin web programlamada da thread'ler kullanılır ancak programcı çoğu kez bunları bilmeden program yazar. Swing ve AWT'de de thread'ler youğun bir şekilde kullanılır ve çoğu lez altyapı bunu otomatik yapar. Ekrana çizilen bir şekil, bir event'in handle edilmesi gibi konular zaten çok kanallı olarak gekçekleştirilir. Ancak arayüz programlamada porgramcının de thread'lerle doğrudan veya dolaylı olarak çalışması gerkmektedir. Doğrudan çalışma, Thread class'ını kullanma anlamı9na gelir. Dolaylı çalışma da Timer veya SwingUtilities' class'ının bazı methodları gibi thread kullanan class ve methodları kullanmak demektir.

java.util.Timer Kullanma

Java'nın Utility paketindeki (java.util) Timer genel amaçlı olarak yazılmış bir Timer olmakla birlikte arayüzde de kullanılabilir. Örnek olarak AWT kulllanarak ekrana analog saat çizen bir program yapalım :

ClockCanvas.javaİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 package com.godoro.samples.awt;
  2 import java.awt.*;
  3 import java.util.*;
  4 public class ClockCanvas extends Canvas{
  5   private final static int SLICE_DEGREE=6;
  6   private Point center=new Point(100,100);
  7   private int radius=80;
  8   public ClockCanvas(){
  9     Timer timer=new Timer();
 10     TimerTask task=new TimerTask(){
 11   public void run() {
 12       repaint();
 13   }
 14     };
 15     timer.scheduleAtFixedRate(task,0,1000);
 16   }
 17   public void paint(Graphics g){
 18       Calendar now=Calendar.getInstance();
 19       drawDial(g);
 20       drawSecondHand(g,now);
 21       drawMinuteHand(g,now);
 22       drawHourHand(g,now);
 23   }
 24   private void drawDial(Graphics g) {
 25     g.drawOval(center.x-radius,center.y-radius,2*radius,2*radius);
 26     int numbersRadius=radius-8;
 27     for(int i=1;i<=12;i++){
 28   double hour=Math.PI/6;
 29   int x=(int)(center.x-5+(numbersRadius)*Math.sin(i*hour));
 30   int y=(int)(center.x+5-(numbersRadius)*Math.cos(i*hour));           
 31   g.drawString(Integer.toString(i),x,y);
 32     }
 33   }
 34   private void drawSecondHand(Graphics g,Calendar now) {
 35     int second = now.get(Calendar.SECOND);  
 36     double radian=Math.toRadians(SLICE_DEGREE*second);
 37     int x=(int)(center.x+(radius-5)*Math.sin(radian));
 38     int y=(int)(center.y-(radius-5)*Math.cos(radian));
 39     g.drawLine(center.x,center.y,x,y);
 40   }
 41   private void drawMinuteHand(Graphics g,Calendar now) {
 42     int minute=now.get(Calendar.MINUTE);
 43     double radian=Math.toRadians(SLICE_DEGREE*minute);  
 44     int x=(int)(center.x+(radius-10)*Math.sin(radian));
 45     int y=(int)(center.y-(radius-10)*Math.cos(radian));  
 46     g.drawLine(center.x,center.y,x,y);
 47   }
 48   private void drawHourHand(Graphics g,Calendar now) {
 49     int hour = now.get(Calendar.HOUR);      
 50     int minute=now.get(Calendar.MINUTE);
 51     double radian=Math.toRadians(30*hour+minute/2);    
 52     int x=(int)(center.x+(radius-25)*Math.sin(radian));
 53     int y=(int)(center.y-(radius-25)*Math.cos(radian));
 54     g.drawLine(center.x,center.y,x,y);
 55   }
 56   public static void main(String[] args) {
 57     Frame frame=new Frame();
 58     frame.setLayout(new BorderLayout());
 59     frame.add(BorderLayout.CENTER,new ClockCanvas());
 60     frame.setBounds(0,0,220,220);
 61     frame.setVisible(true);
 62   }
 63 }

javax.swing.Timer Kullanma

Java'nın Swing paketindeki (java.swing) sadece Swing'de kullanılmak için yazılmış bir class'dır. Aslında bir olayın (event'in) işlenmesi sürecine paralel bir biçimde çalışması için yazılmıştır. Zaten event'ler düğmeye basma, fareye tıklama menü maddesi seçme gibi durumlarda EventDispatcher thread denilen bir thread tarafından teker teker değerlendirlmekte va eventi dinleyen nesnelere teker teker çağrılmaktadır. java.swingTimer'ın yaptığı, programcının yapmak istediği bir işinde diğer olaylara benzer bir şekilde değerlendirlmesini ve çalıştırlmasını sağlamaktır. Örnek olarak Swing kulllanarak ekrana dijital saat çizen bir program yapalım :

ClockCanvas.javaİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 package com.godoro.samples.awt;
  2 import java.awt.*;
  3 import java.util.*;
  4 public class ClockCanvas extends Canvas{
  5   private final static int SLICE_DEGREE=6;
  6   private Point center=new Point(100,100);
  7   private int radius=80;
  8   public ClockCanvas(){
  9     Timer timer=new Timer();
 10     TimerTask task=new TimerTask(){
 11   public void run() {
 12       repaint();
 13   }
 14     };
 15     timer.scheduleAtFixedRate(task,0,1000);
 16   }
 17   public void paint(Graphics g){
 18       Calendar now=Calendar.getInstance();
 19       drawDial(g);
 20       drawSecondHand(g,now);
 21       drawMinuteHand(g,now);
 22       drawHourHand(g,now);
 23   }
 24   private void drawDial(Graphics g) {
 25     g.drawOval(center.x-radius,center.y-radius,2*radius,2*radius);
 26     int numbersRadius=radius-8;
 27     for(int i=1;i<=12;i++){
 28   double hour=Math.PI/6;
 29   int x=(int)(center.x-5+(numbersRadius)*Math.sin(i*hour));
 30   int y=(int)(center.x+5-(numbersRadius)*Math.cos(i*hour));           
 31   g.drawString(Integer.toString(i),x,y);
 32     }
 33   }
 34   private void drawSecondHand(Graphics g,Calendar now) {
 35     int second = now.get(Calendar.SECOND);  
 36     double radian=Math.toRadians(SLICE_DEGREE*second);
 37     int x=(int)(center.x+(radius-5)*Math.sin(radian));
 38     int y=(int)(center.y-(radius-5)*Math.cos(radian));
 39     g.drawLine(center.x,center.y,x,y);
 40   }
 41   private void drawMinuteHand(Graphics g,Calendar now) {
 42     int minute=now.get(Calendar.MINUTE);
 43     double radian=Math.toRadians(SLICE_DEGREE*minute);  
 44     int x=(int)(center.x+(radius-10)*Math.sin(radian));
 45     int y=(int)(center.y-(radius-10)*Math.cos(radian));  
 46     g.drawLine(center.x,center.y,x,y);
 47   }
 48   private void drawHourHand(Graphics g,Calendar now) {
 49     int hour = now.get(Calendar.HOUR);      
 50     int minute=now.get(Calendar.MINUTE);
 51     double radian=Math.toRadians(30*hour+minute/2);    
 52     int x=(int)(center.x+(radius-25)*Math.sin(radian));
 53     int y=(int)(center.y-(radius-25)*Math.cos(radian));
 54     g.drawLine(center.x,center.y,x,y);
 55   }
 56   public static void main(String[] args) {
 57     Frame frame=new Frame();
 58     frame.setLayout(new BorderLayout());
 59     frame.add(BorderLayout.CENTER,new ClockCanvas());
 60     frame.setBounds(0,0,220,220);
 61     frame.setVisible(true);
 62   }
 63 }

Burada 1000 milisaniye arayla verilen ActionListener'ın çağrılması sağlanmaktadır. Ve actionPerformed method'unda zaman alınmakta ve repaint çağrılmaktadır. Burada repaint() method'u da paint method'unu dolaylı olarak çağıracağından gerekli çizimler yapılmış olacaktır. Örnekte belli bir biçimde zamanı basmak için java.text.DecimalFormat class'ı kullanılmış.

SwingUtilities'in invokeLater ve InvokeAndWait Method'ları

javax.swing.SwingUtilities class'ında Thread'lerle ilgili invokeLater() ve InvokeAndWait() bulunmaktadır. Bu iki method, bir işlemin arayüz olaylarını değerlendiren event dispathcer thread çalıştırılmasını sağlar. Bu şekilde daha önce arayüzle ilgili işlemlerin tamamlanmış olması sağlanmış olur. Bu iki method parametre olarak Runnable alır.

Bu methodlardan invokeLater() bir işlemin kuyruğa konmasını sağlayıp çalışmanın devam edilmesini sağlar. Yanı asıl thrad'i bloke etmez.

Runnable runnable = new Runnable() {
    public void run() { 
		doAnyVisualOperation();
	}
};
SwingUtilities.invokeLater(runnable);
doAnyIndepenentOperation();

Buna karşın InvokeAndWait() çu andaki thread'i bloke eder ve işlem bitene kadar bekletir. Belli bir işlem bitmeden devam edilmemesi gerektiğinde ve devam eden kodun o işlemde yapılan değişikliklere bağlı olarak çalışmasını sağlamak iç.

Runnable runnable = new Runnable() {
    public void run() { 
		doAnyVisualOperation();
	}
};
SwingUtilities.invokeAndWait(runnable);
doAnyDependedOperation();

Dosya Listesi

İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır