Druga część o metodzie "paintComponent". Na zakończenie dzisiejszej porcji wiedzy, postanowiłem powrócić do tego samego tematu omawianego wcześniej jednak przybliżę Wam teraz możliwości biblioteki "Swing" i klasy "JPanel" prezentując więcej funkcji rysujących. Konstrukcję podstawową już znacie, zatem nie muszę już dzielić tych tematów na dwie części. Pokażę Wam jak przy pomocy rzutowania instancji typu "Graphics" na "Graphics2D", możecie sobie poszerzyć pole manewrów!

"GRAPHICS2D" POSZERZA MOŻLIWOŚCI

Pamiętacie jak wygląda metoda "paintComponent" w poprzedniej części? Pomogę Wam:

@Override
protected void paintComponent(Graphics g)
{
	super.paintComponent(g);
}

Posiada parametr typu "Graphics". Jest to kolejna klasa za pośrednictwem której możemy rysować po panelu przy użyciu wszystkich funkcji. Cóż...nie wszystkich. Większości. Wbudowany typ zapewnia większość metod przeznaczonych do rysowania figur, ale nie wszystkie. Możemy to szybko zmienić wykonując w środku jedną prostą instrukcję:

@Override
protected void paintComponent(Graphics g)
{
	super.paintComponent(g);
	
	Graphics2D g2D = (Graphics2D)g;
}

"Dodatek" wpisany powyżej ("Graphics2D") zwie się "rzutowaniem typu". Jest to konwersja obecnego typu danego parametru na typ zmiennej do której próbujemy "upchnąć" wartość celem zachowania kompatybilności. Uprzedzę od razu, TAK. Podczas deserializacji danych robiliśmy identyczną operację. Klasa "Graphics" jest klasą abstrakcyjną, zatem nie można na jej podstawie tworzyć instancji. To system decyduje o jej istnieniu. Rzutując na klasę "Graphics2D" dziedziczącą od poprzedniczki, dysponujemy większą ilością funkcji manipulujących obrazem.

PRZYKŁAD BARDZO GRAFICZNY

Oto kod źródłowy prezentujący szereg funkcji udostępnianych zarówno przez "Graphics", jak i wersję "rzutowaną". Obok każdej metody zostawiłem komentarz co to dokładnie robi i jakich oczekuje parametrów:

  • KLASA "Main"
public class Main
{
	public static void main(String[] args)
	{
		new SwingWindow();
	}
}
  • KLASA "SwingWindow"
import java.awt.*;
import javax.swing.*;

public class SwingWindow extends JFrame
{
	private SwingPanel panel;

	public SwingWindow()
	{
		createInstances();
		addToFrame();
		configure();
	}

	private void createInstances()
	{
		panel = new SwingPanel();
	}

	private void addToFrame()
	{
		Container pane = getContentPane();

		pane.add(BorderLayout.CENTER, panel);
	}

	private void configure()
	{
		setTitle("Rysowanie po panelu JPanel");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		setResizable(false);
		setSize(800, 600);
		setLocationRelativeTo(null);
	}
}
  • KLASA "SwingPanel"
import java.awt.*;
import javax.swing.*;
import java.awt.geom.Line2D;

public class SwingPanel extends JPanel
{
	@Override
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		Graphics2D g2D = (Graphics2D)g;

		g2D.setColor(Color.GREEN);
		g2D.fillRoundRect(32, 192, 256, 64, 16, 16);			// wypełniony prostokąt z zaokrągleniami (x, y, szerokość, wysokość, szerokość zaokrąglania, wysokość zaokrąglania)
		g2D.setColor(Color.BLUE);
		g2D.fillPolygon(new int[]{640, 287, 305}, new int[] {117, 159, 303}, 3);			// wypełniony wielokąt (tablica liczb całkowitych jako współrzędne X każdego punktu, tablica liczb całkowitych jako współrzędne Y każdego punktu, liczba punktów)
		g2D.setColor(Color.MAGENTA);
		g2D.fillOval(340, 340, 32, 32);			// wypełniona elipsa (x, y, szerokość, wysokość)

		g2D.setColor(Color.BLACK);
		g2D.drawString("Tekst rysowany przez Graphics2D", 16, 16);			// rysowanie podanego łańcucha znaków (tekst, x, y)
		g2D.setColor(Color.ORANGE);
		g2D.fill3DRect(32, 32, 128, 128, true);			// rysowanie wypełnionego prostokąta z krawędziami symulującymi efekt 3D (x, y, szerokość, wysokość, wrażenie obniżenia czy podwyższenia?)
		g2D.setColor(Color.RED);
		g2D.draw(new Line2D.Double(192, 64, 192 + 256, 64));			// rysowanie niestandardowe (konstruktor dla obiektu)
	}
}

Metodę "setColor" już znacie. "fillRoundRect" rysuje wypełniony prostokąt z charakterystycznymi zaokrąglonymi "rogami", czyli krawędziami. "fillPolygon" pozwala utworzyć dowolny wielokąt przy podaniu tylu wierzchołków ile chcecie. Parametry służą do "przetrzymywania" osobno w pojedynczych tablicach współrzędnych X i Y oraz liczbę wierzchołków. "fillOval" z kolei umożliwia malowanie elipsy lub koła (pod warunkiem, że szerokość i wysokość jest taka sama).

A teraz metody dostępne tylko dla "Graphics2D". Na przykład funkcja "drawString", która rysuje zwykły tekst, lecz na panelu. "fill3DRect" wbrew sugerowanej nazwie nie rysuje niczego trójwymiarowego, tylko wypełniony prostokąt posiadający krawędzie mające dawać iluzję trójwymiarowości. Tylko tyle. A za ostatni przykład już bardziej skomplikowany dorzuciłem funkcję "draw", która umożliwia rysowanie dowolnego niestandardowego obiektu.

Za parametr dodałem konstruktor tworzący zwykłą linię rysującą odcinek pomiędzy dwoma punktami, natomiast pozwalający również na wstawienie współrzędnych zmiennoprzecinkowych! Klasa "Line2D" nie dopuszcza żadnych ułamkowych wartości. Dlatego też jeśli Wasz odcinek koniecznie musi mieć typy "double", stosujcie tylko to.


Tych funkcji jest o wiele więcej, natomiast zaprezentowałem kilka bardziej złożonych przykładów mogących Was zaciekawić możliwościami "Graphics2D" oraz samą klasą "Graphics".

PODOBNE ARTYKUŁY