Tegyük össze amit eddig tudunk:
Ami még hiányzik:
No, akkor kalandra fel! URL változó - az olyan, mint a city.
Ha meg megnyomják a gombot, az url-t úgy kell összerakni, hogy a city értéke a megfelelő helyen legyen:
url="http://maps.googleapis.com/maps/api/staticmap?center="+city+"&size=300x300&zoom=10";
public class MapWindow extends Form {
String city="Budapest";
String url="http://maps.googleapis.com/maps/api/staticmap?center=Budapest&size=300x300&zoom=10";
final FieldString<MapWindow> CITY=FieldString.of(MapWindow.class,"city");
final FieldString<MapWindow> URL=FieldString.of(MapWindow.class,"url");
public MapWindow() {
window()
.text("Térkép")
.add(
group(
edit(this,CITY),button(showAction)
),br(),
view(this,URL).asPicture()
)
.show();
}
Action showAction=new Action("Mutasd") {
@Override
protected void execute() {
url="http://maps.googleapis.com/maps/api/staticmap?center="+city+"&size=300x300&zoom=10";
}
};
}
Ez igazán csinos így! Észrevetted a group()-ot, amivel a szövegmező és a gomb egy csoportot képeznek, így a kép az egész csoport alá igazítja magát? Az is fontos, hogy induláskor az URL ne legyen üres. Ha üres az URL, akkor a view nem tud semmit betölteni, és nem tudja meghatározni a méretét, és akkor az egész ablak mérete nem számolható ki. Ezért beletettem Budapestet a városnévnek is, meg az URL-nek is, mint kezdőérték.
Az URL-be további paramétereket is lehet tenni:
Akkor hát:
public class MapWindow extends Form {
String city="Budapest";
String url="http://maps.googleapis.com/maps/api/staticmap?center=Budapest&size=300x300&zoom=10";
boolean terrain;
final FieldString<MapWindow> CITY=FieldString.of(MapWindow.class,"city");
final FieldString<MapWindow> URL=FieldString.of(MapWindow.class,"url");
final FieldBoolean<MapWindow> TERRAIN=FieldBoolean.of(MapWindow.class,"terrain");
public MapWindow() {
window()
.text("Térkép")
.add(
group(
label("Város:"),edit(this,CITY),
label("Domborzat:"),edit(this,TERRAIN),
button(showAction)
),br(),
view(this,URL).asPicture()
)
.show();
}
Action showAction=new Action("Mutasd") {
@Override
protected void execute() {
url="http://maps.googleapis.com/maps/api/staticmap?center="+city+"&size=300x300&zoom=10";
if (terrain) {
url=url+"&maptype=terrain";
}
}
};
}
Fúú de jó! Figyelted, hogy csak edit-et kellett írni, és az edit kitalálta a változó típusából, hogy hogyan kell editálni? A stringes city-re szöveges editort rakott ki, a boolean-os terrainre meg egy checkbox-ot! Ez akkor azt jelenti, hogy Dulifuli listájáról ki lehet pipálni mégegy dolgot: nekünk nem kell megtanulni és fejben tartani, hogy épp hogyan nevezik azt a "be-ki pipálható izékét ma délután", hanem csak annyit mondunk, hogy edit, és hopsz, máris editál, bármit. A view meg megjelenít, bármit. (Néha lehet, hogy nem egyértelmű, mit kell csinálni, ezért a view például tudja ezt az .asPicture() dolgot, hogy a belerakott szöveget nem szövegként, hanem kép URLként kell értelmezni. De ez alapvetően ritka eset.)
Figyelted, hogy mit csináltunk itt? Csak elmondtuk a kívánságainkat, ide egy edit, ami ezt és ezt szerkeszti, oda egy view, ami ezt és ezt mutatja meg. Semmit nem rágtunk a gép szájába, csak kinyilvánítottuk, mit kívánunk. Ezt nevezik deklaratív programozásnak. (Ez fontos dolog, ezért beszélek róla újra, most, hogy jobban érzed az előnyeit.)
Imperatív: parancsoló, parancs alapú: lépésről lépésre elmondjuk, mit kell csinálni, és reményeink szerint ez megoldja a célt. A ma használt harmadik generációs nyelvek mind imperatívak (C, Pascal, C++, Java, Javascript).
Deklaratív: kinyilvánítás, szándék alapú: mi a célt mondjuk meg, nem pedig a cél eléréséhez szükséges lépéseket. Ezzel sokkal kevesebb programsorból sokkal áttekinthetőbben lehet programozni olyan dolgokat, amire ez a módszer értelmezhető. A ma használt negyedik generációs nyelvek deklaratívak (SQL), szintén deklaratívak a nem-programnyelvek (HTML - itt is csak azt mondjuk, hogy "ez itt egy fejléc", vagy a CSS "minden fejléc legyen sárga").
Deklaratív vagy imperatív a jobb?
A tapasztalat az, hogy néhány problémát nagyon kényelmes deklaratívan megoldani, más feladatokat viszont teljesen lehetetlen. Például, zenét hangokból lejátszani nem lehet deklaratívan, hiszen a zene arról szól, hogy egymás után sorban meg kell parancsolni, melyik hang következzen.
A mi programunkban is deklaratív volt az ablak kinézetének megadása, viszont imperatív volt a gomb megnyomására elinduló eseménykezelő kód.
Modern adatbázis rendszerekben egyszerre van deklaratív programozás az adatok kinyerésére (SQL) és imperatív programozás az adatok feldolgozására (Oracle: PL/SQL Microsoft SQL server: Transact SQL).
A deklaratív és az imperatív nyelvek ésszerű kombinálásával mindkét világ előnyös oldalát használhatjuk. Dulifuli azt mondja, ez megéri :)