Adobe Flex ve XML-1: DataGrid Bileşeni İçerisinde XML Verilerini Göstermek ve Formatlandırmak
İlyas Doğruer Tarih: 7/09/2007 Yorum: 0 adet
Okunma : 484 Tutanlar: Bu yazıyı 0 kişi tuttu.
Merhabalar,
Bu yazımızda Adobe Flex ile XML formatındaki verilerin işlenmesi hakkında konuşacağız. Öncelikle XML (Extensible Markup Language – Genişletilebilir İşaretleme Dili)’den bahsedelim biraz. Bir çoğunuzun bildiği gibi web veya masaüstü programcılığında, programlar arasında veri iletişimini büyük ölçüde XML yükleniyor. XML’in bir çok alanda kullanılmasının temel sebebleri arasında sadelik, okuma-yazma kolaylığı, platform bağımsız her yazılım ile çalışabilme özelliği v.b sebebler sayılabilir. Bugün XML, Adobe Flash ile veritabanından veri okurken veya Flash içerisinde text ve resim alanlarını dışardan yüklerken, haber-döviz kurları-hava durumu bilgilerini dinamik olarak web sayfalarında gösterirken, cep telefonları ile multimedia mesaj gönderirken, bir fabrikada bilgisayar kontrollü makinalar yönetim yazılımı ile haberleşirken v.b gibi çok farklı alanlarda başarı ile kullanılmaktadır.
Evet genel olarak XML’den bahsettikten sonra, Flex içerisinde ilk olarak DataGrid bileşeni içerisinde XML dosyamızdaki verilerin gösterilmesini inceleyeceğiz. XML dosyamızdan alacağımız verilerimizi DataGrid bileşeni içerisine aktarırken, verilerimizi kendi belirlediğimiz formatlarda ve istediğimiz yerde nasıl gösterebileceğimizi göreceğiz.Bu uygulama için ben bir XML dosyası oluşturdum. XML dosyamızda bir öğrencinin numara,isim, soyisim, doğum tarihi, doğum yeri, ana adı, baba adı ve puan bilgilerini saklayabileceğimiz yapılar oluşturdum.
Şimdi Adobe Flex içerisinde XML verilerimizi yükleteceğimiz DataGrid bileşenini inceleyelim. DataGrid bileşeni, satır sütunlardan oluşur. Satırların herbiri bir üye alanını, sütunlar ise bu üyenin sahip olduğu farklı değişkenler ve değerlerini oluşturan alanlar olarak tanımlanabilir. [Bkz. Resim-1]
Flex ile geliştirilen bir uygulamada XML içerisindeki verileri Flex içerisindeki bileşenlere aktarmanın birden fazla yöntemi var. Bunların en çok kullanılanı HTTPService’tir. HTTPService ile XML veya başka bir veri yüklemek oldukça basit. HTTPService, üzerinden yüklenecek olan verileri yükleyebilmek için send() methoduna ihtiyaç duyar. Bunu uygulama başladığında çalışacak fonksiyonlar için hazırlanmış creationComplete veya initialize ile yapabiliriz. Uygulama içerisinde <HTTPService/> tagını oluşturduktan sonra geriye sadece HTTPService parametrelerine değerlerini atamak kalıyor. Bunlar id, url ve request gibi parametreler.
Not: Serverda çalıştıracağınız uygulamalar için HTTPService url parametresine dosyanın serverdaki tam yolunu girmelisiniz.
Şimdi Adobe Flex’i açarak yeni bir proje oluşturuyoruz ve projemiz içerisinde HTTPService taglarını oluşturmaya başlıyoruz. En basit yöntem ile HTTPService XML’i aşağıdaki gibi yükler.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:HTTPService id="myHTTP" url="data/database.xml"/>
<mx:DataGrid id="myGrid" datataProvider="{myHTTP.lastResult.otomasyon.ogrenci}"/>
</mx:Application>
Burada initialize ile uygulama ilk yüklendiğinde myHTTP id ismine sahip olan HTTPService‘ın url parametresi ile belirtilen dosyayı uygulamaya yükleme işlemini yapıyoruz. HTTPService’ın dataProvider parametresi ise içeriğinin kaynağını belirtiyor. dataProvider içerisinde myHTTP id isimli HTTPService in yükletmiş olduğu dosyadaki verilerin hiyerarşik yolu belirtiliyor. XML dosyamız içerisinde <otomasyon></otomasyon> ana tagı, ve <ogrenci></ogrenci> ise alt tagları oluşturuyor.
Evet yukarıdaki kodlar en basit haliyle XML içerisindeki verileri DataGrid bileşenimize aktarıyor. Biz yukarıdaki yükletme işlemini değilde biraz daha farklı bir yükletme işlemi kullanalım. XML içerisindeki verilerimizi bir ArrayCollection‘a atayabiliriz. XML içerisindeki verilerimizi göz önüne aldığımızda her bir öğrenciyi bir dizi olarak düşünebiliriz, çünkü birden fazla değişkene sahip. Yine XML içerisinde birden fazla öğrenci bilgisini tuttuğumuz için ArrayCollection (Dizi Kolleksiyonu) bizim için uygun tip tanımıdır diyebiliriz.
Uygulamamız içerisinde HTTPService’in result parametresine myResult() isminde bir fonksiyon belirtelim. <mx:Script> bloğu açalım ve içerisinde öncelikle bir adet ArrayCollection tipinde bir değişken tanımlayalım ve sonra HTTPService‘in result parametresinde belirttiğimiz fonksiyonumuzu oluşturalım. Bu fonksiyon ogrenciler isimli ArrayCollection değişkenimize XML içerisindeki verileri aktaracaktır. Fonksiyonumuzun event parametresi ResultEvent tipine sahip olup event.result sonucu XML dosyamız içerisinden verilerimizi çekmemizi sağlayacaktır.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult(event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
]]>
</mx:Script>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}"/>
</mx:Application>
Dikkat ettiyseniz DataGrid içerisinde sütunların herbiri bir başlığa sahip (headerText). Bu başlıklar, yukarıda yaptığımız yükleme için varsayılan olarak XML içerisindeki <ogrenci> tagının sahip olduğu alt tagların isimlerini almıştır.
Genellikle uygulamalarımızda bu başlıkların daha düzenli olmasını isteriz. Mesela başlıkların istediğimiz sıraya göre dizilmesini istiyoruz ama başlıklar XML içerisindeki sıraya göre diziliyorlar. Bunu XML içerisinden istediğimiz gibi düzenleyebiliriz, ancak XML içerisinde herzaman istediğimiz başlık isimlerini vermek (Büyük harfle başlaması v.b) ve istediğimiz sıraya koymak işimize gelmeyebilir. Flex’in bunun için kolay bir çözümü var. Başlıkların ve sıralarının XML içerisinde değilde Flex içerisinde formatlandırılması mümkün. Bunun için DataGrid bileşeni içerisine <mx:columns></mx:columns> taglarını ekliyoruz. Bu taglar içerisinde ise görüntülemek istediğimiz kadar veri için DataGridColumn bileşeni eklebiliriz. DataGridColumn bileşenin sahip olduğu özellikler sayesinde biraz önce dert yakındığımız DataGrid bileşeninin başlık alanları ve sıraları gibi pek çok özelliğini özelleştirebiliriz.
Aşağıdaki kodlarda da gördüğünüz gibi DataGridColumn bileşeninin headerText özelliği sütun başlığını, dataField özelliği o sütuna gelecek olan verinin yolunu, width özelliği o sütunun genişliğini belirliyor.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult (event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
]]>
</mx:Script>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}">
<mx:columns>
<mx:DataGridColumn headerText="No" dataField="no"/>
<mx:DataGridColumn headerText="İsim" dataField="isim"/>
<mx:DataGridColumn headerText="Soyisim" dataField="soyisim"/>
<mx:DataGridColumn headerText="Doğum Tarihi" dataField="dogum"/>
<mx:DataGridColumn headerText="Ana Adı" dataField="ana"/>
<mx:DataGridColumn headerText="Baba Adı" dataField="baba"/>
<mx:DataGridColumn headerText="Puan" dataField="rating"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
XML içerisindeki tüm alanları göstermek istiyorsak bunların herbiri için birer DataGridColumn ekliyoruz ve istediğimiz sıraya diziyoruz. XML içerisinde belirttiğiniz bazı verileri formatlandırmak isterseniz bununda bir çözümü mevcut. DataGridColumn bileşeninin labelFunction özelliği ile formatlandırma işlemini yapacak olan fonksiyonu çağırabiliriz.
Örneğin 1986-03-01 formatında yazmış olduğumuz doğum tarihi bilgisini 01-Mar-1986 formatında göstermek istiyoruz. Bu işlemi DateFormatter bileşeni sayesinde yapabiliriz. DateFormatter bileşenine dgmTrh id ismini verelim ve formatString özelliğine ise "DD-MMM-YYYY" değerini atayalım. Bu format gün ismini iki haneli, ay ismini üç haneli ve yıl ismini ise dört haneli olarak DataGrid’e aktaracaktır. DateFormatter bileşeninin id ve formatString değerlerini girdikten sonra DataGridColumn’un labelFunction özelliğinde belirttiğimiz fonksiyonu oluşturalım. Bu fonksiyon sahip olduğu iki parametre olcak. Bunlardan ilki item, Object tipinde bir değişken ve dogum ise DataGridColumn tipindeki değişkenimizdir. Fonksiyon dönüş tipi olarak String belirtilmiştir çünkü sonuç olarak dönecek olan değer (formatlı tarihimiz) bir stringdir. DateFormatter bileşenimizin format metoduna item.dogum değerini parametre olarak gönderiyoruz. Böylece doğum tarihi alanını yukarıda belirttiğimiz formatta görüntüleyebiliyoruz.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult(event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
private function dogumTarihiFormat(item:Object, dogum:DataGridColumn):String
{
return dgmTrh.format(item.dogum);
}
]]>
</mx:Script>
<mx:DateFormatter id="dgmTrh" formatString="DD-MMM-YYYY"/>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}">
<mx:columns>
<mx:DataGridColumn width="35" headerText="No" dataField="no" />
<mx:DataGridColumn width="90" headerText="İsim" dataField="isim"/>
<mx:DataGridColumn width="80" headerText="Soyisim" dataField="soyisim"/>
<mx:DataGridColumn width="90" headerText="Doğum Tarihi" dataField="dogum" labelFunction="{dogumTarihiFormat}"/>
<mx:DataGridColumn width="115" headerText="Doğum Yeri" dataField="dogumYeri"/>
<mx:DataGridColumn width="70" headerText="Ana Adı" dataField="ana"/>
<mx:DataGridColumn width="70" headerText="Baba Adı" dataField="baba"/>
<mx:DataGridColumn width="45" headerText="Puan" dataField="rating"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
XML içerisinde doğum yeri bilgisini tutan ve ülke bilgisini tutan iki alan var. Bu iki alanı tek bir sütun içerisinde göstermek istiyoruz. Bunun için, dogumYeri için oluşturduğumuz DataGridColumn bileşenini formatlandıracağız. İlgili DataGridColumn bileşeninin labelFunction özelliğine bir fonksiyon atayalım ve bu fonksiyonu Script bloğumuzda oluşturalım. Yine önceki format fonksiyonumuz gibi iki parametreye sahip ancak bir öncekinde olduğu gibi Formatter kullanmıyoruz.
Aşağıdaki kodlarımız ile birlikte uygulamamız doğum tarihi ve doğum yeri bilgilerimizi belirttiğimiz formatlarda gösteren bir hal almış oldu.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult(event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
private function dogumTarihiFormat(item:Object, dogum:DataGridColumn):String
{
return dgmTrh.format(item.dogum);
}
private function dogumYeriFormat(item:Object, dogumYeri:DataGridColumn):String
{
return item.dogumYeri + ", " + item.ulke;
}
]]>
</mx:Script>
<mx:DateFormatter id="dgmTrh" formatString="DD-MMM-YYYY"/>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}">
<mx:columns>
<mx:DataGridColumn width="35" headerText="No" dataField="no" />
<mx:DataGridColumn width="90" headerText="İsim" dataField="isim"/>
<mx:DataGridColumn width="80" headerText="Soyisim" dataField="soyisim"/>
<mx:DataGridColumn width="90" headerText="Doğum Tarihi" dataField="dogum" labelFunction="{dogumTarihiFormat}"/>
<mx:DataGridColumn width="115" headerText="Doğum Yeri" dataField="dogumYeri" labelFunction="{dogumYeriFormat}"/>
<mx:DataGridColumn width="70" headerText="Ana Adı" dataField="ana"/>
<mx:DataGridColumn width="70" headerText="Baba Adı" dataField="baba"/>
<mx:DataGridColumn width="45" headerText="Puan" dataField="rating"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Bu uygulamada kullandığımız XML dosyamız oldukça sadeydi ama XML dosyalarımız herzaman bu kadar sade olmayabilir. Dosya içerisindeki veri ve kod arttıkça hata yapma oranı da buna bağlı olarak artacaktır. Peki XML dosyamız içerisinde herhangi bir hata varsa uygulamamız nasıl çalışır? XML dosyamızda ufak bir hata oluşturalım ve uygulamamızı derleyelim. Beklenilenin aksine uygulama hatasız derlenecektir ancak veriler yüklenmeyecektir. [Bkz. Resim-2]
Bu durumu Flex içerisindeki Fault sınıfı ile kontrol edebilir ve hatayı uygulama içerisinde bir mesaj ile kullanıcıya bildirebiliriz. Bunun için HTTPService’ın fault parametresine hatayı bildiren fonksiyonumuzu belirtelim ve Script bloğumuzda bu fonksiyonu oluşturalım. myFault isimli fonksiyon hata mesajını uygulama içerisinde kullanıcıya verecektir.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult(event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
private function dogumTarihiFormat(item:Object, dogum:DataGridColumn):String
{
return dgmTrh.format(item.dogum);
}
private function dogumYeriFormat(item:Object, dogumYeri:DataGridColumn):String
{
return item.dogumYeri + ", " + item.ulke;
}
private function myFault(event:FaultEvent):void
{
var hataTanimi:String = "Hata Tanımı" + " ";
hataTanimi += event.fault.faultString + " ";
Alert.show(hataTanimi, "Hata Oluştu");
var olayTanimi:String = "Olay Tanımı" + " ";
olayTanimi += event.target + " " + event.type + " ";
Alert.show(olayTanimi, "Hata Oluştu");
}
]]>
</mx:Script>
<mx:DateFormatter id="dgmTrh" formatString="DD-MMM-YYYY"/>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" fault="{myFault(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}">
<mx:columns>
<mx:DataGridColumn width="35" headerText="No" dataField="no" />
<mx:DataGridColumn width="90" headerText="İsim" dataField="isim"/>
<mx:DataGridColumn width="80" headerText="Soyisim" dataField="soyisim"/>
<mx:DataGridColumn width="90" headerText="Doğum Tarihi" dataField="dogum" labelFunction="{dogumTarihiFormat}"/>
<mx:DataGridColumn width="115" headerText="Doğum Yeri" dataField="dogumYeri" labelFunction="{dogumYeriFormat}"/>
<mx:DataGridColumn width="70" headerText="Ana Adı" dataField="ana"/>
<mx:DataGridColumn width="70" headerText="Baba Adı" dataField="baba"/>
<mx:DataGridColumn width="45" headerText="Puan" dataField="rating"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Son olarak DataGrid sınıfının bir kaç özelliğine daha değinelim ve bitirelim. Uygulamamızı derleyelim. Tarayıcınızda açılan uygulama üzerinde bir takım işlemler yapılabildiğini farketmişinizdir. Mesela sütun boyutlarını mouse ile sürükleyerek değiştirebiliyor, başlık kısmına tıkladığımızda sütunları alfabetik olarak sıralayabiliyor ve tekrar tıkladığınızda ters alfabetik olarak sıralayabiliyor, mouse ile başlığa tıklayarak sürükleyerek sütunların yerlerini değiştirebiliyoruz. Tüm bu bahsettiğimiz özellikler ve daha fazlasını DataGrid sınıfının methodlarını ve özelliklerini kullanarak değiştirebilirsiniz.
Yukarıda bahsettiğimiz işlemleri yapan parametreler sortableColumns, draggableColumns ve resizeableColumns ‘dır. Bunların değerlerini false yaparsanız DataGrid bileşeniniz üzerinde kullanıcılar bahsettiğimiz işlemleri yapamazlar. Aşağıdaki kodlar uygulamamızın son halini oluşturmaktadır.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myHTTP.send()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var ogrenciler:ArrayCollection;
private function myResult(event:ResultEvent):void
{
ogrenciler = event.result.otomasyon.ogrenci;
}
private function dogumTarihiFormat(item:Object, dogum:DataGridColumn):String
{
return dgmTrh.format(item.dogum);
}
private function dogumYeriFormat(item:Object, dogumYeri:DataGridColumn):String
{
return item.dogumYeri + ", " + item.ulke;
}
private function myFault(event:FaultEvent):void
{
var hataTanimi:String = "Hata Tanımı" + " ";
hataTanimi += event.fault.faultString + " ";
Alert.show(hataTanimi, "Hata Oluştu");
var olayTanimi:String = "Olay Tanımı" + " ";
olayTanimi += event.target + " " + event.type + " ";
Alert.show(olayTanimi, "Hata Oluştu");
}
]]>
</mx:Script>
<mx:DateFormatter id="dgmTrh" formatString="DD-MMM-YYYY"/>
<mx:HTTPService id="myHTTP" url="data/database.xml" result="{myResult(event)}" fault="{myFault(event)}" />
<mx:DataGrid id="myGrid" dataProvider="{ogrenciler}" draggableColumns="false" resizableColumns="false" sortableColumns="false">
<mx:columns>
<mx:DataGridColumn width="35" headerText="No" dataField="no" />
<mx:DataGridColumn width="90" headerText="İsim" dataField="isim"/>
<mx:DataGridColumn width="80" headerText="Soyisim" dataField="soyisim"/>
<mx:DataGridColumn width="90" headerText="Doğum Tarihi" dataField="dogum" labelFunction="{dogumTarihiFormat}"/>
<mx:DataGridColumn width="115" headerText="Doğum Yeri" dataField="dogumYeri" labelFunction="{dogumYeriFormat}"/>
<mx:DataGridColumn width="70" headerText="Ana Adı" dataField="ana"/>
<mx:DataGridColumn width="70" headerText="Baba Adı" dataField="baba"/>
<mx:DataGridColumn width="45" headerText="Puan" dataField="rating"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Tabi bunların yanısıra onlarca parametreyi istediğiniz gibi kullanabilir ve DataGrid bileşeninizi daha çok özelleştirebilirsiniz. Uygulamanın çalışan örneği aşağıdadır. Kolay Gelsin!
NOT: Sayfada bazan SWF dosyaları çalışmıyor (tarayıcıya göre) yada bağlantılara izin verilmiyor. Eğer kaynağı görüntüle butonlarını çalıştıramıyorsanız, uygulamanın kaynağına buradan ulaşabilirsiniz.
İçeriğe kayıtlı yorum bulunmuyor. İlk yorumu siz buradan ekleyebilirsiniz.
Makale
Haber
MMIstanbul Adobe UG
ColdFusion, Flex, AIR, Flash, PDF, Dreamweaver, Fireworks, Photoshop, Illustrator, iNdesign, Premiere, Soundbooth, Lightroom, InCopy, JRun, LiveCycle, Acrobat, AfterEffects, Resmi Adobe Kullanıcı Grubu.
Etkinlikler
Fuar
CeBIT 2008 Bilişim Eurasia 7 - 12 Ekim 2008' de
CeBIT 2008 Bilişim Eurasia 7 - 12 Ekim 2008' de
CeBIT Bilişim Eurasia bu yıl 7 – 12 Ekim tarihlerinde düzenleniyor
Adını dünyanın en büyük on fuarı arasına yazdırarak, İstanbul’u Avrasy...
Kategori: Fuar


