Jason. Cała informatyka w jednym miejscu!

Gorączkowa praca nad programem zakończyła się sukcesem, a zatem pozostało mi jedynie kontynuowanie redagowania artykułów. Czas wrócić do języka którym się najczęściej teraz posługuję i iść z kolejnymi tematami. Przed Państwem, język Java i "FlowLayout" w "Swing", kolejny menedżer układu występujący w bibliotece.

"FLOWLAYOUT" W "SWING" KOLEJNYM MENEDŻEREM UKŁADU

Wspomniany niedawno menedżer układu jest kolejnym rodzajem stojącym zaraz obok dużo wcześniej opisanego "BorderLayout". Jest domyślnym menedżerem układu dla komponentów "JPanel". Działa on w taki sposób, że "naciąga się" dostosowując się do potrzeb umieszczonych w nim komponentów. Co ciekawe, to "dostosowywanie się" daje zupełnie inne rezultaty w przypadku, gdy jest on ustawiony dla ramki, bądź dla komponentu osadzonego w "BorderLayout" (nic nie stoi na przeszkodzie, aby za pomocą metody "setLayout" ustawić go w "JFrame" lub w "JPanel"). Wobec tego, przedstawię dwa różne kody źródłowe prezentujące zastosowanie tego menedżera w ramce oraz w panelu. Wykorzystamy przykład dodawania kilku tekstów "JLabel" celem zbadania jak będą reagować w obu przypadkach.

Zacznijmy od części wspólnej obu przypadków, czyli od metody "main":

KLASA "MAIN"

public class Main {
	public static void main(String[] args) {
		new SwingFrame();
	}
}
"FLOWLAYOUT" W "SWING" W OBIEKCIE "JFRAME"

Wspomniany menedżer układu można bez problemu osadzić w obiekcie typu "JFrame", który posiada domyślnie "BorderLayout". W poniższym wpisie wywoływana jest metoda "setLayout" za pomocą której można ustawić menedżer układu na dowolny inny. Za parametr przyjmuje ona obiekt menedżera układu. Przeważnie wstawia się konstruktor, chyba że potrzebna jest uprzednia konfiguracja takiego układu.

KLASA "SWINGFRAME"

import java.awt.*;
import javax.swing.*;

public class SwingFrame extends JFrame {
	private JLabel labelA, labelB;

	public SwingFrame() {
		super();
		setLayout(new FlowLayout());
		createInstances();
		setVisible(true);
		setResizable(false);
		setTitle("Flow Layout");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(320, 240);
		setLocationRelativeTo(null);
		addBordersToLabels();
		addToFrame();
	}

	private void createInstances() {
		labelA = new JLabel("Pierwszy tekst w FlowLayout");
		labelB = new JLabel("Drugi tekst w FlowLayout");
	}
	
	private void addBordersToLabels() {
		LineBorder lb = new LineBorder(Color.BLACK);
		
		labelA.setBorder(lb);
		labelB.setBorder(lb);
	}
	
	private void addToFrame() {
		add(labelA);
		add(labelB);
	}
}

Warto wspomnieć, że w przypadku zmiany układu z "BorderLayout" na ten, zapominamy kompletnie o metodzie "getContentPane"! Ona nie dotyczy menedżera "FlowLayout" w "Swing", tu wywołujemy od razu metodę "add" i wprowadzamy tylko jeden parametr. Po uruchomieniu programu składającego się z DWÓCH klas, ujrzycie dwa teksty jeden pod drugim oznaczone prostą ramką liniową. Celowo ją wstawiłem, aby pokazać Wam jedną rzecz.

Jeżeli skrócicie jeden z tekstów i ponownie uruchomicie program, to wówczas dwa teksty będą umieszczone w jednym rzędzie. Wniosek z tego nasuwa się taki, iż "FlowLayout" stara się domyślnie umieścić wszystko w jednym rzędzie zachowując tylko tyle miejsca ile trzeba, a jeśli kolejny element już nie mieści się w tym samym rzędzie, to zostaje on umieszczony poniżej. Ponadto, w przeciwieństwie do "BorderLayout", ten menedżer dostosowuje szerokość komponentów względnie do zawartości w środku. To znaczy, że przycisk o tekście "Kliknij mnie" będzie znacznie dłuższy od przycisku opisanego tekstem "OK". Dotyczy to wszystkich komponentów.

"FLOWLAYOUT" W "SWING" W OBIEKCIE "JPANEL"

Jeżeli omawiany menedżer układu obowiązuje w obiekcie "JPanel", to spodziewajcie się innej reakcji na przypadek, gdy suma szerokości wszystkich komponentów w jednym rzędzie zostanie przekroczona. Aby zaobserwować to zjawisko, będziemy potrzebować dodatkowej klasy dla panelu, który będzie centralnym punktem eksperymentu. Dorzucam jeszcze raz klasę "SwingFrame", która różni się od poprzedniej:

KLASA "SWINGFRAME"

import java.awt.*;
import javax.swing.*;

public class SwingFrame extends JFrame {
	private FlowLayoutPanel flowLayoutPanel;

	public SwingFrame() {
		super();
		setLayout(new FlowLayout());
		createInstances();
		setVisible(true);
		setResizable(false);
		setTitle("Flow Layout");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(320, 240);
		setLocationRelativeTo(null);
		addToFrame();
	}

	private void createInstances() {
		flowLayoutPanel = new FlowLayoutPanel();
	}

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

		pane.add(BorderLayout.EAST, flowLayoutPanel);
	}
}

KLASA "FLOWLAYOUTPANEL"

import java.awt.*;
import javax.swing.*;

public class FlowLayoutPanel extends JPanel {
	private JLabel labelA, labelB;

	public FlowLayoutPanel() {
		super(new FlowLayout());
		setBackground(Color.BLACK);
		createInstances();
		changeLabelsColor();
		addToPanel();
	}

	private void createInstances() {
		labelA = new JLabel("Pierwszy tekst w FlowLayout");
		labelB = new JLabel("Drugi tekst w FlowLayout");
	}

	private void changeLabelsColor() {
		labelA.setForeground(Color.RED);
		labelB.setForeground(Color.ORANGE);
	}

	private void addToPanel() {
		add(labelA);
		add(labelB);
	}
}

Gdy skompilujecie sobie program, ujrzycie czarny panel, a w nim, dwa teksty o różnych kolorach. O wiele bardziej interesującym zjawiskiem jest to, iż w momencie przekroczenia szerokości panelu, nie dochodzi do umieszczenia tekstu poniżej! Struktura pozostaje nietknięta i dochodzi do wyjścia komponentów poza ekran programu. Być może to dotyczy tylko sytuacji dodania takiego panelu do miejsca menedżera "BorderLayout", nie wiem jak w innych przypadkach. Ponoć można to zmienić, ale "droga" do tego nie jest prosta i trzeba korzystać z wielu "furtek" Javy. Jeżeli "FlowLayout" w "Swing" jest pusty (zakomentowane lub usunięte polecenia "add"), wtedy zostaje sama "listwa" panelu. "FlowLayout" jest widoczny, ale zajmuje bardzo niewielką powierzchnię na ekranie. To również jest istotny wniosek.

"FlowLayout" w Swing

"FlowLayout" w "Swing", domyślny menedżer układu w "JPanel", powoduje zignorowanie umieszczenia niżej wszystkich tych komponentów, które nie mieszczą się w jednej linijce.


To wszystko na temat nowo poznanego menedżera układu. Pewnie są jeszcze jakieś różnice których nie zawarłem, ale nie chciałem poszerzać już i tak dużego artykułu. Niech Wam dobrze służy! Może interesuje Was dalszy ciąg tego wątku?

PODOBNE ARTYKUŁY