Hakkında Künye

Swing ile GUI Programlama II

Merhaba sevgili e-bergi okuyucuları;

Bu ay, geçen ay giriş yaptığımız Swing'i incelemeye devam edeceğiz ve Swing'in daha gelişmiş özelliklerini tanıyacağız. Hepinizin hoşuna gideceğini umuyorum.

Bu ayki ilk örneğimizde JRadioButton'ları, JCheckBox'ları ve JTextArea'ları tanıyacağız. JRadioButton ve JCheckBox, kullanıcının, birden çok seçenek arasından seçim yapmasını sağlayan bileşenlerdir. JRadioButton ve JCheckBox'ın farkı, JCheckBox ile seçeneklerden istenilen kadarı seçilebiliyorken, JRadioButton ile yalnızca bir adet seçim yapılabilmesidir. JTextArea ise kullanım açısından JTextField'a benzer. Fakat JTextField ile tek satırlık veri girilip görüntülenebilirken, JTextArea ile birden çok satır girilebilir ve görüntülenebilir.

Üçüncü programımızın ismi Hayvanlar.java. Bu programda kullanıcı, JRadioButton'ları kullanarak "Kedi", "Kopek" ve "Fare"den birini seçiyor. Hemen altta, yaptığı seçime karşılık gelen resmi görebiliyor. Daha sonra JCheckBox'ları kullanarak bunlardan hangisini veya hangilerini sevdiğini işaretliyor ve "Tamam" düğmesine tıklayarak sevdiği hayvanların listesini görebiliyor. Resimleri görüntülemek için JLabel kullanacağız. Resimlerin görüntülenebilmesi için aşağıdaki resimleri sırasıyla kedi.jpeg, kopek.jpeg ve fare.jpeg isimleriyle, programınızla aynı dizine kaydetmelisiniz.hayvanlar alemi :)






Programın kaynak kodunu verelim.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Hayvanlar {
JRadioButton jrbKedi, jrbKopek, jrbFare;
ButtonGroup bg;
JCheckBox jcbKedi, jcbKopek, jcbFare;
JLabel resim, bilgi;
JButton tamam;
JTextArea text;

public Hayvanlar(){
JFrame jfr = new JFrame("Hayvanlar");
jfr.getContentPane().setLayout(new FlowLayout());
jfr.setSize(220,400);
jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

jrbKedi = new JRadioButton("Kedi");
jrbKedi.setSelected(true);
jrbKedi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
resim.setIcon(new ImageIcon("kedi.jpeg"));
}
});

jrbKopek = new JRadioButton("Kopek");
jrbKopek.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
resim.setIcon(new ImageIcon("kopek.jpeg"));
}
});

jrbFare = new JRadioButton("Fare");
jrbFare.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
resim.setIcon(new ImageIcon("fare.jpeg"));
}
});

bg = new ButtonGroup();
bg.add(jrbKedi);
bg.add(jrbKopek);
bg.add(jrbFare);

jfr.getContentPane().add(jrbKedi);
jfr.getContentPane().add(jrbKopek);
jfr.getContentPane().add(jrbFare);

resim = new JLabel(new ImageIcon("kedi.jpeg"));
jfr.getContentPane().add(resim);

text = new JTextArea("Sevdiginiz hayvanlar:\n",5,15);
text.setEditable(false);
jfr.getContentPane().add(text);

bilgi = new JLabel("Sevdiginiz hayvanlari secin.");
jfr.getContentPane().add(bilgi);

jcbKedi = new JCheckBox("Kedi");
jcbKopek = new JCheckBox("Kopek");
jcbFare = new JCheckBox("Fare");

jfr.getContentPane().add(jcbKedi);
jfr.getContentPane().add(jcbKopek);
jfr.getContentPane().add(jcbFare);

tamam = new JButton("Tamam");
tamam.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
text.setText("Sevdiginiz hayvanlar:\n");
if (jcbKedi.isSelected())
text.append("Kedi\n");
if (jcbKopek.isSelected())
text.append("Kopek\n");
if (jcbFare.isSelected())
text.append("Fare\n");
}
});
jfr.getContentPane().add(tamam);

jfr.setVisible(true);
}

public static void main(String[] args){
Hayvanlar h = new Hayvanlar();
}
}

Kodumuzdaki önemli yerleri inceleyelim.

ButtonGroup bg;

Aynı anda yalnızca bir tane JRadioButton'ın seçilebileceğini söylemiştik. Bu sebeple, arasından seçim yapılacak JRadioButton'ların bir grup altında toplanması gerekir. ButtonGroup nesnesini bu amaçla kullanıyoruz.

jrbKedi = new JRadioButton("Kedi");

JRadioButton'larımızı oluştururken, hemen yanında görüntülenecek yazıyı da belirleyebiliyoruz.

jrbKedi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
resim.setIcon(new ImageIcon("kedi.jpeg"));

Geçen ayki örneğimizde JButton'a tıkladığımız zaman ne yapılması gerektiğini belirtmiştik. Şimdi de, benzer şekilde, JRadioButton'ın seçildiği zaman ne olması gerektiğini kodluyoruz. Burada yeni olan tek şey setIcon metodu. JLabel'ların yazının yanısıra resim göstermek için de kullanılabileceğini söylemiştik. Bunu sağlamak için JLabel'ın setIcon metodunu bir ImageIcon nesnesiyle çağırmamız gerekiyor. ImageIcon nesnesini, dosya ismini kullanarak oluşturuyoruz ve setIcon metoduna gönderiyoruz.

bg = new ButtonGroup();
bg.add(jrbKedi);
bg.add(jrbKopek);
bg.add(jrbFare);

ButtonGroup nesnesini oluşturuyoruz ve sırayla, JRadioButton'larımızı, ButtonGroup'un add metodunu kullanarak gruba ekliyoruz.

text = new JTextArea("Sevdiginiz hayvanlar:\n",5,15);
text.setEditable(false);

JTextArea nesnesini oluşturuyoruz. Yapıcı fonksiyona (constructor) gönderdiğimiz ilk argüman, içerisinde görüntülenecek yazıyı, ikinci argüman satır sayısını, üçüncü argüman ise sütun sayısını gösteriyor. setEditable(false) yaparak JTextArea'nın kullanıcı tarafından değiştirilmesini engelliyoruz. Yani bu alana klavyeden giriş yapılmayacak. Bu durum, JTextArea'nın içeriğinin program çalıştığı sürece sabit kalacağı anlamına gelmez. Programın akışı içerisinde burası değişebilir.

jcbKedi  = new JCheckBox("Kedi");

JCheckBox'larımızı oluşturuyoruz ve yazılarını belirliyoruz. JCheckBox'ların herhangi bir grup altında toplanmasına gerek yoktur, çünkü bunlar birbirinden bağımsız çalışırlar.

if (jcbKedi.isSelected())
text.append("Kedi\n");

JCheckBox'ın isSelected metodu, CheckBox seçili ise true, değilse false döner. JTextArea'daki append metodu ise, isminden anlaşılacağı gibi, JTextArea'nın içindeki yazıya ekleme yapmak için kullanılır.

Swing'de tanımlı daha birçok bileşen vardır. Sıradaki örneğimizde JSlider ve JProgressBar'ı tanıyacağız.JSlider

Çoğu zaman, yapmak istediğimiz şeyin anında gerçekleşmediği, sonucu görebilmemiz için beklemek zorunda kaldığımız durumlarla karşılaşırız. Bu gibi durumlarda kullanıcıya, sürecin ne kadarının tamamlandığını bildirmek iyi bir fikirdir. Hatta sürecin ne kadarının tamamlandığı bilinmese bile, kullanıcıyı, çalışmanın devam ettiği yönünde bilgilendirmek isteyebiliriz. Swing kütüphanesinde tanımlı JProgressBar bu amaçla kullanılır. JProgressBar, isminden de anlaşılacağı gibi, bir işin ne kadarının tamamlandığını gösteren bir çubuktur. JSlider ise, belli bir aralık içerisinde bulunan bir değeri değiştirmek için sürükleyip bırakabileceğimiz bir düğmedir. Değişik amaçlarla kullanılabilir, örneğin; çalan müziğin sesini ayarlamak ya da radyo frekansını değiştirmek gibi.

Örneğimizde 3 adet JSlider'ı penceremizin arkaplan rengini ayarlamak için kullanacağız. Birincisi rengin kırmızı (R), ikincisi yeşil (G), üçüncüsü de mavi (B) bileşenini kontrol edecek. 2 adet JProgressBar'larımızdan birisini, "Başla" düğmesine tıklanınca başlayan ve eşit zaman aralıklarında eşit miktarda ilerleyen hayali bir işi göstermek için kullanacağız. Tabi gerçek bir iş sabit hızda ilerlemeyebilir, fakat bu örnek için öyle olduğunu varsayalım. JProgressBar'lar, sürecin ne kadarının tamamlandığı belli olmadığı zamanlarda belirsiz (indeterminate) modda çalıştırılmalıdır. Diğer JProgressBar'ımızı bunu göstermek için kullanacağız. Şimdi programımızın kaynak kodunu verelim. Sınıfımızın ismi "Renk", dosyamızın ismi "Renk.java" olacak.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Renk extends JFrame {
private JProgressBar cubuk1, cubuk2;
private JButton basla;
private JSlider sliderR, sliderG, sliderB;
private JLabel lblR, lblG, lblB;
private Timer timer;
private int yuzde = 0;

public Renk(){
setTitle("Renkler");
setSize(230,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new FlowLayout());

timer = new Timer(500, new ActionListener(){
public void actionPerformed(ActionEvent e){
if (yuzde == 100)
timer.stop();
else
{ yuzde += 5;
cubuk2.setValue(yuzde);
}
}
});

lblR = new JLabel("R :");
getContentPane().add(lblR);

sliderR = new JSlider(0,100);
sliderR.setMajorTickSpacing(20);
sliderR.setMinorTickSpacing(10);
sliderR.setPaintTicks(true);
getContentPane().add(sliderR);
sliderR.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
getContentPane().setBackground(new Color(
sliderR.getValue()/100.0F,
sliderG.getValue()/100.0F,
sliderB.getValue()/100.0F));
}
});

lblG = new JLabel("G :");
getContentPane().add(lblG);

sliderG = new JSlider(0,100);
sliderG.setMajorTickSpacing(20);
sliderG.setMinorTickSpacing(10);
sliderG.setPaintTicks(true);
getContentPane().add(sliderG);
sliderG.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
getContentPane().setBackground(new Color(
sliderR.getValue()/100.0F,
sliderG.getValue()/100.0F,
sliderB.getValue()/100.0F));
}
});

lblB = new JLabel("B :");
getContentPane().add(lblB);

sliderB = new JSlider(0,100);
sliderB.setMajorTickSpacing(20);
sliderB.setMinorTickSpacing(10);
sliderB.setPaintTicks(true);
getContentPane().add(sliderB);
sliderB.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
getContentPane().setBackground(new Color(
sliderR.getValue()/100.0F,
sliderG.getValue()/100.0F,
sliderB.getValue()/100.0F));
}
});

cubuk1 = new JProgressBar(0,100);
cubuk1.setIndeterminate(true);
getContentPane().add(cubuk1);

cubuk2 = new JProgressBar(0,100);
cubuk2.setStringPainted(true);
getContentPane().add(cubuk2);

basla = new JButton("Basla");
getContentPane().add(basla);
basla.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
timer.start();
basla.setEnabled(false);
}
});

getContentPane().setBackground(new Color(0.5F, 0.5F, 0.5F));

setVisible(true);
}

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

Kodumuzun önemli yerlerine göz atalım.

public class Renk extends JFrame {

Önceki örneklerden farklı olarak, bu örneğimizde sınıfımızı JFrame sınıfından türettik. Bu sayede bir JFrame nesnesi yaratıp onun üzerinden işlem yapmak yerine doğrudan kendi sınıfımız üzerinden işlem yapabiliriz.

private Timer timer;

Eşit zaman aralıklarında ilerleyen bir işi temsil etmek için bir Timer nesnesine ihtiyacımız olacak. Bir Timer nesnesi, belli aralıklarla action event ateşler.

timer = new Timer(500, new ActionListener(){
public void actionPerformed(ActionEvent e){
if (yuzde == 100)
timer.stop();
else
{ yuzde += 5;
cubuk2.setValue(yuzde);
}
}
});

Timer'ın yapıcı fonksiyonuna gönderilen ikinci argüman, ateşleyeceği action event'i belirten ActionListener nesnesini, birinci argüman da bu action event'in kaç milisaniye arayla ateşleneceğini belirtir. Timer, stop() fonksiyonu çağrılarak durdurulabilir.

sliderR = new JSlider(0,100);

JSlider'ın yapıcı fonksiyonuna gönderilen argümanlar, JSlider'ın alabileceği minimum ve maksimum değerleri belirler.

sliderR.setMajorTickSpacing(20);

setMajorTickSpacing fonksiyonu ile JSlider'daki büyük çentiklerin kaç birim arayla çizileceğini belirtiyoruz.

sliderR.setMinorTickSpacing(10);

setMinorTickSpacing fonksiyonu da JSlider'daki küçük çentiklerin kaç birim arayla çizileceğini belirtmemizi sağlıyor.

sliderR.setPaintTicks(true);

Çentiklerin ekranda görüntülenmesi için setPaintTicks fonksiyonunu kullanıyoruz.

sliderR.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
getContentPane().setBackground(new Color(
sliderR.getValue()/100.0F,
sliderG.getValue()/100.0F,
sliderB.getValue()/100.0F));
}
});

JSlider'ın sürgüsü kaydırıldığında bir change event ateşlenir. Sürgü kaydırıldığında yapılmasını istediğimiz şeyi bu sayede belirtebiliriz. JSlider'ın şu anki değeri getValue fonksiyonuyla elde edilebilir. Pencerenin arkaplan rengini değiştirmek için ContentPane'inin setBackground fonksiyonunu bir Color nesnesiyle çağırıyoruz. Color'ın yapıcı fonksiyonuna gönderdiğimiz değerler sırasıyla oluşturmak istediğimiz rengin kırmızı (R), yeşil (G) ve mavi (B) bileşenlerinin değerleridir. Bu değerler 0.0 ile 1.0 arasında ve float türünde olmalıdır.

cubuk1 = new JProgressBar(0,100);

JProgressBar'ın yapıcı fonksiyonuna gönderilen değerler sırasıyla JProgressBar'ın minimum ve maksimum değerleridir.

cubuk1.setIndeterminate(true);

Bu JProgressBar belirsiz (indeterminate) modda çalışacak. Bunu yapmak için JProgressBar'ın setIndeterminate fonksiyonunu kullanıyoruz.

cubuk2.setStringPainted(true);

JProgressBar'ın setStringPainted fonksiyonunu true ile çağırmak, JProgressBar'ın değerinin yüzde kaçına denk geldiğinin çubuğun üstüne yazılmasını sağlar.

timer.start();

Timer nesnesinin start fonksiyonu, zamanlayıcının başlamasını sağlar.

basla.setEnabled(false);

"Başla" düğmesine bir defa tıklandıktan sonra tekrar tıklanmaması için JButton'ın setEnabled fonksiyonunu false ile çağırıyoruz. Bir JButton'a tıklanabilmesi için JButton'ın etkinleştirilmiş olması gerekir.

Sonuç

Bu ayki yazımızın da sonuna geldik. Gelecek ay, programlarımıza menü çubuğu ekleyerek kullanımını kolaylaştırmayı ve klavyeden veri girişi yapıldığında ortaya çıkan olayları (KeyEvent) yönetmeyi öğreneceğiz. Görüşmek üzere :)



Tolga Akın
- 5 -