Az ENSZ 1987-ben július 11-ét a népesedési világnappá (World Population Day) nyilvánította. Bolygónk lakossága aznap érte el az 5 milliárdot. További kerek számok voltak: 1999. október 12-én 6 milliárd, 2011. október 30-án 7 milliárd. További kerek számok várhatóak: 2023 – 8 milliárd, 2037 – 9 milliárd, 2057 – 10 milliárd. A KSH elemzése részletes elemzéseket közöl évről-évre a témában, például: 2019-ben, 2018-ban. A worldometer.info weboldalon folyamatosan frissülő kimutatások érhetők el a népességhez globálisan, valamint országonként is: például Magyarország aktuális népesedési adatai.
A népesedési világnap inspirált egy Java program megtervezésére és megírására. A swing GUI-s program megjeleníti a worldometer.info weboldalról kinyerhető adatok alapján régiónként (kontinensenként) az elérhető adatokat 1950-től 2020-ig az alábbiak szerint egy világtérképen.
Az elkészült program
Tervezés
Objektumorientált szemlélettel, MVC architekturális tervezési mintát követünk, angol nyelvű interfész, osztály, változó, objektum, metódus nevekkel. A projekt neve: WorldPopulation, a csomag neve: worldpopulation. Amit lehet, konstansként interfészbe (szeparálva) teszünk és az MVC rétegekhez kötődő osztályok implementálják. A modell minden évszámhoz tárolja a szükséges adatokat, mindezt egyetlen betöltéssel/letöltéssel éri el. A program kliensként hat régióra vonatkozó adatot gyűjt össze, alkalmazkodva a szerver adatforráshoz. A címsorban lévő összesített adat is elérhető közvetlenül a weboldalon, de a kisebb adatforgalom érdekében hasznos inkább a kliensben összesíteni. Mindössze egyetlen eseménykezelés szükséges: a csúszka beállításával megadott évszám alapján frissíteni kell a régiók címkéit és az ablak címsorát. Öröklődés hasznos a feladat megoldása során: egyrészt interfészek, másrészt osztályok között.
Interfészek
Az ősinterfész a WorldPopulationConstants, benne az évszám intervallum MIN_YEAR és MAX_YEAR határaival, valamint a megjeleníthető régiók neveivel tömbben: REGION_NAME_ARRAY. Két utódinterfész épül az ősre: ModelConstants és ViewConstants. Előbbi interfész az adatforráshoz kapcsolódik: URL_COMMON az URL eleje, URL_ARRAY az URL végei régiónként tömbben. Utóbbi interfész a megjelenítéshez kapcsolódik: WORLD_MAP_IMAGE a háttérkép annak WORLD_MAP_RECT méretével együtt, valamint a régiónkénti REGION_RECT_ARRAY téglalapok tömbje a kezdeti pozíciókkal/méretekkel, TITLE a sablon a program címsorához (frissítendő az évszámmal és az összesített népességgel). A megfelelő utódinterfészt mindig implementálja az MVC szerint hozzá illeszkedő osztály.
Osztályok
A belépési pont a WorldPopulation.java fájlban található.
Három összetartozó elemi adatot fog össze egybe a RegionData POJO, ezek name, year, population nevű rendre String, int, long típusú adatok. Például: Európa, 2020, 747643253. Tartalmaz két függvényt: getPopulation(), valamint toString(). Utóbbi HTML formátumban adja vissza a megjelenítendő adatokat.
A JLabel-ből származik az igényekhez alakított RegionLabel osztály. Ennek van előre megadott pozíciója, mérete, betűtípusa, betűmérete, sárga háttérszíne, piros kerete. Ezenkívül a téglalap átlátszó, valamint a benne megjelenő HTML tartalom vízszintesen középre igazított. Némi extra funkció, hogy egérrel megfogva – drag and drop – áthelyezhető, ami a MouseMotionListener egérmozgást figyelő interfész mouseDragged() metódusának felülírásával válik lehetővé. A mozgathatóságáért saját maga felel. Példaként közöljük az osztály teljes forráskódját:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package worldpopulation; import java.awt.Color; import java.awt.Font; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.SwingConstants; public class RegionLabel extends JLabel { public RegionLabel(Rectangle bounds) { setBounds(bounds); setFont(new Font("Tahoma", Font.PLAIN, 14)); setHorizontalAlignment(SwingConstants.CENTER); setBorder(BorderFactory.createLineBorder(Color.RED, 2, true)); setBackground(Color.YELLOW); setOpaque(true); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { setLocation(getX()+e.getX()-getWidth()/2, getY()+e.getY()-getHeight()/2); } }); } } |
A webről adatokat szerez és tárolja a Model osztály, a java.io és java.net csomagokra építve. Egy példa: a https://www.worldometers.info/world-population/europe-population/ oldal forrásából nyeri ki az osztály az alábbi adatokat:
1 2 3 4 5 6 7 8 9 10 11 |
var dataT=new google.visualization.DataTable( {cols: [ {type:'date',label:'Date'},{type:'number',label:'Europe Population'} ], rows: [ {c:[{v:new Date(1950,6,1)},{v:549328883}]}, {c:[{v:new Date(1951,6,1)},{v:554324469}]}, ... {c:[{v:new Date(2019,6,1)},{v:747182751}]}, {c:[{v:new Date(2020,6,1)},{v:747636026}]} ]}); |
Ezek parszolását követően elkészül egy optimálisnak tekinthető, generikus listákból álló regionListArray tömb adatszerkezet. A parszolás történhet egyszerű szövegkezeléssel vagy JSON feldolgozással is. Erre épülnek a konstruktorral és vezérlővel összehangoltan működő getter metódusok: getHTML(), getRegionList(), getRegionData(), getPopulation(). A JSON adatforrás feldolgozását most nem részletezzük, de hasonlóról blogoltunk már: Időjárás Budapesten.
A grafikus felhasználói felületet adja a JFrame utód View osztály. Három GUI komponensből áll: pnWorldMap – háttérkép JPanel, lbYear – kiválasztott/aktuális év JLabel, slYear – kiválasztható/görgethető aktuális év JSlider. Izgalmas megoldani egymásra/egymáson elhelyezni a komponenseket. Egy JLayeredPane komponens DEFAULT_LAYER rétegére kerül a térképet tartalmazó háttérkép, majd a PALETTE_LAYER rétegére kerül dinamikusan a hat RegionLabel osztályú/típusú objektum. A csúszka komponens slYearStateChanged() eseménykezelő metódusa vezérlőként megszólítja a modell réteget és a visszakapott adatokkal frissíti a nézet réteget (a címsorban lévő összesítéssel együtt, ezres szeparátorokkal).
Ötlet továbbfejlesztésre
Hat különböző weboldal forráskódjából kell összegyűjteni a megjelenítendő adatokat. Ez 2020-ban régiónként 71 számot jelent és hat régió van. Érdemes lehet olyan adattárolást megvalósítani, amely csökkenti a szerverhez fordulások számát, illetve a letöltendő adatok mennyiségét. Hiszen a múltbeli évekhez kötődő historikus adatok nem változnak. Ha ezekre valamilyen formában a program emlékszik, akkor elegendő az utolsó tárolt évből kiindulva az aktuális évig évenként, régiónként lekérni mindössze 6, 12, 18… számot, a program utolsó futtatásának évéből kiindulva. Ez lényegesen kevesebb lenne, mint a jelenlegi 6*71 lekért szám. A koncepció kulcsszava: inkrementális adatfrissítés. Ha megvalósítjuk az ötletet, akkor figyelni kell arra, hogy az aktuális/utolsó évben az adatok akár másodpercenként is változhatnak.
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 tematikájához kötődik (ha a swing GUI-ra koncentrálunk és az adatok helyi fájlrendszerből elérhetők), és a Java EE szoftverfejlesztő tanfolyam tematikájához kapcsolódik (ha az adatokat közvetlenül a webről olvassuk).
A magyarországi adatok a KSH honlapján:
– Népességtudományi Kutatóintézet: https://www.demografia.hu/hu/tudastar/nepesseg-eloreszamitas
– Kohorsz ‘18 Magyar Születési Kohorszvizsgálat: https://www.kohorsz18.hu/eredmenyek/elozetes-eredmenyek.html
– „A legutóbbi, 2018-as előreszámítás eredményei szerint az alapváltozatban 2070-ben várhatóan 7 millió 750 ezer fő lesz Magyarország népessége; a magas változat 9 millió 70 ezres népességszámot jelez, az alacsony változatban 6 millió fő szerepel.”, forrás: https://demografia.hu/hu/kutatasok/17-kutatasok-egyenkent/175-nepesseg-eloreszamitasok
2100-ig a világ népességének előrejelzése kontinensenként, grafikonon:
https://www.ksh.hu/interaktiv/grafikonok/vilag_nepessege.html
Szuper lekérdezéseket lehet összekattintani a https://population.un.org/wpp/ weboldalon. Hasznos lehet gyakorolni.
Ugyanitt elérhető egy nagyon részletes, sok cikket és adatot tartalmazó 164 oldalas kiadvány angolul: https://www.unfpa.org/sites/default/files/pub-pdf/UNFPA_PUB_2020_EN_State_of_World_Population.pdf
Hosszú távú előrejelzés sokféle mutatószámmal, táblázattal, grafikonnal, térképpel:
– A népesség növekedése a világon
– Várható élettartam
– Termékenységi mutatók
– Korszerkezet
https://ourworldindata.org/future-population-growth
Csilla, András, Bálint: köszönjük a sok témához kapcsolódó kiegészítést, linket.
Tutorial a több rétegben összeállított swing GUI építésére:
https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html
Mintaprogram:
https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html#LayeredPaneDemo
Ha jól értem a RegionLabel forráskódjából, akkor a területek mozgatása azon alapul, hogy mi a közepe és a felső bal csúcs különbsége, ezért „darabos” egy kicsit. Lenne ötletem a finomítására. Megbeszélhetjük a ma esti Skype-on?
Andrea: hogyne. Nekem is van kétféle megoldásom erre. Lehet, hogy az egyik ugyanaz, mint a Tiéd? Hasonlítsuk majd össze.
Ez a többrétegű grafika emlékeztet a régi, DOS-os Super Mario játék kinézetére. Ott is egy statikus, állandó háttérkép volt és előtte mozogtak a figurák. Nagy-nagy kedvencem volt.
Norbert: kb. azonos korosztályba tartozhatunk. Ezek szerint Te is tudod még mi az a flopi, nem csak a pen-drive, meg a felhőbeli tárhely. Persze nem csak úgy, hogy az a mentés ikonja a Word-ben. 😉
2022. november 15-én a világ népessége elérte a 8 milliárdot: