Szívgörbe ábrázolása

Szívgörbét ábrázolunk Java programmal. A Valentin-nap inspirálta ezt a feladatot. Számos matematikai görbe ismert, amelyek szívformához (kardioid) hasonlítanak. Szükséges egy megfelelő paraméteres görbe. A függvény szív formájú ábrája/grafikonja és egyenletrendszere alapján is nagy a választék.

Ábrázoljuk ezt a paraméteres szívgörbét Java swing GUI felületen!

A szívgörbe ábrázolásához felhasználom az StdDraw osztályt, amely ennek a tankönyvnek a példatárából származik: Robert Sedgewick, Kevin Wayne: Computer Science: An Interdisciplinary Approach, 1st edition, Princeton University, Addison-Wesley Professional, 2016, ISBN 978-0134076423. Az osztály metódusaival könnyen beállítható a nézőpont, a vízszintes/függőleges skála, a rajzoláshoz használt toll mérete/színe és a grafikai primitívek közül csak a pont ábrázolása szükséges.

Négy megoldást mutatok. Mindegyik azonos szívgörbét rajzol a fenti egyenletrendszer alapján. Mindegyik metódus átveszi az N paramétert, amely az összetartozó x és y koordinátapárok számát jelenti. Az N db pont meghatározása/kiszámolása szükséges a szívgörbe ábrázolásához. A szívgörbe ábrázolása önálló ablakban – grafikus felhasználói felületen – jelenik meg. A feladat matematikai jellegéből adódik, hogy tipikus a t nevű ciklusváltozó használata. A metódusokat a vezérlés az 512 paraméterrel hívja meg.

1. megoldás

A heartCurveDraw1() metódus a kiszámolt x és y koordinátákat két párhuzamos, double típusú tömb adatszerkezetben tárolja. A két tömbbe összesen 2*N db double típusú szám kerül. Azonos index jelöli az összetartozó koordinátapárokat. Az egymást követő két ciklus közül az első előállítja az adatszerkezetet és a második megjeleníti a pontokat.

2. megoldás

A heartCurveDraw2() metódus a párhuzamos tömbök helyett adatszerkezetként egyetlen tömböt használ. A java.awt.geom csomag Point2D osztályú objektumai kerülnek a tömbbe. Mivel a Point2D absztrakt osztály, így a Double() osztálymetódusával (factory method) példányosítható úgy, hogy a szükséges koordinátapárokat megfelelően tudja tárolni. A tömbbe N db objektum kerül.

3. megoldás

A heartCurveDraw3() metódus nem használ tömb adatszerkezetet. Tehát nem emlékszik az összes pont koordinátájára. Ehelyett a ciklus röptében, egyesével létrehozza a pontobjektumokat és azonnal ki is rajzolja azokat (átmeneti az emlékezet).

4. megoldás

A heartCurveDraw4() metódus Stream API-t és lambda kifejezéseket használ. Az első N természetes számból készül egy sorozat, amihez röptében hozzákötődik a t-edik Point2D típusú objektum. Ezzel létrejön egy folyam adatszerkezet. Tehát van egy pillanat, amíg a program emlékszik az összes folyambeli pontobjektumra. Végül a folyam feldolgozása, bejárása során egyesével megszólítva a folyam objektumait, a pontok kirajzolódnak a vászonra.

A vezérlés

Az eredmény

A szívgörbe önálló – swing, grafikus felhasználói felület, GUI – ablakban így jelenik meg:

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 matematikai háttértől eltekintve – a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 21-24. óra: Objektumorientált programozás 2. rész, valamint a 29-36. Grafikus felhasználói felület alkalmaihoz kötődik.

A 2D szívforma egyenletrendszerét erről a weboldalról választottam: Heart Curve – from Wolfram MathWorld. Egy merész továbbfejlesztési ötlet: a haladóknak megtalálható a 3D szívforma ábrázolása is: Heart Surface – from Wolfram MathWorld.

Sándor is blogolt már a Valentin-nap témában: Rómeó és Júlia. Ebből kiderül, hogy vajon ki szereti jobban a másikat: Rómeó vagy Júlia.

Nemzeti pizza nap

Az USA-ban és még néhány országban február 9-én ünneplik a nemzeti pizza napot. Ehhez kötődően kreatív ötletekkel és persze finom pizzákkal vonzzák az éttermek a vendégeket.

Kreatív ötletekkel a mi oktatói csapatunk is rendelkezik. A nemzeti pizza nap inspirált bennünket az alábbi feladat megoldására.

Osszunk szét igazságosan 9 db egyforma pizzát 10 fő között!

Az igazságost úgy értelmezzük, hogy mindenkinek ugyanannyi (ugyanakkora szelet) pizza jut. Két megoldást mutatunk be grafikusan. Ötleteket adunk ahhoz, hogyan programozható le mindez Java nyelven: swing grafikus felületen, grafikai primitívekkel vagy ismert algoritmusokkal. Ábrákkal mutatjuk be a megoldásokat, színekkel kiemelve az azonos/különböző méretű pizzaszeleteket.

1. megoldás

Mind a 9 db pizzából vágjunk ki egytized méretű szeletet. Marad 9 db kilenctized méretű pizzaszelet és a 9 db egytizedből összeállítható a 10. főnek járó szintén kilenctized méretű pizzaszelet/adag.

2. megoldás

A 9 db pizzából 5 db pizzát vágjunk ketté. Keletkezik 10 db fél pizza. A maradék 4 db pizzát harmadoljunk fel. Keletkezik 12 db egyharmad pizza. A keletkező 2 db egyharmad pizzát osszuk fel 5-5 részre. Keletkezik 10 db egytizenötöd méretű pizzaszelet. Az egyharmad ötödrésze adja az egytizenötöd részt. A 10 főnek járó adaghoz rakjuk össze a 30 db részből a különbözőket: egy adag kilenctized, ami egy fél és egy harmad és egy tizenötöd részből áll össze. Másképpen: 9/10 = 27/30 = 15/30 + 10/30 + 2/30.

Ötletek a Java nyelvű megvalósításhoz

  • A JFrame osztályból származtatott ablak utódosztály tartalompaneljére ráhelyezhető egy öröklődés útján testre szabott JPanel utódosztályból létrehozott objektum. Ennek van grafikus vászna ( Graphics objektum), amely saját koordináta-rendszerrel és pixelszintű hozzáféréssel rendelkezik. Rendelkezésre áll számos grafikai primitív rajzolására használható metódus, például vonal/szakasz, téglalap, ellipszis. A grafikai primitíveknek rajzolható adott színű körvonala és lehetnek adott színnel kitöltöttek is. Például: drawArc(x, y, width, height, startAngle, arcAngle), vagy az azonos paraméterezésű fillArc(...) metódus. A két szög értelmezése: a startAngle az analóg órán a 3 óra irányába néz, valamint az arcAngle pozitív szög fokban megadva az óramutató járásával ellenkező irányba mutat.
  • A beépített grafikus primitívek helyett használhatunk klasszikus algoritmusokat is. Például a Bresenham vonalrajzoló algoritmus, vagy ennek általánosítása a Bresenham körrajzoló (felezőpont) algoritmus. Ezekhez hasznos némi koordináta-geometria és többféle koordináta-rendszer ismerete.

Ötletek továbbfejlesztéshez

  • Megpróbálhatjuk általánosítani a problémát: osszunk szét igazságosan n db egyforma pizzát n+1 fő között!
  • A statikus képek előállítását követően időzítéssel ellátott animációt is készíthetünk, amely megfelelően mozgatja, forgatja a pizzaszeleteket. Így fázisonként megmutathatók a feladat megoldásának lépései. Ehhez többrétegű vászontechnika szükséges, amelyen könnyen mozgatható a nézőhöz közelebbi réteg úgy, hogy a háttér nem változik meg.
  • A saját rajzolt elemek időzítővel – javax.swing.Timer – történő mozgatására példáink java.swing-ben: Hóesés szimuláció és Naprendszer szimuláció – megvalósítás Java nyelven.
  • A saját rajzolt elemek kézi – eseménykezelővel megvalósított – mozgatásához felhasználható példánk JavaFX-ben: Kígyókocka grafikus felületen.
  • A fázisokból lépésenként vezérelhetően felépülő ábrák elkészítéséhez példáink: Fibonacci-spirál és Koch-görbe rajzolása.

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 matematikai háttértől eltekintve – a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 21-24. óra: Objektumorientált programozás 2. rész, valamint a 29-36. Grafikus felhasználói felület alkalmaihoz kötődik.

Doktoranduszok programoznak – újratöltve

it-tanfolyam.hu doktoranduszok programoznak

it-tanfolyam.hu doktoranduszok programoznakSaját doktorandusz csoporttársaimmal én is többször beszélgettem már arról – ahogyan Sándor is tette 2018-ban –, hogyan tudnák/tudják használni a programozás eszköztárát, módszereit, lehetőségeit saját kutatási munkájukban, beépítve a kutatási folyamat egyes lépéseibe, illetve disszertációjuk elkészítésébe.

A 7 fős csoportban mindenkinek más az alapvégzettsége, így szoftverfejlesztéshez, programozáshoz közös szókincs és terminológia haladó szinten természetesen nincs, viszont közös bennünk, hogy mindannyian alkotunk különféle modelleket és elemzünk adatokat. A csoport teljesen inhomogén, több szempontból is: ki melyik évfolyamot végzi, hol tart a kutatómunkájában, vannak-e ipari kapcsolatai, nappali vagy levelező képzésben végzi tanulmányait és persze ki mikor ér rá.

Különféle modelleket alkotunk

  • a mérnökök, fizikusok, geográfusok, biológusok többféle kísérletet végeznek el, szimulációkat terveznek és futtatnak, mérőeszközöket és műszereket használnak,
  • az informatikusok különböző matematikai eszközöket alkalmazva objektumorientált – vagy másféle – modellezést végeznek, szoftvereket terveznek, javítanak, újraírnak.

Adatokat is elemzünk, ki-ki előképzettségének megfelelően

  • kérdőívező szoftverekből exportálva valamit,
  • Excel munkalapokon, függvényekkel, adatbázis-kezelő funkciókkal, kimutatásokkal (Pivot táblák),
  • különböző fájlformátumokkal (CSV, XML, JSON, egyedi) dolgozunk és konvertálunk A-ból B-be,
  • távoli adatbázisokhoz, felhőbeli adattárházakhoz csatlakozunk, lekérdezünk és kapunk valamilyen – többnyire szabványos – adathalmazt,
  • matematikai, statisztikai szoftvereket használunk, például: MATLAB, Derive, Maple, SPSS.

Az öt évvel ezelőtti tematikát újragondoltuk. Kérdőívben felmértük a csoporttársak koncepcionális és konkrét igényeit. Más doktori iskolák hallgatói közül is toboroztunk. Ehhez kötődően köszönjük a DOSZ segítségét. Ezek alapján összeállítottunk egy olyan 3 részből álló tematikát, ami mindannyiunk számára hasznos. A 72 óra három 24 órás modulból áll: Java programozás, MATLAB programrendszer, mesterséges intelligencia.

Java programozás modul

  • 1-6. óra: Objektumorientált modellezés, MVC rétegek, algoritmus- és eseményvezérelt programozás
  • 7-12. óra: Fájlkezelés és szövegfeldolgozás (XLS, CSV, XML, JSON formátumú adatok írása, olvasása, feldolgozása), helyi és távoli adatforrásból
  • 13-18. óra: Adatbázis-kezelés JDBC alapon (SQL parancsok, CRUD műveletek, hierarchikus lekérdezések), helyi és távoli adatforrásból, natív módon és készen kapott API-kkal
  • 19-24. óra: Komplex adatfeldolgozási feladatok megoldása programozási tételek használatával, egyszerű statisztikai funkciók implementálásával

MATLAB programrendszer modul

  • 1-6. óra: Bevezetés az MATLAB nyelvbe (R2012 vs. R2022), utasításkészlet, vektorok, mátrixok, szkriptek, függvények, grafika
  • 7-12. óra: Szimulációk tervezése és készítése, numerikus módszerek áttekintése, algoritmizálása, tesztelés, analitikus megoldás, egyenletek megoldása
  • 13-18. óra: Adatok importálása helyi és távoli adatforrásból is, fájlkezelés: szövegfájlok, Excel-fájlok, import, feldolgozás, export, statisztikai alapok
  • 19-24. óra: Statisztikai próbák (illeszkedés- és függetlenség vizsgálata), hisztogramok készítése, differenciálegyenletek megoldása

Mesterséges intelligencia modul

  • 1-6. óra: Klasszikus és újabb megközelítések, alap AI funkcionalitás, megerősítéses és gépi tanulás lehetőségei és korlátai, OpenAI GPT nyelvi modell
  • 7-12. óra: Általános csevegés lehetőségei, korlátai, hasznos tanácsok; csevegés fájlok (szöveg, multimédia) tartalmáról; generatív AI funkciói; kép, ábra, grafikon, térkép, hang, animáció, videó generálása és ezek tömeges feldolgozása; programozási tételek alkalmazása multimédia analitikával együtt
  • 13-18. óra: Statisztikai adatok elemzése AI eszközökkel, automatikus tételbizonyítás AI eszközökkel, gráfelméleti kérdések kontra AI, hatékonysághoz kötődő kérdések AI eszközök esetén
  • 19-24. óra: Objektum- és aspektusorientált tervezés AI eszközökkel, kutatómunkát támogató AI eszközök

Mivel mindenki doktorandusz a csoportban, így a különböző MSc-s alapvégzettsége ellenére mindannyiunknak vannak strukturális programozáshoz kötődő alapismeretei, valamint adatok elemzéséhez szükséges elméleti matematikai/statisztikai alapjai.

A csoport órái szeptembertől decemberig, szombatonként zajlottak. Sándor tartotta a 24 órás Java programozás modult. Ez nagyban lefedi a Java SE szoftverfejlesztő tanfolyamunk tematikáját és kapcsolódik a Java EE szoftverfejlesztő tanfolyamunk és a Java adatbázis-kezelő tanfolyamunk tematikájához is. Én tartottam a 24 órás MATLAB programrendszer modult. Ketten közösen tartottuk a 24 órás Mesterséges intelligencia modult. Igazán tartalmas őszi időszakot jelentett számunkra ez a 12 szombat. Mindenki elvitte, amit beletett.

A koncepciót once-in-a-lifetime jelleggel dolgoztuk ki 🙂 (újratöltve) azzal a fő szándékkal, hogy hatékonyabban működjünk együtt a jövőben. A visszajelzések alapján bátran állíthatom, hogy ez gördülékenyen fog menni. Egyben köszönöm mindenkinek az aktív, konstruktív részvételt.

Kölcsönös ajándékozás véletlenszerűen

A kölcsönös ajándékozás időről-időre több közösségben is felmerül. Munkahelyi környezetben és iskolai csoportokban is (például: Télapó, karácsony). Hagyományos megközelítésben így hangzik a szabály: „húzzunk neveket a kalapból”. Másképpen: mindenki 1 ajándékot ad, mindenki 1 ajándékot kap és a sorsolás véletlenszerűen történik.

Készítsünk Java programot, ami megoldja a kölcsönös ajándékozást véletlenszerűen!

A neveket tároljuk el szövegfájlban ( nevsor10.txt). Soronként egy nevet. Ha különböznek, akkor elegendő a keresztnév. A soroknak/neveknek különbözniük kell. Ha szükséges, akkor hozzáírjuk a vezetéknevet, a vezetéknév első betűjét vagy sorszámot. Ezt a program beolvassa és megjegyzi egy szöveg típusú generikus nevsorLista nevű indexelhető adatszerkezetben. A nevek eredeti sorrendje nem befolyásolja a kiválasztást, mert a neveket a program összekeveri (helyben, véletlenszerűen, a shuffle() metódussal). Adott elemszámú lista indexelhető nullától elemszám-1-ig ( size()-1-ig).

A szövegfájl olvasása, tartalmának betöltése során – az ékezetes karakterek miatt – előfordulhatnak karakterkódolási problémák. Ekkor használható a readAllLines() függvény túlterhelt változata esetén a Charset típusú második paraméter, például így: Charset.forName("ISO-8859-2"). A fájlkezeléshez kötelezően kivételkezelés is szükséges (ezt most nem részletezem).

1. megoldás

Az ajándékot adó-kapó párosokat a listában egymás mellett lévő i-edik (bal) és i+1-edik (jobb) nevek adják. Az adó az elsőtől az utolsó előttiig, a kapó a másodiktól az utolsóig léptethető. Kimarad az a pár, amikor az utolsó ad és az első kap. A lista indexei szerint az adók esetében a nulladik elemétől az utolsó előtti eleméig és a kapók esetében a lista első elemétől az utolsó eleméig jelenti a kiválasztást. Mindez könnyen megoldható for számláló ciklussal. A kimaradó pár ajándékot adó tagja a lista size()-1-edik eleme és kapó tagja a lista nulladik eleme. Ez a ciklus után egyszerű kiírással megoldható.

2. megoldás

A program átmenetileg megváltoztatja a listát: az utolsó elem után bővül az első elemmel ( nevsorLista.add(nevsorLista.get(0))). Ennek köszönhetően az ajándékot adó-kapó párosokat a listában egymás mellett lévő lévő i-edik (bal) és i+1-edik nevek adják. Most nem lesz kimaradó pár, mert a korábbi utolsó elem most az utolsó előtti elem és az utolsó elem most az első. Másképpen: mindenki ad és mindenki kap.

A megoldás Stream API-t használ. Először előállít egy olyan IntStream típusú folyamot, amiben az ajándékot adó és kapó párosok adó (bal) tagjainak sorszámát/indexét tartalmazza. Ezután ezt végigjárva összefűzi a szövegeket ( mapToObj()) úgy, hogy a páros kapó (jobb) tagja az adó tag rákövetkezője. Végül a program kiírja a összefűzött szövegeket ( forEach()) a konzolra. Ha a neveket tartalmazó listát használnánk később még valamire (azaz kellene az eredeti összekevert állapota), akkor érdemes aktiválni a megjegyzésbe tett utolsó utasítást.

Eredmény

A program konzolos/szöveges eredménye mindkét esetben azonos. Persze a nevek sorrendje különbözhet, hiszen az összekeverés minden futtatás esetén másképpen alakul(hat), mert véletlenszerű. Például:

Érdemes tesztelni és átgondolni, hogy mi történne, ha üres a fájl, üres a generikus lista, 1 név van, 2 név van, illetve nem szabadna ilyet, de mi történne azonos nevek esetén. Vajon különbözik/különbözne a fenti két megoldás eredménye? Miért?

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 szakmai moduljának 17-28. óra Objektumorientált programozás és 37-44. óra: Fájlkezelés alkalmaihoz kötődik.

Kép élesítése effektus működése

Ismert számos képfeldolgozó, képjavító effektus. Az egyszerűbb effektusok elérhetők ingyenes web- és mobil alkalmazásokban, PowerPointban. Az összetettebb (művészi) effektusokhoz, szűrőkhöz már érdemes professzionális eszközt használni, ilyen például az Adobe Photoshop. Ezek a belépő szint képeffektusai kulcsszavakban: élesítés (sharpen), homályosítás (blur), elmosódás (gaussian blur), folyadékszerű rajz (liquid), olajfestmény (oil painting), öregítés (sepia), szürkeskála (grayscale).

Lássuk, hogyan valósítható meg Java programozási nyelven a kép élesítése!

A kép adatszerkezete

Adott egy képfájl. Formátuma a tipikus, feldolgozhatók (JPG, GIF, PNG, WebP) egyike. Ezek rasztergrafikus képformátumok. Lekérdezhető a dimenziója: ez képpontban (pixelben) jelenti a kép szélességét (width) és a kép magasságát (height). A vászontechnika meghatározza a kép origóját (0, 0) és a képpontok kétdimenziós koordinátapárját. A kép origója a bal felső sarokban van. A kép oszlopai (column) jobbra haladva növekvő módon, a kép sorai (row) lefelé haladva növekvő módon számozottak. Egy pixel koordinátapárja (c, r) alakban írható le. Minden pixel három szín kombinációjaként áll elő (r, g, b). Másképpen: a piros, zöld és kék összetevők aránya alapján meghatározott. A tipikus színmélység alapján a színek külön-külön 256-félék lehetnek, és ezeket 0-tól 255-ig egész szám képviseli. A 0 az adott szín hiányát, a 255 a szín teljes intenzitását jelenti.

A kép élesítéséhez használható szűrőmátrixok

A kép élesítése során szűrőt alkalmazunk a kép belső pixeleire. A kép 4 szélén lévő pixeleket nem változtatjuk. Többféle szűrő közül választhatunk, íme két példa:

A három színösszetevőre külön-külön kell alkalmazni a szűrőt. Az aktuális pixel – amire alkalmazzuk a szűrőt – a 3×3-as mátrix középső eleméhez igazítva szorzóértékeket tartalmaz. A konkrét eset: az a mátrix esetén az 5 érték a 2. sor 2. oszlopában helyezkedik el; ennek a közvetlen szomszédos pixeleire a -1 értékek, átlós szomszédaira pedig a 0 értékek vonatkoznak. Eredményül a szűrt pixel színeit kapjuk meg külön-külön. Ha a kapott értékek kisebbek 0-nál, akkor nullázzuk őket. Ha a kapott értékek nagyobbak 255-nél, akkor beállítjuk azokat 255-re. Az a szűrőmátrix kevésbé élesít, a b szűrőmátrix erősebben élesít.

Természetesen sok más képélességhez köthető szűrő is van még. Olyanok is vannak, ahol nem csak a közvetlen szomszédos pixeleket veszi figyelembe az algoritmus. További kulcsszavak a témához kötődően: digitális képfeldolgozás, lokális operátor, korreláció, konvolúció, átlagszűrő, mediánszűrő, zajszűrő, Laplace-szűrő.

A kép élesítését megvalósító Java forráskód-részlet

A fenti a mátrixot a SHARP_FILTER konstans kétdimenziós tömb tárolja. A paraméterként átvett BufferedImage típusú img1 objektum kép pixeleinek végigjárását ütközőként segíti a w szélesség és h magasság. A data egydimenziós tömb sorfolytonosan tárolja a kép pixeleit. Az if elágazó utasítás igaz ága kezeli a kép 4 szélét (változatlanul hagyott másolt színek). Az if hamis ága a belső pixelekre alkalmazza a szűrőmátrixot. A red, green, blue változók tartalmazzák az aktuális pixel színeit, amelyekbe az eredeti pixelre alkalmazott szűrő által szorzott értékek kerülnek, „belekényszerítve” a 0-255 zárt intervallumba. Végül az eredményül visszaadott img2 kép pixelei kerülnek beállításra. Az alábbi sharpenEffect() függvény mindezt megoldja az alábbiak szerint:

A metódus meghívása a fájlkezelést is tartalmazó vezérlőmetódusban például így történhet:

Az eredeti és élesített képek összehasonlítása

A bal oldalon az eredeti kép, a jobb oldalon az a mátrixszal élesített kép látható:

A bal oldalon az eredeti kép, a jobb oldalon a b mátrixszal élesített kép látható:

A látvány alapján fontos kiemelni, hogy másképpen is lehet összehasonlítást végezni. Például: színtérkép, színmélység, színösszetevők aránya (hisztogram).

Ötletek továbbfejlesztésre

  • Konzolos program átvehetné parancssori paraméterként a szűrőmátrixot, vagy annak nevét, kódját, egyes értékeit.
  • Grafikus felületű programban vízszinten JScrollBar  GUI komponens(ek) segítségével paraméterezhető, kigörgethető lehetne a szűrőmátrix szélsőértéke(i).
  • A fenti effektek a kép összes pixelét érintik. GUI felületen megoldható az is, hogy ki tudjuk jelölni a kép egy-egy részét, amire alkalmazni szeretnénk az effektek. Ez a kijelölés többféle lehet, például téglalap alakú, szabálytalan, átlátszó, adott vagy adotthoz hasonló árnyalatú színű, vagy valaminek a körvonala.
  • Egy mappában lévő összes képre alkalmazható effekt, előnézettel, képfájlonként megerősítéssel, jóváhagyással, csoportos kijelöléssel, szűrővel.
  • Szürkeskála effekt megvalósítása és tesztelése az alábbi forráskód-részlettel:
  • Homályosítás effekt megvalósítás és tesztelése a 4 élszomszéd színeinek átlagolásával, így:

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 Java SE szoftverfejlesztő tanfolyamunkon, a szakmai modul Objektumorientált programozás témakörét követő 29-36. óra Grafikus felhasználói felület alkalmain már tudunk egyszerűbb GUI programot tervezni, kódolni, tesztelni, kiegészítve a 37-44. óra Fájlkezelés alkalmaihoz kötődő példaprogramokkal.