táblázat logo

Táblázatos komponens testreszabása

táblázat logoA Java programozási nyelv egyik ismert GUI csomagja a swing. Ennek népszerű grafikus komponense az adatok táblázatos megjelenítését biztosító JTable komponens. A táblázatos megjelenítéshez több beállítás is szükséges. A JTable egy MVC komponens, így külön kezelendők a modell, nézet és a vezérlő funkcióihoz kötődő beállítások. A modell tárolja az adatokat például DefaultTableModel típusú objektumban, amiben szétválaszthatók a fejlécben és a többi cellákban található adatok. A nézethez tartozik a betűméret, a cellák színezése, az adatok igazítása, megjelenítése, a gördítősáv. A viselkedést, a felhasználói reakciót a vezérlő határozza meg, például rendezés, görgetés, fókusz, kijelölés, oszlopok sorrendjének cseréje.

Feladat

Készítsünk olyan Java swing-es kliensprogramot, amely tetszőleges adatforrásból (XML vagy JSON a hálózatról, JDBC adatbázis kapcsolatból, ORM leképzésből származó objektumokból) képes az átvett adatok grafikus felületen való táblázatos megjelenítésére JTable komponenssel! Építsünk arra, hogy az adatokon kívül metaadatok is rendelkezésünkre állnak! A megoldás legyen univerzális!

Képernyőkép

OracleHR képernyőkép

Modell

A táblázatos GUI komponenst kezdetben inicializálni kell, illetve a benne tárolt adatok is törölhetők, ha újrahasznosításra kerül a sor:

Ki kell nyerni a tároláshoz és a megjelenítéshez kötődő adatokat (1. lépés). A metaadatokból a for() ciklus előállítja az oszlopTomb-öt, és az oszlopTipusTomb-be kerülnek az Oracle adattípusból Java objektumtípusként megfeleltetett adatok. Előbbi a fejléc feliratainak szövegeit tartalmazza, és az utóbbi befolyásolja az egyes cellákban az igazítást, illetve hatással van adott oszlop rendezésére is:

Ki kell nyerni a tároláshoz és a megjelenítéshez kötődő adatokat (2. lépés). A while() ciklus végigjárja az eredménytábla sorait és Object típusú tömböt állít elő az összetartozó rekord mezőiből. Ezek először generikus listába kerülnek, majd onnan kétdimenziós Object típusú tömbbe:

Mi indokolja a tömbökből álló generikus lista ( adatLista) alkalmazását?

A while() ciklus végrehajtása előtt nem tudjuk lekérdezni, hogy mennyi rekordot kaptunk vissza, így nem tudjuk rögtön az adatTomb-be tenni az adatokat. A Java nyelvben a tömbök mérete fix, és a deklaráció során meg kell adni. Az eredménytábla metaadatai között megtalálható a mezők száma, ami felhasználható a kétdimenziós tömb oszlopszámaként. A generikus lista dinamikus, annyi elemből fog állni, ahány lépésben végrehajtódik a while() ciklus. Ezután a listától lekérdezhető az elemszáma ( adatLista.size()), és ezzel megvan a kétdimenziós tömb sorainak száma, ami eddig hiányzott. Persze használhatnánk Vector-t is a tömbökből álló generikus lista helyett (mert a DefaultTableModel-nek van olyan túlterhelt konstruktora, ami átvenné paraméterként), de ezt inkább nem tesszük, hiszen a Vector már régóta obsolete kollekció.

Előállítjuk a vizuális komponens mögötti adatmodellt. Öröklődéssel kiegészítjük két hasznos függvénnyel, így cellák rajzolása/renderelése és rendezése megkaphatja a szükséges adattípust ( getColumnClass()), valamint letiltható a cellák szerkeszthetősége ( isCellEditable()). Utóbbiak inkább a vezérléshez kötődnek, de modellen keresztül itt és így kell beállítani:

Végül a vizuális komponens mögötti adatmodellt kell átadni:

Nézet

Adott betűtípus, betűstílus és betűméret használható a táblázat fejlécében, celláiban, illetve a betűmérettől függhet a sorok magassága:

Hasznos ha JScrollPane típusú gördítősáv tartozik a táblázathoz, így dinamikusan megjeleníthető/elrejthető a függőleges/vízszintes gördítősáv:

Vezérlés

Az adatokhoz valahogyan hozzá kell jutni. Most JDBC kapcsolatot használunk és az Oracle HR sémából kérdezünk le adatokat, de a forráskód-részlet univerzális. A folyamat a következő:

  • A driver osztályt betöltjük.
  • Autentikációval c kapcsolatot nyitunk az adatbázis-szerver felé.
  • Végrehajtjuk a lekérdező SQL parancsot.
  • Feldolgozzuk az eredményül kapott ResultSet típusú rs objektumot.
  • Végül lezárjuk a c hálózati kapcsolatot.

Ha engedélyezzük, akkor a megjelenő táblázat fejlécében az egyes oszlopok felirataira kattintva elérhetjük, hogy az adott oszlop típusának megfelelően növekvő vagy csökkenő sorrendbe átrendeződjenek az adatok:

A kivételkezelést nem részleteztük a fenti forráskódoknál, de természetesen kötelezően adott.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam 45-52. óra: Adatbázis-kezelés JDBC alapon, illetve Java adatbázis-kezelő tanfolyam 9-12. óra: Oracle HR séma elemzése, 33-36. óra: Grafikus kliensalkalmazás fejlesztése JDBC alapon, 2. rész alkalmaihoz kapcsolódik.

“Táblázatos komponens testreszabása” bejegyzéshez 7 hozzászólás

  1. Tipikus Exceles igény, hogy a táblázat páros és páratlan sorai más háttérszínnel jelenjenek meg. Kérhetek ehhez ötletet, hogy csináljam JTable-lel?

    Válasz
  2. Szeretnék egy olyan JTable cellát, aminek a háttérszíne részben megváltoztatható. Ha a cellát teljesen kitölti egy háttérszín, akkor azt meg tudom csinálni a ColorRenderer.java mintapélda alapján, ami így néz ki (Favorite Color oszlop):

    A mai dátumból kivonva a HIRE_DATE-et és osztva 365-tel megkapjuk kb. egy alkalmazott tapasztalatát. A cégnél eltöltött idő alapján. Ezt már összeraktam SQL-ben. Egy cellában szeretném megjeleníteni a háttérszín arányos kitöltésének beállításával az adatokat, valahogy így (Age oszlop):

    Arra gondoltam, hogy JPanel-be raknék egymás mellé két JLabelt. A balra lévőt színezném, a jobbra lévő fehér lenne. És a panel kerülne a cellába. Szeretnék támpontot kérni, hogy jó-e az irány, vagy inkább teljesen másképp induljak el. A hétvégén fogok majd ezzel foglalkozni. Köszönöm előre is.

    Válasz
    • Áron: tetszik, hogy ilyen konkrétan megfogalmaztad, hogy mit szeretnél. A linkekről beraktam a képeket a hozzászólásodba.
      Jól látod: ez a feladat a rajzolás felüldefiniálásával már nem oldható meg könnyen, ezért jó út a komponens alapú megközelítés. Az ötleted megvalósítható. Ugyanilyen konténer-elvvel építünk GUI-t általában. Azért nem javaslom, mert 3 komponenst használnál egyetlen adat megjelenítéséhez cellánként.
      Más utat javaslok, amiben 1 adathoz 1 komponens tartozik.
      A felső képeden látható, hogy a Vegetarian oszlopban JCheckBox osztályú objektumok jelennek meg. Abból kiindulva, hogy a JTable bármelyik cellájába “belerendereltethető” bármilyen swing-es komponens, így próbálkozz a JSlider folyamatindikátor beillesztésével. A cellákhoz javaslom egyéni ToolTip beállításaként a lekérdezett tapasztalati éveket (kerekítve vagy egésszé csonkolva – mint eltöltött teljes év).

      Válasz
        • Áron, tudod: mindenki annyit visz el a tanfolyamról, amennyit beletett. Örülök neki, hogy sikerült megoldanod.
          Nincs már több kontakt óránk, de egy következő csoporttal kb. március végén járunk majd ennél a témakörnél. Ha lenne kedved, szívesen látunk: gyere be és mutasd meg a többieknek, hogy meddig jutottál, hogyan gondoltad végig, hogyan fejlődtél. Ha szeretnéd, egyeztessük privátban.

          Válasz

Szólj hozzá!