3. diel - Programovanie jednoduchých Java GUI hier - Text
V tomto diele nadviažeme na predchádzajúce časť, kedy sme si ukázali ako kresliť a písať na JPanel. Teraz budeme na JPanel vykresľovať text. Tiež si povieme niečo o písmach.
Umiestnenie textu
Kresliť už vieme. Skúste si ale u predchádzajúceho príkladu zmeniť veľkosť okna. Umiestnenie nakreslených tvarov sa nijako nezmení. Ak okno zmenšíme, nakreslené objekty môžu zostať mimo. To nám vadiť nemusí, ale môžeme napríklad chcieť umiestniť tvar doprostred okna. To docielime buď metódou pokus-omyl alebo vypočítame pozíciu podľa veľkosti panelu a veľkosti tvaru. U tvaru veľkosť zistíme jednoducho volaním funkcie getWidth () poprípade getHeight (). Ako ale zistíme veľkosť textu?
import javax.swing.JFrame; public class KresleniTextu extends JFrame { public KresleniTextu() { this.setTitle("Kreslení Textu"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); KresliciPanel panel = new KresliciPanel(); this.add(panel); this.pack(); } public static void main(String[] args) { new KresleniTextu().setVisible(true); } }
Hlavná trieda by nás nemala nijako prekvapiť, iba vás upozorním na hlavnú metódu.
public static void main(String[] args) { new KresleniTextu().setVisible(true); }
Tento zápis zodpovedá zápisu
public static void main(String[] args) { KresleniTextu kresleni = new KresleniTextu(); KresleniTextu().setVisible(true); }
, Ale ušetrí nám jeden riadok a nemusíme vymýšľať názov pre tvorený objekt. Ak by sme s objektom ďalej pracovali a odovzdávali ho ako parameter, museli by sme použiť dlhší zápis. Pretože ho však nikde ďalej nepoužívame, môžeme si zápisnicu skrátiť.
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import javax.swing.JPanel; public class KresliciPanel extends JPanel { String text = "GAME OVER"; public KresliciPanel() { this.setPreferredSize(new Dimension(400, 300)); this.setBackground(Color.BLUE); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 28)); g.setColor(Color.RED); g.drawString(text, 120, 150); } }
Farbu pozadia sme nastavili na modrú farbu, font na bezpätkové, tučný, veľkosť 28px a farbu textu na červenú. Začiatok textu sme umiestnili na súradnici [120, 150], takže je dajme tomu uprostred panelu. Ak zmeníme veľkosť okna, text zostane na zadaných súradniciach.
A teraz to urobíme inak. Text bude umiestnený symetricky nehľadiac na veľkosť okna a prípadnej zmene veľkosti okna sa prispôsobí. Trieda hlavného okna zostane rovnaká, mení sa iba panel.
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import javax.swing.JPanel; public class KresliciPanel extends JPanel { private String text = "GAME OVER"; public KresliciPanel() { this.setPreferredSize(new Dimension(400, 300)); this.setBackground(Color.BLUE); } public void paintComponent(Graphics g) { //vykreslení pozadí super.paintComponent(g); //nastavení typu a velikosti písma Font pismo = new Font(Font.SANS_SERIF, Font.BOLD, 28); g.setFont(pismo); //nastavení barvy g.setColor(Color.RED); //získání šířky a výšky panelu int sirkaPanelu = this.getWidth(); int vyskaPanelu = this.getHeight(); //objekt FontMetrics pro daný typ písma FontMetrics fm = g.getFontMetrics(pismo); //získání šířky a výšky textu v daném grafickém kontextu int sirkaTextu = fm.stringWidth(text); //nakreslení textu na dané umístění g.drawString(text, ((sirkaPanelu - sirkaTextu) / 2), (vyskaPanelu / 2)); } }
Úvodná časť je rovnaká, len pripomeniem, že volaním rodičovskej metódy pomocou super vykresľujú pozadia.
int sirkaPanelu = this.getWidth(); int vyskaPanelu = this.getHeight();
JPanel umožňuje zistiť svoju veľkosť a to metódami getWidth () a getHeight (). Môžete sa opýtať, prečo zisťovanie veľkosti panelu vykonávam v metóde paintComponent () a nie napríklad v konstruktoru. Dôvod je ten, že metóda paintComponent () sa volá nielen pri prvom zobrazení komponenty, ale tiež treba pri zmene veľkosti. Nasledujúci výpočet pozície texte teda robím vždy, keď je paintComponent () zavolaná.
FontMetrics fm = g.getFontMetrics(pismo);
Pre zistenie vlastností daného písma voláme metódu getFontMetrics (pismo), ktorá nám vracia objekt typu FontMetrics. Pomocou tohto objektu môžeme zisti množstvo informácií o danom písme ako napríklad sklon či šírku jednotlivých znakov, šírku a výšku určitého textu alebo získať obrysový obdĺžnik (obdĺžnik o výške a šírke textu).
int sirkaTextu = fm.stringWidth(text);
Voláme metódu stringWidth objektu FontMetrics, ktoré ako parameter zadáme text, ktorého dĺžku chceme poznať.
g.drawString(text, ((sirkaPanelu - sirkaTextu) / 2), (vyskaPanelu / 2));
Nakreslenie reťazca na pozícii ((sirkaPanelu - sirkaTextu) / 2) a (výška panelu / 2) = text je uprostred (na výšku približne).
Ak neviete, aké typy písma máte k dispozícii, alebo aké budú k dispozícii na počítačoch, kde sa vaše programy budú spúšťať, môžete použiť "symbolická mená":
Font.MONOSPACED, Font.SERIF, Font.SANS_SERIF
Sú to konštanty triedy Font. Monospaced je neproporcionálne písmo, serif je pätkové písmo (má kolmé čiarky na konci znakov) a sansserif je písmo bezpätkové (nemá kolmé čiarky na konci znakov).
Pri použití vyššie uvedených konštánt sa použije písmo vždy z danej rodiny písiem (neproporcionálne, pätkové, bezpätkové), ktoré sa nachádza na danom počítači. Ak použijete písmo sansserif a program bude bežať na počítači s Windows, tak sa pravdepodobne použije typ písma Arial. Pokiaľ bude na počítači Linux, použije sa typ písma Helvetica.
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import javax.swing.JPanel; public class KresliciPanel extends JPanel { private String text = "GAME OVER"; private int size = 20; private Font monospacedPlain = new Font(Font.MONOSPACED, Font.PLAIN, size); private Font monospacedBold = new Font(Font.MONOSPACED, Font.BOLD, size); private Font monospacedItalic = new Font(Font.MONOSPACED, Font.ITALIC, size); private Font monospacedBoldItalic = new Font(Font.MONOSPACED, Font.BOLD + Font.ITALIC, size); private Font serifPlain = new Font(Font.SERIF, Font.PLAIN, size); private Font serifBold = new Font(Font.SERIF, Font.BOLD, size); private Font serifItalic = new Font(Font.SERIF, Font.ITALIC, size); private Font serifBoldItalic = new Font(Font.SERIF, Font.BOLD + Font.ITALIC, size); private Font sansserifPlain = new Font(Font.SANS_SERIF, Font.PLAIN, size); private Font sansserifBold = new Font(Font.SANS_SERIF, Font.BOLD, size); private Font sansserifItalic = new Font(Font.SANS_SERIF, Font.ITALIC, size); private Font sansserifBoldItalic = new Font(Font.SANS_SERIF, Font.BOLD + Font.ITALIC, size); public KresliciPanel() { this.setPreferredSize(new Dimension(200, 600)); this.setBackground(Color.white); } public void paintComponent(Graphics g) { //vykreslení pozadí super.paintComponent(g); g.setFont(monospacedPlain); g.drawString(text, 20, 40); g.setFont(monospacedBold); g.drawString(text, 20, 80); g.setFont(monospacedItalic); g.drawString(text, 20, 120); g.setFont(monospacedBoldItalic); g.drawString(text, 20, 160); g.setFont(serifPlain); g.drawString(text, 20, 240); g.setFont(serifBold); g.drawString(text, 20, 280); g.setFont(serifItalic); g.drawString(text, 20, 320); g.setFont(serifBoldItalic); g.drawString(text, 20, 360); g.setFont(sansserifPlain); g.drawString(text, 20, 440); g.setFont(sansserifBold); g.drawString(text, 20, 480); g.setFont(sansserifItalic); g.drawString(text, 20, 520); g.setFont(sansserifBoldItalic); g.drawString(text, 20, 560); } }
Pre písmo základné, tučné a italikom existujú konštanty v triede Font. S tými sme sa už zoznámili. Tieto konštanty sú typu int.
Font.BOLD + Font.ITALIC
Nám vytvorí hodnotu pre tučnú kurzívu.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 258x (3.64 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java