18 Mart 2011 Cuma

JavaFx


Bu yazı daha önce saltokunur.org e-derginin Temmuz 2009 sayısında yayınlanmıştır. 

Bilgisayar teknolojileri ilerledikçe ve bilgisayar destekli, hayatımızı kolaylaştıran teknolojiler geliştirildikçe, hepimiz bilgisayarla daha fazla vakit geçirir olduk. Kullanıcıların gündelik ihtiyaçlarına yönelik çözümler üreten yazılım firmaları, rakip ürünler arasından kendi ürünlerini ön plana çıkarıp, kullanıcıların kendi ürünlerini kullanmalarını sağlama yarışı içindeler. Bu amaçla bazı firmalar var olan teknolojilerle hep daha kullanışlı ve daha görsel ürünler üreterek pazarda yer tutmaya çalışıyorlar. Olaya internet kullanımı tarafından bakarsak, bunlara şu aralar etrafta mantar gibi biten sosyal ağ sitelerini örnek verebiliriz (Facebook, Flickr, FriendFeed). Hepsi kullanıcı sayısıyla birlikte reklam gelirlerini de artırma peşinde.

Zengin İnternet Uygulamaları (RIA)
Sektöre yön veren büyük yazılım firmaları ise, diğerlerinin kullandığı bu teknolojileri ya da platformları üreterek kullanıcılara ve geliştiricilere yeni dünyalar açıyorlar. Gene internet teknolojileri açışından olaya bakarsak, bu teknolojilerin ilk büyük örneğini Macromedia (daha sonra Adobe tarafından satın alındı) tarafından Flash'la gördük. Bu gün neredeyse flash kullanmayan internet sitesi yok gibi (bakınız bizim derginin sitesi :). Bunlara verilebilecek diğer güzel örnekler Sun'un Applet teknolojisi, AJAX, Adobe'nin Flex'i, son dönemde büyük ses getiren Microsoft'un Silverlight'ı... Hepsi geliştiricilere daha kolay, çabuk ve görselliği yüksek ürünler geliştirmesi imkanını sağlamak üzere üretildiler ve günümüzde Facebook, Google Maps, Google Doc, v.b. Zengin İnternet Uygulamaları (RIA - Rich Internet Applications) geliştirmede kullanılıyorlar.
Sun Microsystems bugüne Java ile sunduğu Applet teknolojisi dışında görsel uygulamalar geliştirmeler dışında geliştiricilere hiçbir teknoloji sunmuyordu. Zaten o da AWT (Abstract Window Toolkit) ve Swing (Java'nın Arayüz geliştirme kütüphanesi) tabanlı olduğu için geliştiriciler "deveye hendek atlatmaktansa" başka teknolojilere yönelmeyi tercih ediyorlarlardı. Gerçektende Java'da Swing'le program yazmak çok uğraş gerektici bir işlemdir. Geliştiriciler programın işi yapacak kodundan çok onu arayüze taşıyacak olan koduna daha fazla zaman ayırırlar (kendimden biliyorum :). Sanırım Sun bu konuda gerilere düşmekte olduğunu farketti ve Mayıs 2007'de San Francisco'da RIA ve multimedia uygulama geliştirme amaçlı yeni teknolojisi JAvaFx'in 1.0 sürümünü tanıttı. Şimdilerde 1.2 sürümüyle karşımızda olan JavaFx bu ayki yazımızın konusu.

JavaFx
JavaFx, Zengin İçerikli İnternet Uygulamaları (RIA) geliştirmek ve Java'nın fakir arayüz ve multimedia özeeliklerini zenlinleştirmek için geliştirdiği açık kaynak bir teknolojidir. Gelişmiş güncel ses, video ve grafik desteği sunar. Yazılım geliştiricilerin zengin içerikli, etkileşimli ve etkileyici uygulamalara Web tabanlı vektör grafiği, animasyon, ses ve video gibi öğeler yerleştirmelerine olanak verir.
Java teknolojisi halen masaüstü ve dizüstü bilgisayarların yüzde 90’ından fazlasında (yaklaşık 800 milyon), mobil araçların ise yüzde 85’inden fazlasında, TV, taşınabilir oyun platformları ve diğer taşınabilir cihazlarda kullanılıyor. Sun JavaFx'de Java ile getirdiği "Bir kere yaz heryerde çalıştır" felsefesini devam ettiriyor. Yani JavaFx, JVM (Java Sanal Makinesi) kurulu olan herhangi bir cihazda değişikliğe uğratılmadan çalışabiliyor. Bu da JavaFx'in kullanım alanlarının çok geniş olacağını vaat ediyor.
JavaFX uygulamalarında her tür Java kitaplığının kullanılmasına olanak sağlayarak Java'nın gücünü artırır. JavaFx, 2D, AWT ve Swing gibi Java API'lerini kullanabiliyor. Bu da demek oluyorki Java ile oluşturduğumuz bir programa, JavaFx kullanarak, program ile ilgili hesap yapan kodları değiştirmeden daha iyi görünüm ve kolay kullanım özellikleri katabiliriz.

Dil Yapısı
JavaFx dil yapısı olarak iki kısma ayrılıyor. Daha çok RIA geliştirmek için web tarafında kullanılan JavaFx Script ve mobil cihazlara yönelik JavaFx Mobile.
JavaFX Mobile bir platform olarak düşünülmüş. JavaFx Mobile ile geliştirilen uygulamalar mesajlaşma, grafik yönetimi, GPRS/EDGE/UMTS, WiFi, yüksek tanımlı video (HD) gibi özellikleri barındırır.
JavaFx Script, ise deklaratif bir dil. Yani geliştiriciler programa işlerin nasıl yapılacağını değil de, ne yapacağını, ekranda ne göstereceğini söylüyor. Bunu HTML gibi düşünebilirsiniz, bildiğiniz gibi HTML'de  neyi göstereceğini tarayıcıya söylememiz yeterli. Böylece JavaFx çok daha hızlı GUI geliştirmeye olanak sağlıyor. Hali hazırda bulunan Swing ve Java kütüphanelerini kullanımına imkan sağlıyor. Kodlama yapısı da benzer script dilleri gibi. Ana penceremizde bir sahne var ve bu sahneye görsellerimizi ekliyoruz. Eklenen her görsele bir düğüm deniliyor. Sonra bu düğümlere en, boy, renk gibi özellikler atanıyor.

Örnek:
Stage sahne{
    Cirle cember{
    height:100
    weight:100
    color:blue
    }
}

Ayrıca JavaFX Script ile gelen olay oluşturma ve yürütme konusundaki iyileştirmelerden Swing uygulamaları da faydalanacak ve yakın zamanda daha performanslı Swing uygulamaları göreceğiz.


Özellikleri
JavaFx diğer RIA geliştirme ortamlarına göre sistem kaynaklarını daha az kullanır.
Browser içinde çalışan JavaFX uygulaması sürükle-bırak yöntemi ile masaüstüne taşınarak sanki bir masaüstü uygulamasıymış gibi çalıştırılabilir.

JavaFx ile neler yapılabilir?
JavaFx ile yapabilecekleriniz hayal gücünüzle sınırlı olsa da (çok klişe oldu), işte size fikir verebilecek bazı örnekler.
Mash-Up uygulamaları. Çeşitli servislerin sağladığı özellikleri bir uygulamada birleştirmek. Örn, Google Map ten istenilen yerin haritasını alıp, Flickr'dan oraya ait fotoğrafları bulmak.
Yol Animasyonları. Ekran üzerinde bir yolu takip eden araba animasyonu gibi.
Video Oynatımı. JavaFx 'in kendi kütüphaneleri sayesinde (kendi video oynatıcı bile var) uygulamanızda online videolar gösterebilirsiniz.

JavaFx uygulamaları geliştirebilmek için javafx.com 'dan ücretsiz ve açık kaynak JavaFx SDK 'sını (yaklaşık 50 MB) indirmeniz yeterli. Ayrıca Sun'ın açık kaynaklı IDE'si Netbeans de (netbeans.org) JavaFx geliştirmek isteyenlere güzel bir çalışma ortamı sunuyor. JavaFx’i daha geniş incelemek için resmi sitesinde (javafx.com)  yayınlanan kaynaklara başvurabilirsiniz.

SQLite



Bu yazı daha önce saltokunur.org e-dergide yayınlanmıştır.

Şu senaryodaki durum masaüstü uygulamalar geliştiren çaylak-tecrübeli tüm geliştiricilerin başına gelebilir. Benim başına geldi oradan biliyorum :)

Programcının Çilesi
Hikâyemizde geliştiricimiz güzel bir program fikri bulur. Fikri gerçekleştirmek için platform, uygulama çatısı (Framework), programın yazılacağı dil... vb hazırdır. Geliştiricimiz programın işleyeceği verileri bir veri tabanında tutup, ilişkisel veri tabanlarının nimetlerinden faydalanmak istemektedir. İşte sorun da tam burada baş gösterir. Veri tabanı sunucusuna nasıl erişecektir? Uygulama masaüstü uygulama olduğu için çalışması için internet bağımlılığının olmaması gerekmektedir. Günümüz Türkiye şartlarında programı kullanan bütün bilgisayarların internete bağlı olamayacağı, olanların da zırt pırt kesilen bağlantı yüzünden programı adam gibi kullanamayacağı açıktır. Hem programcımız bu riski göze alıp, programı sürekli çevrimiçi olan veri tabanı (VT) sunucusuna bağlarsa, ücretsiz dağıttığı bir uygulama için bir VT sunucusu kiralamak zorunda kalacak, gelecekte belki programın kullanıcı kitlesi genişlediğinde o kadar veriyi tutacak VT sunucusu (VTS) bile bulamayabilecektir. Burada bir çözüm VTS'yi localhost'a kurup verileri bu şekilde işlemek olabilir. Ama şöyle bir gerçek var ki son kullanıcıların hepsi bir VT Yöneticisi değil. Düşünün bir kere dünyanın en çok kullanılan (bu yazıdan sonra aslında 2. olduğunu anlayacağınız :) MySQL'i uygulamanızla birlikte dağıttığınızı. Bugün en güncel MySQL 5.1 sürümü 104 MB, bir önceki 5.0 sürümü 22 MB [1]. Bu boyutta bir programı uygulama ile birlikte dağıtmak, kurulum dosyasını şişirmeye yarar, başka bir şeye değil. Hem MySQL'i kurduğumuzu düşünelim, kurmakla bitmiyor ki, root şifresi ayarlanacak, programın kullanacağı VT uygun karakter-kodlamayla oluşturulacak, MySQL hata verdiği zaman takip edilip düzeltilecek, dahası Windows güvenlik duvarı çalışmasına izin vermeyecek, gerekli olan port kullanımda olacak ve MySQL servisi başlatılamayacak. Biraz abartı gelebilir ama bu sorunlarım hepsi Windows üzerinde MySQL çalıştırılmak istenirken çok sık karşılaşılan sorunlar. Son kullanıcı bu sorunların hiçbiriyle baş edemez, onun için sadece "Next" vardır. "Next-Next-Next-(Bazen de Install :)"

Çözüm
Bu sorunun bir çözümü şu olabilir. Tecrübeli programcıların bile "Benden-Uzak-Allah'a-Yakın-Olsun" dediği, verileri bir dosyaya kaydetmek. Evet, çözüm basit gibi gözükse de programın işleyeceği verilerin yapısı karmaşıklaştıkça (bir VT'deki foreign key, trigger, function gibi yapıların getirdiği kolaylıkları düşünün) bunları bir dosya yapısına dökmek çoğu zaman geliştiricileri projelerinden soğutuyor. İşte bu ahval ve şerait içinde şöyle dediğinizi duyar gibiyim: "Keşke şöyle ne internete, ne sunucuya ne de ayara ihtiyaç duyan bir küçük program-kütüphane (library) olsa da, verileri VT biçiminde bir dosyaya kaydetse..."
Aslında yukarıda tırnak içinde yaptığım tanım SQLite için en basit ve anlaşılır tanım oldu. SQLite sunucu olmadan çalışan, hafif, küçük (tek bir dosya ve 500 KB den az), hiçbir ayara ihtiyaç duymayan, hızlı, SQL komutları kullanarak veri alış-verişi yapabilen bir ANSI-C kütüphanesidir. Kullanımı ise çok basittir. SQLite'ın kütüphane dosyasına (sqlite3.dll) SQL komutları gönderirsiniz, o da bu komutları işler ve bir VT dosyasına kaydeder. İstediğiniz zaman da SELECT sorguları çekerek bu dosyadan verilerinizi alabilirsiniz. Bu işlemler için ne bir ayar ne de bir kurulum gereklidir.

SQLite
SQLite, ilk olarak D. Richard Hipp tarafından geliştirilmeye başlandı ve 17 Ağustos 2000 tarihinde ilk sürümü yayınlandı. [2] İlk yayınlandığından bugüne kadar ki geçen zaman içinde temel VT işlemlerinin neredeyse tamamını gerçekleştirebilecek şekilde geliştirildi. Bu yazı yazıldığında en güncel sürümü 3.6.17 idi.
SQLite sadece bir C Kütüphanesi olduğu için, taşınabilirliği çok yüksektir. Günümüzün bilinen tüm platformlarında çalışabilir. Windows, Mac OS X, Linux, BSD, Solaris, UNIX, AmigaOS, Symbian, z/OS 1. [2]Gelecekte başka bir Veri Tabanı Yönetim Sistemi (VTYS)'ne geçilmek istendiğinde basit bir SQL sorgusuyla tüm veri alınıp rahatça diğer bir VTYS’ye geçilebilir.

Lisanslama
SQLite "Halka Açık" bir yazılımdır. Dağıtımı “Public Domain” [3] altında yapılmaktadır. Kaynak kodu açıktır. Yani SQLite'i istediğiniz gibi kullanabilir, kodunu değiştirebilir (uygulamanızın kullanmayacağı özellikleri kaldırıp yeni özellikler ekleyebilir), ücretsiz-ticari, açık-kapalı kaynak bütün uygulamalarda hiçbir kısıtlama altına girmeksizin kullanabilir, SQLite ile geliştirdiğiniz bir uygulamadan gelir de elde edebilirsiniz.

Teknik Özellikler [2]
Teknik özelliklerinden bahsetmek gerekirse SQLite için boyundan büyük işler başarıyor diyebiliriz.
  • En Fazla VT dosyası boyutu: 32 TB
  • Bir Tablodaki En Fazla Sütun Sayısı: 32767
  • En Fazla Metin (String-Char) Veri Boyutu: 1 GB
  • En Fazla Blob (Binary) Veri Boyutu: 1 GB
  • En Fazla Number (Int-Double) Veri Boyutu: 64 bit
SQLite’in bir güzel özelliği de tam Unicode desteği sağlamasıdır. UTF-8 ve UTF-16 kodlamayı destekler.
SQLite transactional (işlemsel) bir VT kütüphanesidir. Sık kullanılan birçok ilişkisel SQL cümleciğini destekler. Bunlar: Union, Intersect, Except, Inner join, Outer join, Inner select, Merge join. Ayrıca VT içinde Trigger tanımlamaya da izin verir.
Tarih (date) veri tipini ve data domain, cursor, function, procedure gibi işlemleri desteklememesi SQLite’in şu anki sürümü itibariyle eksik yönleri.

SQLite'in en geniş dağıtıma ulaşmış VT motoru olduğu tahmin ediliyor. Bugün birçok program, işletim sistemi, cep telefonu, PDA hatta Mp3 oynatıcılar bile gömülü olarak SQLite kullanıyor. SQLite siz farkına bile varmadan çoktan bilgisayarınıza girmiş olabilir. Örnek vermek gerekirse, Firefox (120 milyon kopya) internet geçmişinizi tutmak için bir SQLite VT'si kullanıyor. Eğer Windows ortamında Firefox kullanıyorsanız "C:\Program Files\Mozilla Firefox" dizini altında "sqlite3.dll" dosyasını bulabilirsiniz. Ya da bir müzik oynatıcı olan AIMP2 şarkı listelerini yine SQLite VT'sinde tutuyor. Bunun Linux dünyasındaki karşılığı ise KDE kullanıcılarının çok iyi bildiği amorak. Yine amorak playlist'lerini SQLite VT'sinde saklıyor. Örnekler çoğaltılabilir, bugün PHP5 (20 milyon kopya) varsayılan olarak SQLite desteğiyle geliyor. Solaris (10 milyon kopya) sistemi boot ekmek için,  Philips mp3 çalarlar yine playlist'leri saklamak için, Skype (100 milyon kopya), iPhone da SMS’leri saklamak için hep gömülü olarak SQLite kullanıyor. Tüm bu dağıtımların toplamının yaklaşık 300 milyon olduğu tahmin ediliyor. Bu da SQLite’i dünyanın en geniş dağıtımlı SQL motoru yapıyor. [4]

Kullanımı
SQLite harici uygulama olarak çalıştırılacaksa Linux'ta konsoldan ya da Windows'ta komut satırından "SQLite3 vt_dosyasi_adi" komutuyla çalıştırılır. vt_dosyasi_adi dosyası yoksa SQLite kendi oluşturur. Bundan sonra (;) ile biten SQL komutlarını programa girerek normal bir VT sunusu gibi kullanılır.
SQLite’in VT hakkında bilgi veren ve üzerinde çeşitli işlemler yapan, komut satırından çalıştırılan bazı özel komutları da vardır. [8]

·         Veritabanındaki tabloları görmek: sqlite> .tables 

·         Veritabanı konsolundan çıkmak: sqlite> .exit 

·         Kolon adlarını almak: sqlite> pragma table_info() 

·         Yardım: sqlite> .help  

·         Select çıktısına format vermek: 1. sqlite> .mode col 2. sqlite> .headers on  

·         Otomatik artan kolonun son değerini ele almak: sqlite> select last_insert_rowid();  

·         Veritabanını dışa aktarmak: sqlite> .dump  

·         Veritabanını sql scriptine aktarır: sqlite> .output file.sql  

·         Konsolda veritabanını kopyalamak: sqlite3 test.db .dump > test.sql 

·         SQL script ile veritabanında tablolar oluşturmak: sqlite3 test2.db < test.sql  


SQLite kütüphanesi bir program içinde gömülü olarak kullanılacaksa "#include " ile SQLite'in başlık dosyası kaynak koda eklenir. sqlite3_open() ile VT dosyası açılır, sqlite3_exec() ile SQL komutu işletilir ve sqlite3_close() ile VT bağlantısı kapatılır. [5]
SQLite'i gömülü olarak kullanmak için ille de C bilmeniz gerekmiyor. SQLite'in bilinen programlama dillerinin neredeyse tamamı için (C#, D, Delphi, Fortran, Java, Perl, PHP, Python, Ruby, Smalltalk…) sarıcı (wrapper) API’leri bulunuyor.[6] Böylece istediğiniz dilde uygulama geliştirirken SQLite’i kullanabiliyorsunuz.

Hız Karşılaştırmaları [7]
SQLite diğer VTYS'lerle karşılaştırıldığında INSERT sorgularında biraz geride kalıyor ama SELECT sorgularında çok daha hızlı sonuçlar veriyor.
Aşağıda SQLite 2.7.6, PostgreSQL 7.1.3 ve MySQL 3.23.41 kullanılarak yapılan hız testlerinin sonuçları yer alıyor. Süreler saniye cinsindendir. SQLite’in Nosync değerleri thread senkronlaması kapatılarak alınmıştır.

25000 INSERT Bir sorguda

100 SELECT indeksiz

1000 UPDATE indeksiz

SELECT’ten INSERT

DELETE indeksli

5000 SELECT indexli

PostgreSQL
4.900
3.629
1.739
61.364
1.316
4.614
MySQL
2.184
2.760
8.410
1.537
2.262
1.270
SQLite
0.914
2.494
0.637
2.787
2.068
1.121
SQLite (nosync)
0.757
2.526
0.638
1.599
0.752
1.162

SQLite üzerinde daha geniş araştırma yapmak isteyenler www.sqlite.org daki wiki'de kullanım, yönetim, bakım hakkında çok yararlı makaleler bulabilirler.

Kaynaklar
[5] M. Ali Vardar, Linux ve UNIX Sistemler İçin Açık Kaynak Kodlu Yazılım Geliştirme, Temmuz 2008

QT Jambi

Bu yazı daha önce saltokunur.org dergisinin Şubat 2010 sayısında yayınlanmıştır. QT Jambi’nin 4.5.2 sürümü temel alınarak hazırlanmıştır.
 
Java serüveninize hevesle başladınız ve her yeni başlayan gibi bir an önce görsel programlar yapmak istediniz. Ama Java'nın sunduğu arayüz kütüphanesi Swing o kadar zordu ki bir türlü istediğiniz görsellikte programlar ortaya çıkaramadınız. Belki de sırf bu yüzden bu güzelim programlama dilinden vazgeçtiniz ve başka dillere yöneldiniz. Gerçek şu ki Java'da arayüz programlamak için Swing'e mahkum değilsiniz. Karşınızda: QT Jambi
 


2008 yılında PcNet dergisinde Türkiye'deki yazılım sektöründe hangi dillerin revaçta olduğunu inceleyen bir yazı okumuştum. Yazıda Türkiye'nin önde gelen yazılım firmalarının görüşlerine yer verilmişti. Yazının özeti şu idi: "Programlama dili olarak Türkiye'de C# ve Java en çok tercih edilenlerdir. Bu dilleri biliyorum diyen hiçbir kimse işsiz kalmaz." Bugün baktığımızda yazının üzerinden 2 yıl geçmiş ve popüler dillerin C# ve Java olduğu gözlemi hala geçerliliğini koruyor.

Bu dillerden C#, arkasında Microsoft olduğu ve Türkiye'deki son kullanıcıların neredeyse tamamının bu firmanın ürünlerini kullandığı, öğrenilmesi ve uygulaması kolay olduğu, kullanıcıların tamamının kullandığı bir platforma görsel nitelikleri ön planda olan yazılımlar geliştirmeyi çok basit bir hale getirdiği için tercih ediliyor.
Java ise, Windows platformlarının virüs belasıyla uğraşmak istemeyen, verilerinin güvenliğini ön planda tutan büyük şirketler tarafından tercih ediliyor. Bir diğer önemli etken ise açık kaynak ve taşınabilir olması. Bir yazılımın açık kaynak olması sizin için çok şey ifade etmiyor olabilir. Açık kaynak yazılımın avantajı şöyle özetlenebilir: Yazılım geliştirmeyle uğraşan herkesin kodlarına bakarak program hakkında bir fikir yürütebilmesini sağlıyor ve böylece kaynağının ve üzerinde değişiklik yapabilme yetkisinin sadece belli bir kesime açık olduğu projelerden çok daha hızlı gelişebiliyor ve daha yetenekli oluyor. Bugün buna en güzel örnekler binlerce Firefox eklentisi ve Java tarafında yazılım gelişmeye yardımcı onlarca Framework. İşte bu artıları Java'yı ön plana çıkarıyor.

Arayüz Kodlamak Mı? Swing'le Asla!
Java'nın bu rekabette en büyük dezavantajı her şeyi taşınabilir hale getirmeye çalışması. Her şeyi taşınabilir hale getirmeye çalışmakla bir çok önemli noktada tavizler veriyor ve sadece belli bir platforma destek veren teknolojilerden geri kalıyor. Örneğin Java'ya yeni başlayan birinin kolaylıkla öğrenip diğer kütüphanelerle yapılabilecek kadar güzel görsellikte arayüzler tasarlamaya imkan veren resmi (resmi diyorum, çünkü konumuz 3. parti bir kütüphane olan QT Jambi) bir kütüphanesi bulunmuyor. Java'nın sağladığı Swing arayüz kütüphanesi öğrenilmesi çok zor ve albenili programlar yapılabilmesi için üzerinde çok çalışılması gereken, zamanının gerisinde kalmış bir kütüphane. Bugün piyasada Swing ile tasarlanmış çok az program görebilirsiniz. Bir çarpıcı örnek de şu ki, Java'da yapılmış bir tane bile video oynatıcı uygulama yok. Çünkü Java güncel hiçbir codec'i desteklemiyor. Bir kaç tane müzik oynatıcı program var onlar da ancak 3. parti kütüphaneleri kullanarak (JLayer) güncel codec'lere destek sağlıyor. Tüm bir JRE (Swing, AWT, I/O, Networking, Math, Collections) yaklaşık 13 MB iken, yazımızın konusu olan QT Jambi sadece GUI tasarımı için sunulan yaklaşık 20 MB'lık bir kütüphane. QT Jambi'nin eksi tarafı ise bir ölçüde taşınabilirlikten ödün vermesi. Çünkü her platform için, arayüz bileşenlerinin ekrana nasıl render edileceğini spesifik olarak belirten platforma özel bir .jar dosyasını uygulamaya eklemek gerekiyor. Aslında bir .jar dosyasını değiştirmek taşınabilirlikten çok da ödün vermek olmasa gerek.

QT Jambi Nedir?
Yazımızın konusu olan QT Jambi bir Java GUI kütüphanesi. QT'yi muhtemelen duymuşsunuzdur. QT C++ dilinde yazılmış, tüm platformlarda çalışan bir arayüz kütüphanesidir. Linux kullanıcılarının çok iyi bildiği KDE masaüstü ortamı ve çeşitli programlar (Skype v.b.) bu kütüphane ile yazılmıştır. QT Jambi ise QT'nin Java dilinde kodlanmış (Port edilmiş) halidir.

QT Jambi temelde iki ayrı lisansla dağıtılıyor. Ücretsiz ve açık kaynak olan LGPL versiyonu ve ticari versiyonundan istediğinizi ihtiyaçlarınıza göre seçebilirsiniz.

QT Jambi günümüzün popüler birçok platformunda çalışır. Uygulama bir kez Java'da derlendikten sonra asıl uygulamanın yanına platforma özgü kütüphaneleri ekleyerek, Java'nın “bir kere yaz her yerde çalıştır” mantığıyla program geliştirmeye devam edebilirsiniz.

QT Jambi'nin bence en önemli özelliği ise Olay İşleme (Event Handling)'ye getirdiği yeni yaklaşım. Signal (Sinyal) – Slot (Yuva) mekanizması sayesinde ne olayı oluşturan nesne ne de olayı alan nesne birbirinden haberdar olmak zorunda kalmıyor ve Loose Coupling'in başarımı büyük ölçüde sağlanıyor.
QT Jambi varsayılan olarak programlara çoklu dil desteği sağlıyor. Kaynak kodda String olarak yazılan her ifade tr(String) metodu içinde yazılır. Daha sonra bu String ifadeler bir dil dosyasında toplanır. Programın çalışması sırasında dinamik olarak dil dosyalarından bu ifadeler çekilerek ekranda istenilen dilde gösterilir.

QT Jambi ile Çalışmak
QT Jambi'yi http://qt-jambi.org/downloads/ adresinden indirebilirsiniz. İndirme sayfasındaki dosyalardan kendi platformunuza uygun sürümünü (Linux için qtjambi-linux32-lgpl-) seçtiğinize emin olun. Sıkıştırılmış dosyanın içinden çıkan qtjambi-xxx.jar ve qtjambi-linux32-gcc-xxx.jar dosyalarını herhangi bir IDE'ye kütüphane olarak ekledikten (aslında sadece CLASSPATH'e eklemeniz yeterli) sonra QT Jambi ile uygulama geliştirmeye başlayabilirsiniz. Aynı adreste QT Jambi'nin Eclipse IDE'si için pluginini de bulabilirsiniz. Bu pluginle Eclipse üzerinde görsel olarak QT Jambi geliştirebilirsiniz.
İndirdiğiniz sıkıştırılmış dosya QT Jambi ile uygulama geliştirmek için gerekli her şeyi içerir.
Designer: Görsel bir şekilde QT Jambi uygulamaları tasarlayabileceğiz program. Tasarladığınız arayüzü .jui (Designerda tasarlanan arayüz elemanlarının yerleşimlerin tutulduğu bir XML dosyası) uzantısıyla kaydedip, qtjambi-linux32-lgpl-xxx/bin klasörünün içindeki juic programıyla derlenebilir .java kodlarına dönüştürebilirsiniz. Ama en kolayı Eclipse pluginini kullanıp her şeyi Eclipse'in halletmesini sağlamak.



QtJambi-Examples: Kaynak kodlarıyla birlikte verilen, açıklamalı QT Jambi örnekleri.















QT Jambi Doc: Referans belgeleri.
Bunların dışında asıl QT'nin C++ sürümüyle birlikte gelen ancak biraz C++ biliyorsanız QT Jambi'nin mantığını anlamada size yardımcı olabilecek şu araçlar da var.
QT Creator: Designer'ın daha gelişmiş C++ sürümü.
QT Assistant: QT ile ilgili herşey. Sınıfların ayrıntılı açıklamaları, adım adım örneklerin incelemeleri, herşey... QT ve QT Jambi ile uygulama geliştirirken ilk başvuru kaynağınız olacak.
Qt Linguist: QT'nin yerleşik çoklu dil desteğini veren, String ifadeleri dil dosyalarına dönüştüren program.
 
QT Jambi Paketleri
QT Jambi'nin 4.5.2 sürümüyle gelen paketler ve bu paketlerdeki sınıflar ise şunlar:
com.trolltech.qt ve com.trolltech.qt.core: Çekirdek QT Jambi sınıfları.
com.trolltech.qt.designer: Designer uygulamasının kullandığı sınıflar.
com.trolltech.qt.gui: Buton, Label, TextBox, Table gibi temel arayüz elemanlarının sınıflarının bulunduğu paket.
com.trolltech.qt.network: QT Jambi'nin ağ iletişimi yapabilmesini sağlayan sınıflar. Bu paketteki sınıflar sayesinde QT Jambi ile Server/Client yazılımlar hazırlanabilir.
com.trolltech.qt.opengl: Uygulamalarınıza OpenGL'in gücünü katabileceğiniz QT Jambi paketi.
com.trolltech.qt.phonon: Multimedia uygulamaları geliştirebileceğiz QT Jambi paketi. Bu pakette çok güçlü sınıflar bulunuyor. Sadece bir sınıfın örneğini oluşturarak çok kolay bir şekilde bir video player (com.trolltech.qt.phonon.VideoPlayer), bir ses ayar düğmesi (com.trolltech.qt.phonon.VolumeSlider) veya bir video içinde gezinme çubuğu (com.trolltech.qt.phonon.SeekSlider) oluşturabilirsiniz.
com.trolltech.qt.sql: Bu kadar desteği sağlayan Qt Jambi, SQL'den de geri durmuyor. Bu paketin içinde günümüzün en çok kullanılan veritabanları için sürücüler bulunuyor. Normal Java uygulaması yazarken bir JDBC sürücüsü eklemek gerekirdi halbuki.
com.trolltech.qt.svg: SVG dosyalarını okuyup yazabilen sınıfların bulunduğu paket.
com.trolltech.qt.webkit: Web sitesi gösterebilme yeteneği olan uygulamalar geliştirebilmek için gerekli sınıflar...
com.trolltech.qt.xml ve com.trolltech.qt.xmlpatterns: QT Jambi bu paket sayesinde XML dosyalarını başka 3. parti kütüphanelere gerek kalmadan işleyebiliyor.

Çığır Açan Signal-Slot Sistemi
Signal-Slot sistemi Qt Jambi'nin olay işlemeye getirdiği yeni bir yaklaşımdır. Bu yaklaşımı daha iyi anlayabilmek için, Swing'in klasik olay işleme mekanizmasına değinip Signal-Slot sistemi ile karşılaştıracağız.
Swing'de arayüz bileşenleri seçme, butona tıklama, enter'a basma vb gibi olay nesneleri üretir. Bu olayları işlemek için, olaylar oluştuğunda yapılacak işlerin belirtildiği olay dinleyici sınıfları yazılır ve hangi olay takip edilecekse, bu sınıfların nesneleri ilgili arayüz bileşenini dinlemek üzere ayarlanır.
Örneğin bir butona tıklandığında mesaj gösterilmek isteniyorsa, önce Buton nesnesi oluşturulur.

JButton but=new Jbutton("Tıkla");

Sonra bu butona tıklandığında çalışacak kodların bulunduğu bir sınıf yazılır. Bu sınıf butonda oluşan her farklı
olay tipi için ayrı bir metot içerir.
 
public class OlayDinleyici implements ActionListener
{
 Object olayiOlusturanNesne;
 
 //tıklama olaylarında çalışacak metod
 public void actionPerformed(ActionEvent e)
 { 
  //Mesaj Göster
   olayiOlusturanNesne.herhangiMetod();
 }
}

Sonra da bu sınıfın bir nesnesi olayları oluşturan buton nesnesine eklenir.

but.addActionListener(new OlayDinleyici());

Bu tip bir yaklaşımla olay işlemek hem karmaşık, hem kodlaması zor, hem de baş edilmesi zahmetlidir. Ayrıca hem dinleyici sınıfta hem de olayı oluşturan sınıfta birbirlerinin nesnelerine bir referans bulunmasını gerektirir. Bu zorunluluk sınıfların içiçe geçmesine ve uygulamanın karmaşıklığının artmasına neden olur.

Bu soruna QT Jambi'nin getirdiği çözüm ise çığır açacak niteliktedir. Bu yaklaşım olayı oluşturan ve takip eden sınıfların birbirinden haberdar olmasına gerek olmaması temeline dayanır. QT Jambi'de arayüzde oluşan her olay (tıklama, enter'a basma) bir Signal'dir. Örneğin bir butona tıklandığında tıklama Signal'i oluşur. Signal'ler üzerinde değer taşıyabilir. Yani arayüzde bir olay oluştu ve olayı gerçekleştiren nesne de bir değer ürettiyse, üretilen değer Signal'le birlikte gönderilir. Örneğin bir textbox'a değer girildiğinde textChanged olayı oluşur. Textbox sınıfının "textChanged Signal'i" üzerinde textbox'ın metnini taşır.

Olay oluştuğunda çalışacak kodlar ise Slot'lardır. Slotlar arayüzdeki bir bileşenin bir metodu olabileceği gibi sizin yazdığınız metotlar da olabilir. Signaller üzerinde connect(QObject alici, String slot) metodunu çağırarak Signalleri Slotlara bağlamış olursunuz. Böylelikle olay yönetimi Swing'den çok daha basit bir şekilde çözülmüş olur.



Örneğin ekrandaki bir butona basıldığında uygulamadan çıkmak istiyorsunuz. Yazacağınız kod sadece şudur.

QPushButton but=new QPushButton("Çıkış");
but.clicked.connect(QApplication, "quit()");

Burada bir buton nesnesi oluşturuyoruz ve bu butonun "tıklanma" Signal'ini uygulamamızın (QT'de her uygulama bir QApplication nesnesidir) "quit()" metoduna bağlıyoruz. Böylelikle butona tıklanınca uygulama kapanmış oluyor.

Yukarıdaki textbox örneğimizi koda dökmek istersek: Textbox'a girilen değerin enter'a basıldığında bir label'da görüntülenmesini istiyoruz. Aşağıdaki üç satır kod bunun için yeterli.

QLineEdit txtBox=new QLineEdit();
Qlabel label=new QLabel();
txtBox.textChanged.connect(label, "setText(String)");

Burada bir textbox ve bir label oluşturuyoruz. Sonra Signal-Slot mekanizması kendini gösteriyor. txtBox'ın textChanged (yazı değişti) Signal'i değişen yazıyı Signal ile birlikte gönderiyor. Bu Signal'i label'ın setText(String) metoduna bağlıyoruz. Böylelikle txtBox'da bir değişim olduğunda label'da metin görüntülenmiş oluyor. Böyle bir uygulamayı Swing ile yapmaya çalışırsak öncelikle txtBox'ın içindeyi metni txtBox.getText() ile almamız, sonra label'da bu yazıyı göstermemiz gerekirdi. İşte Signal-Slot yapısının gücü.



Ben Geldim Dünya!
QT Jambi'de en temel sınıf QObject'tir. Bütün sınıflar bu sınıftan kalıtım alır. Arayüz bileşenlerinin temel sınıfı ise QWidget'tir. QWidget'ten kalıtım alan bütün sınıflar ekranda bir bileşen olarak gösterilebilir. Siz de bu sınıfı genişleterek kendi arayüz elemanlarınızı yazabilirsiniz.

QMainWindow ve QDialog QT Jambi'nin pencere sınıflarıdır. Bu sınıflara eklenen QWidget nesneleri pencerelerde gösterilir. Eğer bir QWidget nesnesi bu sınıflardan herhangi birine eklenmezse bu nesne üzerinden show() metodu çağrılarak ayrı bir pencerede göstermesi sağlanabilir.

Bir QT Jambi uygulaması QApplication.initialize(String[]) statik metodu çağrılarak hafızaya yüklenir. Bu satırdan sonra programın kodları yazılır, en son olarak da QApplication.exec() çağrılarak program çalıştırılır.
İşte Hello World örneğimiz. HelloWorld.java adıyla kaydedip, derleyip, çalıştırabilirsiniz.
import com.trolltech.qt.gui.*;

public class HelloWorld {

    public static void main(String[] args) {

        QApplication.initialize(args);

        //Buraya uygulamayı oluşturan kodlar gelir.
 QLabel hello=new QLabel("Hello World");
 hello.resize(120, 40);
        hello.setWindowTitle("Hello World");
        hello.show(); 
 //uygulama kodu sonu

        QApplication.exec();
    }
}



Şimdi de QWidget sınıfını genişleterek oluşturduğumuz kendi sınıfımızın bir nesnesini gösteren bir örnek yapalım (Signal-Slot kısmında anlattığım TextBox-Label örneği). AnaPencere adında QWidget'i genişleten bir sınıf yazıyoruz. Bu sınıfa bir Label ve bir TextBox ekliyoruz. Layout (Yerleşim) düzenini ayarlıyoruz. main() metodunun içinde bu sınıfın bir örneğinin oluşturup, üzerinden show() metodunu çağırıyoruz. Kodu AnaPencereDeneme.java adıyla kaydedin.

import com.trolltech.qt.gui.*;

class AnaPencere extends QWidget{

    public AnaPencere() {

        QVBoxLayout box=new QVBoxLayout();
        QLineEdit txtBox=new QLineEdit();
        QLabel label=new QLabel();

        box.addWidget(txtBox);
        box.addWidget(label);
        setLayout(box);     
        line.textChanged.connect(label, "setText(String)");
    }
}

public class AnaPencereDeneme {

    public static void main(String[] args) {

        QApplication.initialize(args);

        AnaPencere main=new AnaPencere();
        main.show();

        QApplication.exec();
    }
}

Ben QT Jambi ile kod yazarken Swing'e göre daha çok eğlendim. QT Jambi ile neler yapılabileceği hakkında fikir edinmek istiyorsanız, birlikte gelen örnekleri incelemenizi tavsiye ederim. Örnekleri görünce şaşıracağınıza eminim. Bazıları: Video oynatıcı, müzik oynatıcı, Excel gibi bir hesap tablosu programı, ekran görüntüsü alma programı, tetris oyunu, OpenGL uygulamaları, online anlık mesajlaşma yazılımı, web tarayıcı, windows kenar çubuğu araçları gibi masaüstünde yüzebilen başlık çubuğu olmayan araçlar, HTTP sunucuları, programlama diline göre o dilin reserved (ayrılmış) kelimelerini (for, if, while...) farklı renkte gösteren kod editörleri, sistem tepsisinde (tray) çalışan uygulamalar...

İnternet'te QT Jambi ile ilgili çok örnek yok, genelde uygulamalar QT (C++) ile yazılmış. Ama C++ örneklerini inceleyerek de Java'da neler yapmanız gerektiği hakkında fikir sahibi olabilirsiniz, sonuçta programlama dillerinin mantığı hep aynı.

Benim QT hakkında araşma yaparken karşılaştığım tek Türkçe kaynak olan Çanakkale Onsekiz Mart Üniversitesi bünyesindeki QT Türkiye Topluluğu'nu da gayretli çalışmalarından dolayı tebrik ediyorum. Eğer siz de QT ile devam etmeye karar verirseniz, lütfen öğrendiklerinizi bu toplulukta paylaşın ki QT hakkındaki Türkçe belge sayısı artsın.

Aslında QT Jambi hakkında anlatacak çok şeyim vardı. Ama bu genel bir tanıtım yazısı ve verilebilecek daha ileri seviye örnekler tanıtım yazısının sınırlarını zorlayacak nitelikte. Bundan sonrası merakınıza ve araşmacılık duygunuza kalıyor.
Peygamber Efendimiz'in bir hadisiyle bitirelim: “Merak İlmin Hocasıdır.”

Gelecek ay görüşmek dileyiğle.
Sağlıcakla kalın, Saltokunur'la kalın.

Kaynaklar
http://qt.comu.edu.tr
http://qt.nokia.com

Firefox: Neden mi?

Technorati Etiketleri: ,

Bu yazı daha önce saltokunur.org adlı e-dergide yayınlanmıştır.

Firefox en basit tarifiyle "internet sitelerini görüntülemek" için kullanılan bir programdır. Bu basit açıklama her ne kadar Firefox'un işlevini anlatmak için yeterli olsa da, internette gezinmeyi günlük bir iş olmaktan çıkarıp, bir eğlenceye dönüştüren, müzik çalabilen, günlük işlerinizi planlayabilen, notlar alabilen, hatta küçük çaplı veri tabanlarını kontrol edebilen özellikleri göz önüne alındığında, hayli eksik kalır. Firefox internette gezinmeye bambaşka bir bakış açışı getirmiştir: Firefox kullanarak internette gezinme. 5000 e yaklaşan eklenti ve tema sayısıyla Firefox şekilden şekle, işlevden işleve bürünebilir. Size ise sadece bu güzel programı hangi hayat kolaylaştıran eklentilerle kullanacağınıza karar verip internetin keyfine bakmak kalır.

Açık kaynak yazılım felsefesiyle geliştirilen Firefox, bunu faydasını dünyanın her yerinden Firefox severlerin geliştirdiği binlerce eklenti ile görmüştür. Firefox, onun bu güzel özelliklerini başkalarına anlatmayı görev edinmiş kullanıcılara da sahiptir. Firefox tanıtım bannerlarını çoğu internet sitesinde görebilirsiniz. Bu kullanıcıların başarılı bir şekilde örgütlenmesiyle 2008 yazında Firefox 3 sürümü çıkmadan aylar önce tüm dünyada tanıtım çalışmaları yapıldı. Program kullanıma sunulduğu ilk gün 8 milyon indirmeyle bir günde en çok indirilen program dalında Guinness rekoru kırdı.




Firefox'un belki de en önemli özelliği kullanıcısına istediği esnekliği vermesidir. Bundan da önemlisi bu esnekliği verirken güvenliği elden bırakmamasıdır. Firefox internette gezinme keyfinizi bölen "Bu siteye güveniyor musunuz?" sorularıyla tadınızı kaçırmaz. Siz internette gezerken güvensiz bir siteyle karşılaştığında resimdeki gibi bir mesajla uyarı verir. Böylece siz de söz konusu sitenin zararlı olduğunu bilirsiniz. Böylece esnekliği ve güvenliği en üst düzeyde sağlar.


Firefox bir siteye ait parolanızı kaydetmek isteyip istemediğinizi sorarken, sizi soruya cevap vermek zorunda bırakmaz. Pencerenin üst kısmında bir çubuk belirir. İsterseniz bu çubuktan soruya cevap verebilir, isterseniz de aldırmayıp internette gezinmeye devam edebilirsiniz.

Dosya indirirken her defasında nereye kaydedeyim diye sormaz. Gerçekten indirmek istediğiniz dosya ile site tarafından reklam amaçlı olarak otomatik indirilmeye çalışılan bir dosyanın farkını bilir. Gerçekten indirmek istediğiniz dosyayı engelleyip sinirinizi bozmaz.

Firefox'un albenisini artıran bir diğer özelliği de yüzlerce tema desteği ile çok çeşitli şekillere girebilmesi. Örneğin sizin de fotoğraftaki gibi cıvıl cıvıl bir tarayıcınız olabilir. Hatta Firefox'u açılışta sizi en sevdiğiniz oyunun duvar kağıdıyla karşılayacak şekilde ayarlayabilirsiniz.


Birden fazla sekme açtınız ve aniden bilgisayarınız kapandı. Firefox tekrar açışınızda tüm sekmeleri geri yükler. Herhangi bir metin kutusuna yazdıklarınız bile kaybolmadan geri gelir.
Firefox, kapanırken geri döndüğünüzde eski haliyle bulasınız diye oturumunuzu kaydetmenize izin verir.


Sağına soluna istediğiniz butonu koyup, tüm işinizi bir pencereden yönetebilirsiniz.
Adres çubuğu arka planda Google ile birlikte çalışır. Yazdığınız metin sık kullanılanlar arasında ise hemen oraya bağlanır. Değilse de yazdığınız metnin Google araması karşınıza çıkarır. Sadece adres yazmak zorunda da değilsiniz. Daha önce gezdiğiniz sayfaların başlığını bile yazmanız Firefox'un istediğiniz adresi size getirmesi için yeterlidir.


Sayfa üzerindeyken klavyede bir şeyler yazmaya başladığınızda hemen altta arama çubuğu belirir ve aradıklarınıza çok hızlı bir şekilde ulaşabilirsiniz.


Şimdi Firefox'un bu mükemmel özelliklerine daha iyilerini ekleyen eklentilerine bakalım.
Eklentilerle ilgili bir tavsiye: Yeni bir eklenti kurduğunuzda mutlaka Araçlar > Eklentiler üzerinden ayarlarına bakın.
AdBlock: Can sıkıcı reklamlara veda.
Add to Seach Bar: Bu eklenti ile herhangi bir sitenin arama özelliğini tarayıcınıza ekleyebilirsiniz. Bunun için eklemek istediğiniz sitenin arama kutusuna sağ tıklayıp "Arama Çubuğu Ekle" demeniz yeterli. Böylece IMDB'ye girmeden tarayıcınız üzerinden Tarantino'nun başyapıtı "Pulp Fiction" ı aratabilirsiniz :)


Colorful Tabs: Sekmelerinizi renklendirir. İsterseniz rastgele isterseniz kendi seçeceğiniz şekilde.


Context Seach: Bir metni seçip sadece sağ tıklayarak arama yapabilirsiniz. Kopyalayıp arama kutusuna yapıştırmanıza gerek yok. (Add to Seach Bar ile ekledikleriniz de dahil :)
Ctrl+Tab: Alt+Tab özelliği Firefox'ta. Yalnız Ctrl+Tab olarak :)
Cute Menus: Daha güzel menüler.
Download Statusbar: Editörün Tavsiyesi. İndirme işleriniz ana pencerenin altında bir çubukta gösterilir. Böylece indirme işlerinizi Firefox pencesinden ayrılmadan tek bir yerden yönetebilirsiniz.


Down Them All: İndirme yöneticisi. Sayfadaki nesneleri dosya türüne göre toplu indirme gibi özellikleri var.
Fast Dial: Açılış sayfasına en çok ziyaret ettiğiniz sitelerin ön izlemelerini koyabilirsiniz. Arka plana fotoğraf koyma özelliği de bu eklentiyle geliyor.
FFchrome: Bir sürü eklenti yüklediniz sağ tık menüsü çok mu doldu? Bu eklenti ile sağ tık menüsünde az kullandığınız özellikleri gruplayıp bir alt menüde gizleyebilirsiniz.
FlashGot: Editörün Tavsiyesi. Firefox'u indirme yöneticileriyle ilişkilendirir. Dosya indirmek istediğinizde indirme seçenekleri arasına seçtiğiniz indirme yöneticisini ekler. En önemli özelliği ise, sayfada bir video oynatılıyorsa tek tıkla indirmenizi sağlar.


FireFTP: Firefox'u ftp istemcisine dönüştürür.
FoxyTunes: İnternette gezerken müzik mi dinliyorsunuz? Artık oynatıcınızı yönetmek için Firefox penceresinden ayrılmak zorunda kalmayacaksınız.



Her Google hizmeti için bir Firefox eklentisi bulabilirsiniz. Kullandığınız servise göre şu eklentileri deneyebilirsiniz.
Google Not Defteri
Gmail Chechker
Google Reader Watcher
Gogle Translate
Search Preview: Editörün Tavsiyesi. Google arama sonuçlarına bulunan sayfanın ön izlemesini de ekler.


Greasemonkey: Bu eklenti ile Firefox'a kendi yazacağınız betikleri (script) ekleyebilirsiniz. Örneğin RapidShare Link Checker'ı eklediğinizde siz daha rapidshare.com a gitmeden linkin çalışıp çalışmadığını kontrol eder, çalışmıyorsa üzerini çizer.


Any Color: Firefox’u renklendirin.

In Form Enter: Editörün Tavsiyesi. Metin girilen alanların yanına bir buton ekler. Bu butona basarak daha önceden kaydettiniz bilgileri (ad, soyad e-posta) tekrar tekrar yazmadan otomatik olarak formlara girmenizi sağlar.


NoScript: Sayfalardaki JS betiklerini engelleyerek, Firefox'u daha güvenli hale getirir.
PDF download: Sayfayı pdf olarak kaydeder.
QuickNote: Sayfada seçtiğiniz metinleri tek tıkla hard disk üzerinde bir metin dosyasına kaydeder. Hızlı Not almak için birebir :)
Toolbar Buttons: Firefox'un her tarafını butunlarla doldurmanızı sağlayan eklenti.
Update Notifier: Eklenti güncelleştirmelerini takip eder. Bulursa otomatik indirip yükler.
WebMailNotifier: Editörün Tavsiyesi. Belirttiğiniz sıklıklarla e-posta kutunuzu kontrol eder ve uyarır.


Son olarak, hala Firefox'u denemediyseniz "Bir Şansı Hak Ettiğini" söyleyebiliriz.