Ciele
- Oboznámiť sa s tvorbou grafického používateľského rozhrania.
- Oboznámiť sa s udalosťami riadeným vykonávaním programu.
- Implementovať grafické používateľské rozhranie Swing pre hru Minesweeper.
Úvod
-
Dnes vytvoríme grafické používateľské rozhranie pre našu hru Minesweeper.
Postup
-
Pridajte do triedy
Minesweepernasledujúcu metódu. Táto metóda sa bude používať pre začatie hrania novej hry.
Teraz ju možete použiť v konštruktorepublic void newGame() { Field field = new Field(setting.getRowCount(), setting.getColumnCount(), setting.getMineCount()); startMillis = System.currentTimeMillis(); userInterface.newGameStarted(field); }Minesweeperna začatie prvej hry. -
V nasledujúcom kroku pridajte do projektu Minesweeper triedy pre grafické používateľské rozhranie.Úloha: Pridajte do projektu (do adresáraArchív obsahuje adresár
src) obsah archívu swingui.zip.imgs obrázkami a balíkminesweeper.swingui. V balíkuminesweeper.swinguisú triedyTileComponentaSwingUI. Oboznámte sa s triedamiTileComponentaSwingUI.-
Trieda
TileComponentje grafický komponent slúžiaci pre vykreslenie jednej dlaždice hracieho poľa. -
Trieda
SwingUIpredstavuje okno hry a zároveň implementuje rozhranieUserInterface.
-
Trieda
-
Nasledujúcim krokom je zobrazenie hracej plochy v okne aplikácie.Úloha: Implementujte metóduV rámci tejto metódy je potrebné vykonať nasledujúce kroky:
public void newGameStarted(Field field)triedySwingUI.-
Inicializovať premennú objektu
fieldargumentom metódynewGameStarted(Field field). -
Odstrániť všetky komponenty, ktoré obsahuje panel
contentPanelprostredníctvom volaniacontentPanel.removeAll()(Komponenty sa odstraňujú z dôvodu vytvorenia nového hracieho poľa). Nastavte pre panelcontentPanelmanažér rozmiestnenia na typGridLayoutprostredníctvom aplikáciecontentPanel.setLayout(new GridLayout(field.getRowCount(), field.getColumnCount())) -
Vytvoriť pre každú dlaždicu hracieho poľa grafický komponent triedy
TileComponentspätý s danou dlaždicou. -
Tento komponent následne pridajte do kontajnera hracieho poľa
contentPanelpomocou metódyComponent add(Component comp). -
Pre každý komponent dlaždice je potrebné nastaviť spracovanie udalosti pre stlačenie tlačidla myši -
MouseListener. Pre nastavenie spracovania udalosti použite metóduvoid addMouseListener(MouseListener l). TriedaSwingUIimplementuje rozhranieMouseListener.public class SwingUI extends JFrame implements UserInterface, MouseListener {...} -
Aplikovať metódu
update()triedySwingUIpre zobrazenie počiatočného stavu hracieho poľa. -
Aplikovať metódu
pack()triedySwingUIzabezpečujúcu rozloženie komponentov hlavného okna hry Minesweeper s cieľom minimalizácie veľkosti okna (kompaktný tvar).
Úloha: Implementujte metódupublic void update()triedySwingUI. V tejto metóde je nutné nad každým grafickým komponentom triedyTileComponentaplikovať metóduupdateStyle(). Taktiež je potrebné aktualizovať počítadlo zostávajúcich neoznačených mín aplikovaním metódysetMinesLeftLabelText()triedySwingUI. -
Inicializovať premennú objektu
-
Ďalším krokom je definovanie spracovania udalosti nad dlaždicami hracej plochy hry Minesweeper.Úloha: Implementujte metóduVykonanie tejto metódy je určené nasledujúcimi krokmi:
public void mousePressed(MouseEvent e)triedySwingUI. Táto metóda je implementáciou reakcie na stlačenie tlačidla myši nad grafickým komponentom triedyTileComponent.-
Podmienkou reakcie na stlačenie myši je stav hry
GameState.PLAYING. V inom prípade by nemalo byť hracie pole menené. -
Pri stlačení ľavého tlačidla myši je potrebné aplikovať metódu
void openTile(int row, int column)objektu hracieho poľa triedyField. Pozícia grafického komponentu dlaždice v hracom poli je prístupná v objekte grafického komponentuTileComponent.Poznámka: Komponent dlaždice nad ktorou bola myš stlačená je možné získať z objektu udalosti nasledovne:TileComponent button = (TileComponent)e.getSource();Poznámka: Pre identifikovanie stlačenia ľavého tlačidla myši použite statickú metóduisLeftMouseButton(MouseEvent e)triedySwingUtilities. -
V prípade, že sa zmenil stav hry na stav
GameState.FAILED, je potrebné vypísať používateľovi v dialógovom okne informáciu o chybnom ukončení hry.Poznámka: Pre zobrazenie dialógového okna s požadovanou informáciou použite statickú metóduvoid showMessageDialog(Component parentComponent, Object message, String title, int messageType)triedyJOptionPane. -
V prípade, že sa zmenil stav hry na stav
GameState.SOLVED, je potrebné vypísať používateľovi v dialógovom okne informáciu o úspešnom ukončení hry. Taktiež je potrebné zapísať používateľa do tabuľky najlepších časov použitím metódyvoid addPlayerTime(String name, int time)triedyBestTimes. Pre získanie času hrania hry použite metódugetPlayingSeconds()objektu triedyMinesweeper. Pre získanie mena používateľa použite výrazSystem.getProperty("user.name"), ktorý poskytne hodnotu systémovej premennej prostrediauser.namepredstavujúcu meno používateľa prihláseného do systému. -
Pri stlačení pravého tlačidla myši je potrebné aplikovať metódu void
markTile(int row, int column)objektu hracieho poľa triedyField.Pre identifikovanie stlačenia pravého tlačidla myši použite statickú metóduisRightMouseButton(MouseEvent e)triedySwingUtilities. -
Po vykonaní odkrytia resp. označenia dlaždice je potrebné prekresliť hracie pole aplikovaním metódy
update()triedySwingUI.
-
Podmienkou reakcie na stlačenie myši je stav hry
-
V tomto kroku je potrebné realizovať zobrazenie zoznamu najlepších časov hráčov hry Minesweeper.Úloha: Vytvorte dialóg na zobrazenie času najlepších hráčov.Inšpirujte sa nasledujúcim vzorom:
-
Vytvorte triedu
BestTimesDialogtypuJDialog(„File > New File... > Java GUI Forms > Swing GUI Forms”). Nezabudnite zaradiť túto triedu do balíkaminesweeper.swingui. -
Odstráňte metódu
mainv triedeBestTimesDialog. -
V konštruktore triedy
BestTimesDialogimplementujte zobrazenie najlepšieho skóre získaného aplikovaním metódygetBestTimes()nad objektom triedyMinesweeper. Informácie o časoch zobrazte do grafického prvkuJTextArea(pomocou metódyvoid setText(String t)).Poznámka: Pre vycentrovanie dialógového okna nad oknom hracej plochy použite metódusetLocationRelativeTo(Component c)nad objektom dialógového okna. -
Zaregistrujte nad tlačidlom s textom „OK” obsluhu udalosti
ActionListener. V prostredí NetBeans v zobrazení návrhu dialógového okna označte komponent tlačidla. V okne s názvom „Properties” zvolíte záložku „Events” a kurzor nastavíte do textového poľa pre zadanie názvu udalosti „actionPerformed”. Stlačte „Enter”. V zdrojovom kóde sa automaticky vytvorí metóda pre spracovanie udalosti. Ak bude grafický komponent tlačidla pomenovaný názvomokButton, tak metóda bude vygenerovaná v nasledujúcej forme:
Implementujte spracovanie udalosti pre stlačenie tlačidla nasledovne:private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: }
Daný kód zatvorí dialógové okno a uvoľní zdroje späté s oknom.setVisible(false); dispose(); -
V triede
SwingUIdodajte implementáciu stlačenia menu „Game > Best Times...”. Na vyhľadanie položky menubestTimesMenuItempoužite okno „Inspector”. Postupujte podľa postupu uvedenom hore. Implementácia reakcie na udalosť je nasledovná.new BestTimesDialog(this, true).setVisible(true);
-
Vytvorte triedu
-
Pre zaradenie implementovaného grafického používateľského rozhrania do hry Minesweeper je potrebné vykonať úpravu v hlavnej triede aplikácie podľa nasledujúcich úloh.Úloha: V triede
Minesweeperdefinujte premennúprivate static final String DEFAULT_UI = "swing". Na základe hodnoty tejto premennej sa určí, aký typ používateľského rozhrania bude použitý (SwingUI, aleboConsoleUI).Úloha: Implementujte metóduMetóda na základe mena grafického rozhrania vytvorí požadovaný objekt rozhrania (návrhový vzor Factory Method).private UserInterface create(String name)v triedeMinesweeper.-
Ak hodnota parametra name je rovná "
swing", tak návratovou hodnotou bude objekt grafického používateľského rozhrania typuSwingUI. -
Ak hodnota parametra name je rovná hodnote "
console", tak návratovou hodnotou bude objekt používateľského rozhrania typuConsoleUI. -
Ak hodnota
DEFAULT_UInie je rovná ani jednej z vyššie uvedených hodnôt, tak vznikne objekt výnimky typuRuntimeExceptionso správou "No valid UI specified".
Úloha: Pridajte aplikáciu metódycreate(DEFAULT_UI)do konštruktora triedyMinesweeper. -
Ak hodnota parametra name je rovná "
-
Vymažte projekt z disku a zrušte všetky vami vytvorené nastavenia v prostredí NetBeans!
Zdroje
- Zdrojové kódy:
Doplňujúce úlohy
Úloha:
Implementujte voľbu typu používateľského rozhrania pomocou argumentov príkazového riadku
(prepínač
-swing resp. -console).
Úloha:
Dodajte podporu pre odkrývanie susedných dlaždíc pri stlačení oboch tlačidiel myši naraz.
Úloha:
Rozšírte stav dlaždice o označenie otáznikom.





TileComponentsú uložené priamo v panelicontentPanel. Prechádzať prvkami môžete prostredníctvom metódcontentPanel.getComponentCount()acontentPanel.getComponent(index).