Czy jesteś gotowy(-a) na poznanie kolejnego układu jaki znajduje się w bibliotece "Swing" 😄? Jeżeli pragniesz koniecznie mieć po jednym komponencie w danym rzędzie bez względu na to, czy wyczerpuje całą wolną szerokość, czy nie, to poznaj układ stworzony do tego celu 🎯. "BoxLayout" w "Swing" i wszystko staje się jasne 😁!

"BOXLAYOUT" W "SWING" UŁOŻY CI KOMPONENTY "GRUPOWO"

Wbrew nazwie, układ ten nie robi niczego z komponentami w sposób "skrzynkowy" 📦 - on sprawia, że każdy komponent ma cały rząd/kolumnę tylko dla siebie (w zależności w którym kierunku idziemy) 🧡. W przeciwieństwie do "FlowLayout" gdzie dodawane komponenty układają się w jednym rzędzie, tutaj w momencie dodawania każdego kolejnego, "przechodzimy" do kolejnego rzędu lub kolumny ⏩. Taka jest różnica 👍!

PRZYKŁAD KODU ŹRÓDŁOWEGO

Przejdziemy teraz do przykładowej aplikacji. Dodamy sobie ramkę ("JPanel"), wstawimy wewnątrz niej panel ("JPanel") z ustawionym układem "BoxLayout", a do niego samego, wprowadzimy 3 przyciski do klikania 💥. "BoxLayout" w "Swing" może dotyczyć zarówno obiektu "JFrame", jak i "JPanel" - nie ma znaczenia 😉.

KLASA "MAIN"
public class Main {
	public static void main(String[] args) {
		SwingUtilities.invokeLater(MainJFrame::new);
	}
}

Ta sama klasa "Main" - bz. 🙃.

KLASA "MAINJFRAME"
import java.awt.*;
import javax.swing.*;

public class MainJFrame extends JFrame {
	private final BoxLayoutJPanel boxLayoutJPanel = new BoxLayoutJPanel();

	public MainJFrame() {
		configureFrame();
		getContentPane().add(BorderLayout.NORTH, boxLayoutJPanel);
	}

	private void configureFrame() {
		setTitle("Układ BoxLayout w Swing");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		setResizable(false);
		setSize(512, 128);
		setLocationRelativeTo(null);
	}
}

Tak jak poprzednio, wstawiamy sobie u góry składową dla obiektu panelu i od razu go tworzymy 🧱. Dzięki temu, możemy uczynić tę składową finalną, ponieważ przez cały cykl funkcjonowania aplikacji, nie będziemy nadpisywali referencji (nie będzie nigdzie użycia "new" po raz kolejny) ✅.

Mamy tę samą metodę do konfigurowania samej ramki, a zaraz po tym jest dodawanie naszego panelu do północnego regionu układu "BorderLayout", który akurat w "JFrame" jest układem domyślnym (i przez to nie musimy go ustawiać 😄).

KLASA "BOXLAYOUTJPANEL"
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class BoxLayoutJPanel extends JPanel {
	private final JButton buttonA = new JButton("Przycisk pierwszy");
	private final JButton buttonB = new JButton("Przycisk drugi");
	private final JButton buttonC = new JButton("Przycisk trzeci");

	public BoxLayoutJPanel() {
		setBorder(new LineBorder(Color.BLACK));
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		addToPanel();
	}

	private void addToPanel() {
		add(buttonA);
		add(buttonB);
		add(buttonC);
	}
}

Postępujemy podobnie. Tworzenie instancji u góry i konfiguracja w konstruktorze. A skoro o nim mowa, to zobacz, że siedzi w nim instrukcja "setLayout", a w niej ustawienie układu na "BoxLayout". Konstruktor "BoxLayout" potrzebuje domyślnie DWÓCH parametrów 👇:

  1. komponent, którego ten układ ma dotyczyć (wpisanie "this" oznacza nałożenie układu na "ten" komponent, czyli na nasz panel),
  2. wartość typu wyliczeniowego definiującego oś, czyli jak komponenty mają się układać (rzędami czy kolumnami).

Nie mogliśmy użyć wywołania "super" na samym początku konstruktora "BoxLayoutJPanel" i do niego wstawić od razu ustawienia układu "BoxLayout" z powodu pierwszego parametru 1️⃣. Ustawienie układu oczekującego referencji do komponentu nie może być wcześniej od samego utworzenia komponentu - stąd też próba wstawienia konstruktora "BoxLayout" jako parametru do "super", spowoduje tylko błąd kompilacji i nici z eksperymentu 😝.

"setBorder" doda obramowanie wokół obszaru dla komponentów 🔲. To ma na celu pokazać jak on się układa po dodaniu komponentów 👍. A "addToPanel" dodaje przyciski do panelu ✔️.

Uruchamiając program, zobaczysz 3 przyciski ustawione w jednej kolumnie z zakotwiczeniem do lewej strony ⚓. To jest ułożenie komponentów w osi Y. Co ciekawe, jeżeli zamienimy ustawianie na oś X:

setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

to otrzymamy to samo zachowanie, jakie miało miejsce przy układzie "FlowLayout" i od razu uprzedzam - też będzie wyjście poza ekran, jeśli suma szerokości komponentów okaże się większa od szerokości ramki "JPanel" 🙂.

Tak jak napisałem wcześniej, "BoxLayout" nie obchodzi czy dany komponent obejmuje całą szerokość, czy nie. Jeden rząd/kolumna, jeden komponent. Taka jest reguła. A efekt...różny zależnie od wybranej osi 🙃. Sam zobacz 👀!

Wygląd przycisków w panelu "JPanel" z układem "BoxLayout" w "Swing" w osi X Wygląd przycisków w panelu "JPanel" z układem "BoxLayout" w "Swing" w osi Y

"BoxLayout" w "Swing" w osi X, umieszcza wszystkie komponenty w jednej kolumnie ryzykując "wyjściem" poza ekran, a w osi Y, po wstawieniu komponentu, przechodzi do kolejnego rzędu.


Artykuł dobiegł końca 🙂. Poeksperymentuj sam(-a), wtedy wychodzi z tego najlepsza nauka 💡. Bez praktyki, nie nauczysz się programowania - tak to już jest 😊.

NASTĘPNY ARTYKUŁ: GridLayout w Swing. Siatkowy układ komponentów

PODOBNE ARTYKUŁY