Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - Programování jednoduchých Java GUI her - Text

V minulé lekci, Programování jednoduchých Java GUI her - Kreslení, jsme si ukázali, jak na JPanel kreslit různé tvary a text a pokračovali jsme v tvorbě grafické hry v Java Swing.

V tomto díle navážeme na předchozí část, kdy jsme si ukázali jak kreslit a psát na JPanel. Nyní budeme na JPanel vykreslovat text. Také si řekneme něco o písmech.

Umístění textu

Kreslit již umíme. Zkuste si ale u předchozího příkladu změnit velikost okna. Umístění nakreslených tvarů se nijak nezmění. Pokud okno zmenšíme, nakreslené objekty mohou zůstat mimo. To nám vadit nemusí, ale můžeme například chtít umístit tvar doprostřed okna. Toho docílíme buď metodou pokus-omyl nebo vypočítáme pozici podle velikosti panelu a velikosti tvaru. U tvaru velikost zjistíme jednoduše voláním funkce getWidth() popřípadě getHeight(). Jak ale zjistíme velikost 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í třída by nás neměla nijak překvapit, pouze vás upozorním na hlavní metodu.

public static void main(String[] args) {
    new KresleniTextu().setVisible(true);
}

Tento zápis odpovídá zápisu

public static void main(String[] args) {
    KresleniTextu kresleni = new KresleniTextu();
    KresleniTextu().setVisible(true);
}

, ale ušetří nám jeden řádek a nemusíme vymýšlet název pro tvořený objekt. Pokud bychom s objektem dále pracovali a předávali ho jako parametr, museli bychom použít delší zápis. Protože ho však nikde dále nepoužíváme, můžeme si zápis zkrátit.

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);
    }
}

Barvu pozadí jsme nastavili na modrou barvu, font na bezpatkový, tučný, velikost 28px a barvu textu na červenou. Začátek textu jsme umístili na souřadnici [120, 150], takže je dejme tomu uprostřed panelu. Pokud změníme velikost okna, text zůstane na zadaných souřadnicích.

Vykreslování textu na graphics v Java Swing - Tvorba her v Java Swing

A teď to uděláme jinak. Text bude umístěn symetricky nehledě na velikost okna a případné změně velikosti okna se přizpůsobí. Třída hlavního okna zůstane stejná, mění se pouze 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));
    }
}
Centrování textu v Java Swing - Tvorba her v Java Swing

Úvodní část je stejná, jen připomenu, že voláním rodičovské metody pomocí super vykreslujeme pozadí.

int sirkaPanelu = this.getWidth();
int vyskaPanelu = this.getHeight();

JPanel umožňuje zjistit svoji velikost a to metodami getWidth() a getHeight(). Můžete se zeptat, proč zjišťování velikosti panelu provádím v metodě paintComponent() a nikoliv třeba v konstruktoru. Důvod je ten, že metoda paintComponent() se volá nejen při prvním zobrazení komponenty, ale též třeba při změně velikosti. Následující výpočet pozice textu tedy provádím vždy, když je paintComponent() zavolána.

FontMetrics fm = g.getFontMetrics(pismo);

Pro zjištění vlastností daného písma voláme metodu getFontMetric­s(pismo), která nám vrací objekt typu FontMetrics. Pomocí tohoto objektu můžeme zjisti řadu informací o daném písmu jako například sklon či šířku jednotlivých znaků, šířku a výšku určitého textu nebo získat obrysový obdélník (obdélník o výšce a šířce textu).

int sirkaTextu = fm.stringWidth(text);

Voláme metodu stringWidth objektu FontMetrics, které jako parametr zadáme text, jehož délku chceme znát.

g.drawString(text, ((sirkaPanelu - sirkaTextu) / 2), (vyskaPanelu / 2));

Nakreslení řetězce na pozici ((sirkaPanelu - sirkaTextu) / 2) a (výška panelu / 2) = text je uprostřed (na výšku přibližně).

Pokud nevíte, jaké typy písma máte k dispozici, nebo jaké budou k dispozici na počítačích, kde se vaše programy budou spouštět, můžete použít "symbolická jména":

Font.MONOSPACED, Font.SERIF, Font.SANS_SERIF

Jsou to konstanty třídy Font. Monospaced je neproporcionální písmo, serif je patkové písmo (má kolmé čárky na konci znaků) a sansserif je písmo bezpatkové (nemá kolmé čárky na konci znaků).

Při použití výše uvedených konstant se použije písmo vždy z dané rodiny písem (neproporcionální, patkové, bezpatkové), které se nachází na daném počítači. Pokud použijete písmo sansserif a program bude běžet na počítači s Windows, tak se pravděpodobně použije typ písma Arial. Pokud bude na počítači Linux, použije se 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);

    }
}

Pro písmo základní, tučné a italiku existují konstanty ve třídě Font. S těmi jsme se již seznámili. Tyto konstanty jsou typu int.

Font.BOLD + Font.ITALIC

Nám vytvoří hodnotu pro tučnou kurzívu.

V příští lekci, Programování jednoduchých Java GUI her - Obrázky, si vytvoříme instanci objektu Image, zjistíme výšku a šířku obrázku a umístíme ho do panelu.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 255x (3.64 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Programování jednoduchých Java GUI her - Kreslení
Všechny články v sekci
Tvorba her v Java Swing
Přeskočit článek
(nedoporučujeme)
Programování jednoduchých Java GUI her - Obrázky
Článek pro vás napsal vita
Avatar
Uživatelské hodnocení:
18 hlasů
vita
Aktivity