Czas przedstawić Tobie kolejny układ jaki występuje w bibliotece "Swing" - mianowicie, "FlowLayout" 🔥! Dowiesz się nie tylko tego, w jaki sposób ustawić ten układ, lecz także jak on wpływa na wygląd komponentów, gdy umieścimy je w ramce albo w panelu ⚡! Wchodź, zapraszam 😊!
"FLOWLAYOUT" W "SWING" KOLEJNYM RODZAJEM UKŁADU KOMPONENTÓW
W jednym z poprzednich artykułów przytoczyłem układ komponentu, który jest domyślnym dla obiektów "JFrame" - "BorderLayout" 💡. "FlowLayout" jest z kolei domyślnym dla paneli (obiektów "JPanel") 🔥!
OPIS UKŁADU "FLOWLAYOUT"
"FlowLayout" działa on w taki sposób, że "naciąga się" (poszerza swoje rozmiary) dostosowując swój rozmiar do umieszczonych w nim komponentów ℹ️. Warto nadmienić, że to "dostosowywanie się" działa inaczej w przypadku, gdy wspomniany układ funkcjonuje dla ramki ("JFrame") bądź dla komponentu osadzonego w jednym z regionów "BorderLayout". Jak się przekonasz na zamieszczonych przykładach, nic nie stoi na przeszkodzie, aby za pomocą metody "setLayout", ustawić go w "JFrame" i w "JPanel" 🙂.
PRZYKŁAD KODU ŹRÓDŁOWEGO
Przedstawię 2 różne kody źródłowe prezentujące działanie tego układu zarówno w ramce ("JFrame"), jak i w panelu ("JPanel") ✅. Dodamy sobie kilka tekstów (komponentów "JLabel") celem zbadania jak będą reagować w obu przypadkach 😉.
"FLOWLAYOUT" USTAWIONE W "JFRAME"
Zacznijmy od programu, w którym wprowadzamy "FlowLayout" do "JFrame" 🔲.
KLASA "MAIN"
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(MainJFrame::new);
}
}Standardowo zaczynamy od metody "main". Nic się nie zmienia w kontekście przykładów ukazywanych poprzednio.
KLASA "MAINJFRAME"
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class MainJFrame extends JFrame {
private final JLabel labelA = new JLabel("Pierwszy tekst w układzie \"FlowLayout\"");
private final JLabel labelB = new JLabel("Drugi tekst w układzie \"FlowLayout\"");
private final JLabel labelC = new JLabel("Trzeci nieco większy tekst w układzie \"FlowLayout\"");
private final JLabel labelD = new JLabel("Czwarty tekst w układzie \"FlowLayout\"");
public MainJFrame() {
configureFrame();
setLineBordersToLabels();
addToFrame();
}
private void configureFrame() {
setTitle("Układ FlowLayout w Swing (JFrame)");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setVisible(true);
setResizable(false);
setSize(512, 128);
setLocationRelativeTo(null);
}
private void setLineBordersToLabels() {
var lineBorder = new LineBorder(Color.BLACK);
labelA.setBorder(lineBorder);
labelB.setBorder(lineBorder);
labelC.setBorder(lineBorder);
labelD.setBorder(lineBorder);
}
private void addToFrame() {
add(labelA);
add(labelB);
add(labelC);
add(labelD);
}
}W klasie potomnej "JFrame" mamy całość kodu odpowiedzialnego za utworzenie okna z zawartością. Prywatne składowe finalne dotyczą naszych tekstów (finalne dlatego, gdyż nie będą tworzone nowe obiekty przez cały cykl działania). W metodzie "configureFrame", poza wcześniej wyjaśnianymi metodami, mamy jedną, na którą musimy zwrócić szczególną uwagę 🚨.
"setLayout" zamienia domyślny układ (w tym wypadku "BorderLayout") na dowolny inny 👍. Za parametr przyjmuje typ "LayoutManager", czyli tak naprawdę to "menedżer układu", jednak biorąc pod uwagę nazwy "BorderLayout" i "FlowLayout" w "Swing" od razu wnioskujemy, że chodzi o sam "układ" (ech, ta Java 😜...). Przeważnie wstawia się konstruktor istniejącego układu i to zwykle wystarcza ✔️.
Ważne, aby wspomnieć o tym, że w przypadku zmiany układu na "FlowLayout", zapominamy kompletnie o metodzie "getContentPane" ⚠️! Ona nie dotyczy układu "FlowLayout". Tu wywołujemy od razu metodę "add" i wprowadzamy tylko jeden parametr, jakim jest komponent, który chcemy tam wstawić 🙂.
Po uruchomieniu programu, ujrzysz 4 teksty ustawione blisko siebie, a każde z nich ma na sobie prostą czarną ramkę. Za to odpowiada "setBorder", do którego dodajemy obiekt typu "LineBorder" (który wymaga zaimportowania pakietu "javax .swing.border.LineBorder" 📪). Wstawiłem ją celowo, aby pokazać Ci jedną istotną cechę tego układu 😲.
Jeżeli skrócisz jeden z tekstów i ponownie uruchomisz program, to ułożenie tychże tekstów ulegnie zmianie 😳. W jednym rzędzie wstawi się tyle elementów, na ile pozwoli maksymalna szerokość ramki, na którą nałożono układ "FlowLayout". 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żeli kolejny element już nie mieści się w tym samym rzędzie, to zostaje on umieszczony poniżej ⏬. Czyli w odróżnieniu od "BorderLayout", ten układ dostosowuje szerokość komponentów względnie do zawartości w środku. Dotyczy to wszystkich komponentów.
![]() |
Wygląd tekstów w komponencie "JFrame" przy użyciu układu "FlowLayout" w "Swing".
Mogłeś(-aś) dostrzec słowo kluczowe "var" - ono pozwala uniknąć definiowania typu zmiennej samodzielnie, "przerzucając" ten obowiązek na kompilator. Polecam z tego korzystać jak najczęściej, a kiedy można tego użyć, to zapraszam do odrębnego artykułu 😊.
"FLOWLAYOUT" W "SWING" W OBIEKCIE "JPANEL"
Teraz przypadek, gdy "FlowLayout" w "Swing" dotyczy panelu osadzonego w ramce "JFrame", w której dalej obowiązuje "BorderLayout" 🚨! Jeżeli "FlowLayout" dotyczy obiektu "JPanel", to spodziewaj się innej reakcji, gdy suma szerokości wszystkich komponentów w jednym rzędzie zostanie przekroczona 😱. Aby zaobserwować to zjawisko, będziemy potrzebować dodatkowej klasy dla panelu w środku którego, znajdą się nasze komponenty tekstowe ✒️.
KLASA "MAIN"
Klasa uruchomieniowa jest taka sama. Weź ją sobie z góry, co będę się powtarzał 😄!
KLASA "MAINJFRAME"
import java.awt.*;
import javax.swing.*;
public class MainJFrame extends JFrame {
private final FlowLayoutJPanel flowLayoutJPanel = new FlowLayoutJPanel();
public MainJFrame() {
configureFrame();
getContentPane().add(BorderLayout.EAST, flowLayoutJPanel);
}
private void configureFrame() {
setTitle("Układ FlowLayout w Swing (JPanel)");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
setSize(512, 128);
setLocationRelativeTo(null);
}
}Tutaj już mamy różnice 😉. Kod jest dużo mniejszy z powodu przeniesienia komponentów tekstowych do panelu ("FlowLayoutJPanel") 😁. Zwróć uwagę, że teraz dodajemy do ramki sam panel i, co ważne, korzystamy ze stylu zapisu dostosowanego dla "BorderLayout" - "getContentPane" i wartość typu wyliczeniowego ("BorderLayout.EAST") 💡.
KLASA "FLOWLAYOUTJPANEL"
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class FlowLayoutJPanel extends JPanel {
private final JLabel labelA = new JLabel("Pierwszy tekst w układzie \"FlowLayout\"");
private final JLabel labelB = new JLabel("Drugi tekst w układzie \"FlowLayout\"");
private final JLabel labelC = new JLabel("Trzeci nieco większy tekst w układzie \"FlowLayout\"");
public FlowLayoutJPanel() {
super(new FlowLayout());
setLineBordersToLabels();
addToPanel();
}
private void setLineBordersToLabels() {
var lineBorder = new LineBorder(Color.BLACK);
labelA.setBorder(lineBorder);
labelB.setBorder(lineBorder);
labelC.setBorder(lineBorder);
}
private void addToPanel() {
add(labelA);
add(labelB);
add(labelC);
}
}Tym razem tworzymy sobie trzy teksty, zamiast czterech. Obiekty są tak samo umieszczone u góry klasy. W konstruktorze jest ciekawy zapis 🌟. "super" w języku Java to "zwrócenie się" do konstruktora klasy bazowej (więcej informacji w osobnym materiale). O wiele istotniejsze jest to, że dzięki takiej sztuczce unikamy wywoływania "setLayout"! Reszta metod odpowiada za nałożenie tego samego obramowania do tekstów i dodanie ich do panelu.
Gdy skompilujesz sobie program, ujrzysz całkiem inny efekt. W oknie będą widoczne...dwa teksty. Tak - dwa, nie trzy 🤯! Co więcej, w momencie przekroczenia szerokości panelu, nie dojdzie do umieszczenia tekstu poniżej 😳! W przypadku, gdy komponenty wstawione do panelu nie mieszczą się w jednej linii, dochodzi do wyjścia komponentów poza wymiary okna ⚠️!
Ciekawostka kryje się także przy "pustym" układzie 🔔. Jeżeli komponent z układem "FlowLayout" w "Swing" jest pusty (nie ma w sobie żadnych komponentów), wtedy zostaje sama "listwa" panelu. Komponent będzie widoczny, lecz zajmie bardzo niewielką powierzchnię na ekranie. Najlepiej ustawić sobie tło panelu używając metody "setBackground", zaraz po instrukcji "super" 👇:
setBackground(Color.BLACK);Wtedy zobaczysz o co mi chodzi ☑️.
![]() |
Wygląd tekstów w komponencie "JPanel" przy użyciu układu "FlowLayout" w "Swing".
To wszystko na temat nowo poznanego układu. Być może są jeszcze jakieś różnice których nie zawarłem, jednak nie ma sensu odkrywać wszystkich zakątków takiego zagadnienia, jak na artykuł wrzucony do sieci 🌐. To ma być przyjemne wprowadzenie 😁!
NASTĘPNY ARTYKUŁ: BoxLayout w Swing. Prostokątny układ komponentów

