2009.01_Biblioteka senseGUI czyli GUI z automatu_[Jezyki Programowania].pdf
(
536 KB
)
Pobierz
441671224 UNPDF
Języki programowania
Biblioteka senseGUI
czyli GUI z automatu
Większość programistów zetknęła się z potrzebą stworzenia Graficznego
Interfejsu Użytkownika (ang. GUI). Zwykle do tego celu stosuje się popularne
biblioteki (np. Swing) lub dedykowane edytory, co jest dość pracochłonne. W
tym artykule chcielibyśmy omówić inne rozwiązanie, bazujące na podejściu
deklaratywnym.
Dowiesz się:
• Jakie są sposoby tworzenia GUI;
• Jak zaprojektować własną bibliotekę do auto-
matycznego tworzenia GUI;
• Do czego mogą się przydać adnotacje.
Powinieneś wiedzieć:
• Jak programować w jednym z popularnych ję-
zyków, np. Java.
Warto zauważyć, że jednym z najbardziej
znanych przykładów podejścia deklaratywne-
go, chociaż nie związanym z GUI, jest język
zapytań SQL. Użytkownik określa, co ma być
zrobione (jakie dane potrzebuje), ale nie defi-
niuje, jak to ma być wykonane. O użyteczno-
ści takiego podejścia niech świadczy fakt, iż
jedno zapytanie SQL może odpowiadać kilku-
dziesięciu (lub nawet kilkuset) liniom progra-
mu w klasycznym języku programowania (np.
Java czy C#).
Podobne rozwiązanie chcielibyśmy zastoso-
wać dla graficznych interfejsów użytkownika.
Naszym celem jest, aby mając określone dane
biznesowe (zdefiniowane w postaci klas np. ję-
zyka Java czy C#) GUI pojawiło się automatycz-
nie. I najlepiej, aby spełniało nasze oczekiwania
m.in. w zakresie:
Poziom trudności
cej ręczne modyfikacje kodu źródłowe-
go na wizualny projekt. Istnieją również
rozwiązania działające tylko jako czyste
generatory kodu. Wtedy ręczne modyfi-
kacje są tracone po ponownym wygene-
rowaniu kodu dla wizualnego projektu.
• Zastosowanie specjalnego, deklaratyw-
nego podejścia. Jego zaletą jest to, że
projektant/programista skupia się na tym
co jest do zrobienia
, a nie
jak to zrobić
. Naj-
nowsze, komercyjne technologie podąża-
jące tym tropem to propozycja Microsoft
dotycząca języka XAML (ang.
Extensible
Application Markup Language
). Poszcze-
gólne elementy GUI są definiowane w
specjalnym języku programowania, a wła-
ściwie języku opisu.
delu (danych) mają mieć GUI, a odpo-
wiednia biblioteka automatycznie je ge-
neruje w czasie działania programu. Na począ-
tek pokuśmy się o rozważenie kilku opcji, ja-
kie mamy, gdy chcemy stworzyć GUI. Ogólnie
rzecz biorąc, współcześni twórcy oprogramo-
wania, wykorzystują trzy główne podejścia do
tworzenia graficznego interfejsu użytkownika:
• funkcjonalności,
• użyteczności,
• wydajności,
• estetyki.
• Ręczne pisanie kodu źródłowego odwo-
łującego się do odpowiednich bibliotek.
W przypadku Javy może to być Swing
[3] lub SWT [4]. Programiści C# korzy-
stają z WinForms [5]. Najbardziej skom-
plikowana sytuacja jest w C++, gdzie za-
stosowanie konkretnej biblioteki jest
zdeterminowane przez dialekt języ-
ka. Istnieje również wiele niezależnych
rozwiązań, które czasami są dedykowa-
ne dla różnych platfor. Najbardziej po-
pularne to Qt [6], wxWidgets [7] oraz
GTK+ [8].
• Wykorzystanie wizualnego edytora,
który umożliwia
narysowanie
GUI i wy-
generowanie odpowiadającego mu ko-
du źródłowego. Jakość takich generato-
rów jest bardzo różna. Niektóre z nich
korzystają z tzw. inżynierii wahadło-
wej (ang.
round-trip
) odzwierciedlają-
Czy to jest w ogóle możliwe? Czy komputer
może wygenerować coś tak skomplikowane-
go, jak interfejs użytkownika bez dostarczenia
Niestety, większość przedstawionych po-
dejść do tworzenia GUI, wymaga dość zna-
czącego zaangażowania ze strony progra-
misty. Cały czas, każdy element GUI od-
powiadający jednostce danych musi być
przetwarzany
indywidualnie. Przedstawio-
ny pomysł polega na stworzeniu rozwiąza-
nia, które jest bardzo łatwe w użyciu, a za-
razem użyteczne i nie wymaga dużego na-
kładu pracy ze strony programisty. Opisy-
wana propozycja została zaimplementowa-
na w postaci biblioteki senseGUI dla języka
Java i może być wykorzystana w dowolnej
aplikacji pracującej na tej platformie. War-
to podkreślić, że stosując opisane podejście,
możliwe jest stworzenie podobnego rozwią-
zania dla dowolnego języka wspierającego
refleksję (np. C#).
Listing 1.
Przykładowa klasa biznesowa
public
class
Person
{
private
String
irstName
;
private
String
lastName
;
private
Date
birthDate
;
private
boolean
higherEducation
;
private
String
remarks
;
private
int
SSN
;
private
double
annualIncome
;
public
int
getAge
()
{
// [...]
}
}
44
01/2009
P
rogramista określa, które elementy mo-
Biblioteka senseGUI – czyli GUI z automatu
mu dokładnych informacji? Otóż jest to wyko-
nalne do pewnego stopnia. Niestety, im efekt
końcowy ma być bliższy naszym oczekiwa-
niom, tym nasz wkład pracy będzie większy.
Wydaje się, że podstawą przy konstruowaniu
takiego
automatu
generującego GUI jest zna-
lezienie złotego środka pomiędzy generycz-
nością (zdolnością do pracy z różnymi dany-
mi) rozwiązania a naszymi oczekiwaniami, a
co za tym idzie nakładem pracy. Innymi sło-
wy, zaproponujemy rozwiązanie, które da się
stosować
łatwo, szybko i przyjemnie
, ale za ce-
nę pewnych uproszczeń, które musimy zaak-
ceptować.
Aby sprecyzować nasze oczekiwania funk-
cjonalne dotyczące GUI, spróbujmy określić,
do czego ono jest nam potrzebne. Przecięt-
ny użytkownik aplikacji komputerowej wy-
korzystuje graficzny interfejs użytkowni-
ka jako:
• dla każdej metody dodać widget, który za-
prezentuje wynik jej działania,
• dla każdego widgetu dodać odpowiednią
etykietę,
• dla każdego widgetu dodać kod, który od-
czyta wartość określonego atrybutu i wsta-
wi ją do widgetu,
• dodać przyciski kontrolne (
accept
,
cancel
),
• dla przycisku
accept
dodać kod, który od-
czyta zawartość widgetów, uaktualni od-
powiedni fragment modelu oraz ukryje
formatkę,
• dla przycisku
cancel
dodać kod ukrywają-
cy formatkę.
Uważamy, że w przypadku typowych,
biznesowych formularzy do wprowadzania/
edycji danych, najbardziej obiecującym roz-
wiązaniem jest podejście deklaratywne. Po-
wodem tego jest fakt, iż programista może
skupić się na tym, co chce osiągnąć, a nie
jak to zrobić. Kolejną potencjalną zaletą jest
możliwość przezroczystej pracy na różnych
platformach (przenośność). W ogólnym
przypadku, programista adnotuje kod źró-
dłowy, a dedykowana biblioteka generuje od-
powiedni kod zależny od platformy.
Założenia
proponowanego rozwiązania
Naszym celem będzie stworzenie biblioteki,
która automatycznie wygeneruje formularze
GUI na podstawie zwykłych klas języka Java.
Korzystając z tych formatek, użytkownik apli-
kacji będzie w stanie wprowadzić dane, uak-
tualnić istniejące informacje lub je po prostu
przeglądać. Przykładowo, programista chce
wykonać GUI (podobne do tego z Rysunku 1.)
dla wcześniej przedstawionej klasy
Person
. W
miarę możliwości, będziemy się starali, aby ca-
ły proces odbywał się bez nadmiernego zaan-
gażowania ze strony programisty.
W trakcie prac projektowych musimy roz-
wiązać trzy główne problemy:
Realizacja powyższych wymagań oznacza na-
pisanie kilkudziesięciu linii kodu (7 atrybutów
mnożone przez 5 do 10 linii na kontrolkę plus
zarządzanie rozkładem, przyciskami kontrol-
nymi, itp.), które są do siebie dość podobne.
Aby zmniejszyć nasz nakład pracy, może-
my skorzystać z edytora GUI. Jednym z nich
jest np. Jigloo GUI Builder [9] przeznaczony
dla środowiska Eclipse. Korzystając z tego roz-
wiązania projektant/programista jest w sta-
nie graficznie zaprojektować formatkę odpo-
wiednio rozmieszczając poszczególne widge-
ty. Przykład dla klasy
Person
(Listing 1.) jest
pokazany na Rysunku 1. Dla tego formularza,
edytor GUI wygenerował 105 linii kodu Javy.
Ta liczba nie zawiera elementów niezbędnych
do odczytu/zapisu wartości z/do modelu. Kod
taki musi być stworzony ręcznie przez progra-
mistę. Mimo wszystko, jest to spore udogod-
nienie w porównaniu z ręcznym pisaniem ca-
łego kodu. Niestety programista musi spędzić
trochę czasu rozmieszczając widgety, dodając
kod obsługujący odczyt/zapis danych i zarzą-
dzający rozłożeniem elementów.
Wróćmy jeszcze na chwilę do propozycji
Microsoft zwanej XAML (Extensible Appli-
cation Markup Language) mocno wykorzy-
stywanej w WPF (Windows Presentation Fo-
undation). Polega ona na tym, że sposób wy-
korzystania poszczególnych kontrolek nie jest
definiowany w języku programowania, jak w
klasycznym wykorzystaniu np. Swinga, ale za
pomocą specjalnego pliku. Do tego celu wyko-
rzystywany jest specjalny język opisu (właśnie
XAML) oparty o XML. Fragment takiego pli-
ku jest pokazany na listingu 2. Można się z nie-
go zorientować, że programista korzystający z
XAML do tworzenia GUI nie ma znacząco ła-
twiejszego zadania. Praktycznie rzecz biorąc,
musi wykonać każdy z powyżej opisanych kro-
ków, z ta tylko różnicą, że nie robi tego w ję-
zyku programowania, ale w specjalnym języku
znaczników. Z naszego punktu widzenia, czy-
li maksymalnego zautomatyzowania całego
procesu, to podejście nie wnosi nowej jakości
i właściwie nawet trudno nazwać je deklara-
tywnym. Sprawdza się za to znakomicie przy
generowaniu kodu XAML z dedykowanych
edytorów, np. Microsoft Expression Blend.
• Wejście dla danych w celu wypełnienia ich
pewną zawartością. W tym celu, progra-
mista stosuje pewne widgety (np. pole tek-
stowe) i łączy je z danymi (np. nazwiskiem
klienta w systemie). Gdy użytkownik wpro-
wadzi odpowiednie informacje, dedykowana
część programu, zapisuje je w modelu.
• Wyjście, celem zaprezentowania informa-
cji przechowywanych w modelu. W tym
celu, programista pisze kod odczytujący
odpowiedni fragment danych i wyświetla
go w określonym komponencie GUI.
• Jak odczytać zawartość klasy (jej strukturę)?
• Jaki widget powinien być użyty do po-
szczególnych rodzajów danych?
• Jak połączyć poszczególne elementy GUI
(widgety) z danymi?
Powyższe potrzeby mogą być zaspokojone,
korzystając z jednego ze wcześniej opisa-
nych sposobów. Ponieważ stworzony proto-
typ jest dedykowany dla Javy, w dalszej czę-
ści artykułu skupimy się na rozwiązaniach
przeznaczonych właśnie dla tego języka.
Następne paragrafy zawierają krótkie omó-
wienie implementacji potrzeb związanych
z wejściem/wyjściem korzystając z istnieją-
cych rozwiązań.
Sposoby tworzenia GUI
Najbardziej powszechnym sposobem tworzenia
GUI jest wykorzystanie bibliotek dostarczanych
razem z językiem. Większość graficznych inter-
fejsów użytkownika dla Javy jest implementowa-
na z użyciem bibliotek Swing [3] lub SWT [4].
Spójrzmy na kod znajdujący się na listingu nr 1.
Przedstawia on typową klasę biznesową jakich
wiele we współczesnych systemach.
Aby opracować dla niego odpowiednie GUI,
działające zgodnie z uprzednio określonymi po-
trzebami wejścia/wyjścia, należy wykonać po-
niższe kroki:
Rysunek 1.
Okno obsługujące klasę Person
stworzone za pomocą edytora GUI
• utworzyć pustą formatkę,
• dodać odpowiedni manager rozkładu,
• dla każdego atrybutu dodać widget, który
zaprezentuje jego zawartość i umożliwi je-
go edycję,
Rysunek 2.
Formatka wygenerowana przez
bibliotekę dla kodu z Listingu 2.
www.sdjournal.org
45
Języki programowania
Pierwszy problem rozwiążemy przy pomo-
cy techniki zwanej refleksją. Jest dostępna
dla popularnych języków programowania (Ja-
va, C# i częściowo C++) i umożliwia odczyta-
nie informacji o budowie klasy i tworzenie jej
obiektów. Pozostałymi kwestiami zajmiemy
się w dalszej części artykułu.
Niestety mimo naszych najlepszych chęci,
aby biblioteka obywała się bez podawania do-
datkowych parametrów, byliśmy zmuszeni
je zdefiniować. Dotyczy to choćby przypad-
ku gdy niecała zawartość klasy powinna być
edytowalna i/lub wyświetlana. Ponieważ nie
jest możliwe automatyczne szacowanie, któ-
re elementy powinny mieć swoje odpowied-
niki w GUI, byliśmy zmuszeni wprowadzić
pewne znaczniki. Umożliwiają one dostoso-
wanie generowanego interfejsu użytkowni-
ka do konkretnych potrzeb. Kwestią otwar-
tą było, w jaki sposób osiągnąć taką funkcjo-
nalność, czyli połączyć programistę, bibliote-
kę i GUI? Mieliśmy do wyboru kilka możli-
wości, włączając w to pliki konfiguracyjne
(np. XML) lub przekazywanie parametrów
w wywoływanych metodach. Ostatecznie, po
przeanalizowaniu różnych rozwiązań, zdecy-
dowaliśmy się wykorzystać adnotacje. Takie
konstrukcje istnieją dla języka Java oraz C#
i umożliwiają opisywanie klas oraz ich skła-
dowych. Staraliśmy się zaprojektować je mak-
symalnie prostymi w użyciu, ale ostatecznie
ich liczba wzrosła do 11. Na szczęście więk-
szość z nich ma domyślne wartości, których
nie trzeba modyfikować. Wprowadziliśmy
dwa podstawowe typy adnotacji: przezna-
czone dla atrybutów (
GUIGenerateAttribu-
te
) oraz metod (
GUIGenerateMethod
). Każdy
z nich ma dodatkowe parametry (z domyśl-
nymi wartościami). Poniżej znajdują się naj-
ważniejsze z nich:
Listing 2.
Zastosowanie adnotacji celem wygenerowania GUI – wariant z wartościami domyślnymi
•
Label
– opisuje etykietę znajdującą się
przy widgecie. Jeżeli jest pusta (wartość
domyślna) to zostanie wykorzystana na-
zwa atrybutu lub metody. Ten parametr
był wymagany przy wprowadzaniu spe-
cjalnego nazewnictwa (np. spacji, czy pol-
skich liter).
WidgetClass
– klasa widgetu,
która będzie wykorzystana do edycji oraz
wyświetlania danych. Domyślna wartość
zakłada użycie pola tekstowego (Jtext-
Box);
•
Tooltip
– krótki tekst wyświetlany po na-
jechaniu kursorem na element;
•
GetMethod
– metoda wykorzystywana
do odczytu wartości atrybutu. Domyślna
wartość zawiera pusty ciąg i oznacza za-
stosowanie podejścia opartego na gette-
rach oraz setterach (biblioteka wyszukuje
takie metody w ciele klasy);
•
SetMethod
– analogicznie jak w przypad-
ku
getMethod
, ale dotyczy zapisu warto-
ści;
•
Order
– liczba określająca kolejność widge-
tu na formularzu;
•
ReadOnly
– flaga definiująca, czy dane są
dostępne w trybie tylko do odczytu (bez
możliwości modyfikacji);
•
ScaleWidget
– określa, czy widget powi-
nien zmieniać swój rozmiar w czasie mo-
dyfikacji wielkości formularza.
public
class
PersonAnnotated
{
@
GUIGenerateAttribute
private
String
irstName
;
@
GUIGenerateAttribute
private
String
lastName
;
@
GUIGenerateAttribute
private
Date
birthDate
=
new
Date
()
;
@
GUIGenerateAttribute
private
boolean
higherEducation
;
@
GUIGenerateAttribute
private
String
remarks
;
@
GUIGenerateAttribute
private
int
SSN
;
@
GUIGenerateAttribute
private
double
annualIncome
;
@
GUIGenerateMethod
public
int
getAge
()
{
// ...
}
// Standard getters/setters methods
}
Listing 3.
Zastosowanie adnotacji celem wygenerowania GUI – wariant ze zmodyikowanymi
wartościami
public
class
PersonAnnotated
{
@
GUIGenerateAttribute
(
label
=
"First name"
,
order
=
1
)
private
String
irstName
;
@
GUIGenerateAttribute
(
label
=
"Last name"
,
order
=
2
)
private
String
lastName
;
@
GUIGenerateAttribute
(
label
=
"Birth date"
,
order
=
3
)
private
Date
birthDate
=
new
Date
()
;
@
GUIGenerateAttribute
(
label
=
"Higher education"
,
widgetClass
=
"mt.mas.GUI.CheckboxBo
olean"
,
order
=
5
)
private
boolean
higherEducation
;
@
GUIGenerateAttribute
(
label
=
"Remarks"
,
order
=
50
,
widgetClass
=
"javax.swing.JTextArea"
,
scaleWidget
=
false
)
private
String
remarks
;
@
GUIGenerateAttribute
(
order
=
6
)
private
int
SSN
;
@
GUIGenerateAttribute
(
label
=
"Annual income"
,
order
=
7
)
private
double
annualIncome
;
@
GUIGenerateMethod
(
label
=
"Age"
,
showInFields
=
true
,
order
=
4
)
public
int
getAge
()
{
return
0
;
}
// Standard getters/setters methods
}
Opisywane rozwiązanie jest w stanie pra-
cować z różnymi typami danych: liczbami,
tekstem, wartościami Tak/Nie, datami oraz
typami wyliczeniowymi. Domyślna imple-
Rysunek 3.
Formatka wygenerowana przez
bibliotekę dla kodu z Listingu 3.
46
01/2009
Biblioteka senseGUI – czyli GUI z automatu
mentacja zakłada wykorzystanie pól teksto-
wych do wszystkich typów danych za wy-
jątkiem:
zmienioną kolejność elementów, czy wykorzy-
stanie dedykowanego widgetu dla informacji o
wykształceniu.
Zainteresowany Czytelnik, analizując kod
źródłowy biblioteki (do pobrania na stronie
www.sdjournal.org
) może zauważyć, iż można
z niej korzystać na dwa sposoby:
• Automatycznie wyszukiwać obiekty na
podstawie kryteriów podanych w specjal-
nej formatce.
• Zarządzać ekstensją klasy.
• wartości
Tak
/
Nie
– stosowany jest prze-
łącznik (check box),
• typu wyliczeniowego (
enum
), który jest
przetwarzany w oparciu o specjalne pole
wyboru zawierające wszystkie zdefiniowa-
ne w nim wartości (odczytane dzięki re-
fleksji).
Wykorzystanie powyżej opisanych funkcjo-
nalności jest równie proste, jak podstawo-
wych możliwości oryginalnego rozwiąza-
nia. Dzięki połączeniu bibliotek (
senseGUI
+
senseObjects
) programista ma ułatwione
tworzenie typowych, biznesowych aplikacji.
•
uproszczony
– sprowadzający się do wy-
wołania jednej dużej metody, która zadba
o kompleksowe wygenerowanie i wyświe-
tlenie formatki dla podanego obiektu,
za-
awansowany
zakładający wołanie
mniej-
szych
metod umożliwiających dokładniej-
sze dostosowanie wyświetlanych elemen-
tów. W efekcie otrzymujemy np. instan-
cję JPanel (zamiast pełnego okna), zawiera-
jącą odpowiednie widgety, która może być
dodana do dowolnego, innego elementu
GUI. Dzięki temu można wyświetlać np.
zawartość atrybutów opisywanych za po-
mocą typów zdefiniowanych przez pro-
gramistów (a nie tylko typów prostych).
Listing nr 2. zawiera kod przykładowej klasy
Person udekorowany adnotacjami zdefinio-
wanymi w bibliotece. Warto zauważyć, że je-
dyne co musieliśmy zrobić to dopisać krótkie
adnotacje dla wybranych atrybutów (korzy-
stając z domyślnych wartości).
W rezultacie wywołania pojedynczej me-
tody z biblioteki, wygenerowana i wyświe-
tlona została formatka pokazana na Rysunku
2. Jest ona
połączona
z instancją klasy Person,
dzięki czemu wprowadzone zmiany są auto-
matycznie odzwierciedlane w modelu. Moż-
na zauważyć, że nie zawiera ona widgetu dla
metody obliczającej wiek. Jest to zgodne z
zaproponowanym podejściem, które zakła-
da, że przy domyślnym (bezparametrowym)
użyciu adnotacji, metody nie mają swoich
odpowiedników na formatkach.
Jak widać, takie proste udekorowanie ko-
du nie zawsze prowadzi do idealnych rezulta-
tów. Z punktu widzenia użytkownika, moż-
na mieć zastrzeżenia do nazewnictwa po-
szczególnych elementów, kolejności, w jakiej
występują, czy zastosowanych widgetów. W
takich sytuacjach warto wykorzystać odpo-
wiednie parametry adnotacji, tak jak pokaza-
no na Listingu 3.
Efekt wygenerowania formularza na podsta-
wie powyższego kodu pokazano na rysunku nr
3. Warto zwrócić uwagę na poprawne nazwy,
Podsumowanie
Przedstawiliśmy pewną propozycję dotyczącą
automatycznego generowania graficznych in-
terfejsów użytkownika dla aplikacji bizneso-
wych. Wygenerowany formularz jest oparty na
prostych adnotacjach umieszczonych w kodzie
źródłowym klas definiujących model danych.
Programista wybiera, które inwarianty powinny
mieć swoje odzwierciedlenie w GUI, a zaprezen-
towana biblioteka zajmuje się stworzeniem od-
powiedniego interfejsu użytkownika.
W kolejnej części artykułu dokładniej omó-
wimy budowę biblioteki oraz pokusimy się o
jej rozbudowę o kilka istotnych elementów do-
tyczących elementów międzynarodowości, ge-
nerowania GUI bez konkretnego modelu da-
nych oraz sprawdzania poprawności wprowa-
dzonych informacji.
Prototypowa biblioteka, którą tu opisaliśmy, jest
częścią większego frameworku (
senseFrame-
work
) i w połączeniu z nim pozwala na wiele wię-
cej niż tylko edycję i wyświetlanie stanu poszcze-
gólnych obiektów. Dzięki dodatkowemu zastoso-
waniu biblioteki
senseObjects
możemy:
• Zarządzać powiązaniami pomiędzy obiek-
tami. Stworzyliśmy odpowiednią funk-
cjonalność, która na podstawie adnota-
cji pozwala wyświetlać oraz zarządzać po-
wiązanymi obiektami (asocjacje). Co wię-
cej, można tworzyć kompozycje, asocjacje
kwalifikowane, czy powiązania ogranicza-
ne przez {
xor
} lub {
subset
}.Wyświetlić wie-
le obiektów korzystając z widoku tabela-
rycznego wygenerowanego na podstawie
adnotacji.
MARIUSZ TRZASKA
Mariusz Trzaska jest adiunktem w Polsko-Japoń-
skiej Wyższej Szkole Technik Komputerowych. Wy-
kłada tam przedmioty związane z bazami danych,
programowaniem, modelowaniem oraz inżynie-
rią oprogramowania. Oprócz tego bierze udział w
różnego rodzaju projektach komercyjnych oraz ba-
dawczych. Jest autorem kilkunastu artykułów pu-
blikowanych w kraju i za granicą.
Kontakt z autorem: mtrzaska@pjwstk.edu.pl
R E K L A M A
����������
������
��
�
Visual Studio Professional
�
������������������
Kontakt
���������������������������������������������������������������������������
Plik z chomika:
Kapy97
Inne pliki z tego folderu:
2006.12_Ranking popularności języków programowania SDJ_[Jezyki Programowania].pdf
(187 KB)
2009.12_Delphi i C++Builder 2010_[Jezyki Programowania].pdf
(684 KB)
2009.08_Język skryptowy Lua _[Jezyki Programowania].pdf
(703 KB)
2009.08_WS-BPEL Instrumentacja procesów biznesowych_[Jezyki Programowania].pdf
(1645 KB)
2009.08_Groovy na pohybel Javie, z miłością do Javy–wprowadzenie do języka_[Jezyki Programowania].pdf
(1233 KB)
Inne foldery tego chomika:
Algorytmy
Antyhaking
Aplikacje Biznesowe
Aspekty
Bazy Danych
Zgłoś jeśli
naruszono regulamin