Menempatkan komponen dengan koordinat piksel tetap (setBounds(10, 20, 80, 25)) terasa mudah — sampai jendela diubah ukurannya, teks memanjang setelah ganti bahasa, atau aplikasi dibuka di layar berbeda ketebalannya. Swing menolak pendekatan itu dan menyerahkan penataan kepada layout manager: objek yang menghitung posisi serta ukuran setiap komponen setiap kali ruang tersedia berubah. Kita hanya menyatakan aturan — “tombol-tombol ini sejajar ke kanan”, “tabel ini mengisi ruang tengah” — dan layout manager mengerjakan aritmetika. Chapter ini membedah lima layout manager inti beserta karakternya, lalu membuktikan bahwa perhitungan letak bisa diuji tanpa membuka jendela nyata.
Cara Kerja Layout Manager #
Setiap JPanel lahir bersama satu layout manager (FlowLayout sebagai bawaan) yang duduk di antara panel dan anak-anaknya. Saat sebuah container perlu ditata — karena pack() mengukurnya, setSize() dipanggil, atau pengguna mengubah ukuran jendela — terjadi dua putaran hitung. Pertama, layout manager menanyai setiap anak tentang preferred size, minimum size, dan maximum size milik anak itu, lalu menghitung preferred size container itu sendiri. Kedua, ketika ukuran container yang sebenarnya diketahui, layout manager membagikan ruang nyata itu kepada anak-anak lewat pemanggilan setBounds pada tiap anak. Karena kedua putaran berjalan di atas angka murni, kita bisa memicu tata letak secara manual dengan setSize(...) lalu doLayout() lalu membaca hasil koordinatnya — teknik yang dipakai seluruh contoh runnable chapter ini.
Lima Layout Manager Utama #
| Layout | Gaya penataan | Cocok untuk |
|---|---|---|
FlowLayout | Baris yang mengalir kiri ke kanan, membungkus ke baris baru | Deretan tombol |
BorderLayout | Lima wilayah: NORTH, SOUTH, EAST, WEST, CENTER | Kerangka aplikasi |
GridLayout | Grid sel sama besar, terisi kiri ke kanan lalu turun | Papan tombol, kalender |
GridBagLayout | Grid fleksibel: sel boleh melebar beberapa baris/kolom | Formulir kompleks |
BoxLayout | Satu sumbu — vertikal atau horizontal — dengan perekat | Bilah samping, panel bertumpuk |
Berikut wujud ketiganya dalam kode. FlowLayout adalah default JPanel, jadi panel pertama bahkan tidak menyebut layout apa pun:
import javax.swing.JButton;
import javax.swing.JPanel;
public class PanelFlow {
public static JPanel bangun() {
JPanel panel = new JPanel(); // FlowLayout bawaan
panel.add(new JButton("Tambah"));
panel.add(new JButton("Hapus"));
panel.add(new JButton("Keluar"));
return panel;
}
}BoxLayout mengatur satu sumbu dan menyediakan filler untuk mendorong komponen. Box.createHorizontalGlue() adalah ruang elastis yang menyerap sisa lebar — trik klasik menempel tombol ke kanan:
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PanelBox {
public static JPanel bangun() {
JPanel panel = new JPanel();
panel.setLayout(new javax.swing.BoxLayout(panel, javax.swing.BoxLayout.X_AXIS));
panel.add(new JButton("Bantuan"));
panel.add(Box.createHorizontalGlue()); // ruang elastis
panel.add(new JButton("Simpan"));
panel.add(Box.createHorizontalStrut(8)); // jarak tetap 8 piksel
panel.add(new JButton("Batal"));
return panel;
}
}GridBagLayout adalah yang paling kaya — dan paling banyak ditakuti pemula karena satu-satunya yang mengatur letak lewat objek kendali GridBagConstraints. Kendali tersebut menyatakan sel address (gridx, gridy), seberapa banyak sel diduduki (gridwidth), dan bagaimana komponen meregang (fill):
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PanelForm {
public static JPanel bangun() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints k = new GridBagConstraints();
k.insets = new Insets(4, 4, 4, 4);
k.anchor = GridBagConstraints.LINE_END;
k.gridx = 0; k.gridy = 0;
panel.add(new JLabel("Nama:"), k);
k.gridx = 1; k.gridy = 0;
k.fill = GridBagConstraints.HORIZONTAL;
k.weightx = 1.0; // kolom input menyerap sisa lebar
panel.add(new JTextField("Budi", 16), k);
k.gridx = 0; k.gridy = 1; k.fill = GridBagConstraints.NONE;
panel.add(new JLabel("Kelas:"), k);
k.gridx = 1; k.gridy = 1; k.fill = GridBagConstraints.HORIZONTAL;
panel.add(new JTextField("11-A", 16), k);
return panel;
}
}Nilai weightx = 1.0 pada kolom input adalah kunci: saat jendela melebar, seluruh lebar tambahan mengalir ke kolom itu, sementara kolom label tetap sempit.
Simulasi GridLayout Tanpa Layar #
GridLayout paling mudah dibedah karena aritmetikanya terbuka: lebar sel = (lebar panel − total celah horizontal) ÷ jumlah kolom. Program berikut membangun grid 2×3 bercelah 5 piksel, memberi panel ukuran tetap 160×90, lalu membaca koordinat hasil tata:
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
/** Mensimulasikan GridLayout: sel sama besar, terisi kiri ke kanan. */
public class TataGrid {
public static void main(String[] args) {
JPanel panel = new JPanel(new GridLayout(2, 3, 5, 5));
String[] nama = { "A", "B", "C", "D", "E", "F" };
for (String n : nama) {
panel.add(new JButton(n));
}
panel.setSize(160, 90); // ukuran panel tetap, bukan hasil ukur font
panel.doLayout(); // paksa layout manager bekerja sekarang
for (int i = 0; i < panel.getComponentCount(); i++) {
var c = panel.getComponent(i);
System.out.printf("%s -> x=%d y=%d lebar=%d tinggi=%d%n",
nama[i], c.getX(), c.getY(), c.getWidth(), c.getHeight());
}
}
}Output yang Dihasilkan:
A -> x=0 y=0 lebar=50 tinggi=42
B -> x=55 y=0 lebar=50 tinggi=42
C -> x=110 y=0 lebar=50 tinggi=42
D -> x=0 y=47 lebar=50 tinggi=42
E -> x=55 y=47 lebar=50 tinggi=42
F -> x=110 y=47 lebar=50 tinggi=42Mari kita cocokkan angka dengan rumusnya:
- Baris 7 (
new GridLayout(2, 3, 5, 5)): dua baris, tiga kolom, celah horizontal 5 piksel, celah vertikal 5 piksel. Enam tombol menempati keenam sel secara berurutan. - Baris 13-14 (
setSize+doLayout):setSizemenetapkan ukuran container;doLayoutmemaksa layout manager membagikan area itu kepada anak-anak sekarang juga, tanpa menunggu jendela nyata. - Lebar sel = (160 − 2×5) ÷ 3 = 50: terlihat pada keluaran — setiap tombol berlebar tepat 50. Posisi
xtombolBadalah 50+5 = 55, danCdi 110: pola +55 per kolom. - Tinggi sel = (90 − 5) ÷ 2 = 42,5 → 42: pembagian bulat menghasilkan 42; baris kedua mulai di y = 42+5 = 47, persis seperti keluaran tombol
D.
Wilayah BorderLayout #
BorderLayout memakai logikanya sendiri: NORTH dan SOUTH diukur sesuai tinggi pilihan lalu merentang selebar panel; EAST dan WEST diukur sesuai lebar pilihan; CENTER menyerap seluruh sisa ruang. Program berikut memverifikasi pembagian tersebut pada panel 200×120:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JPanel;
/** Mensimulasikan BorderLayout: lima wilayah dengan prioritas ukuran berbeda. */
public class TataBorder {
static JButton tombol(String teks, int tinggiPilihan) {
JButton b = new JButton(teks);
b.setPreferredSize(new Dimension(60, tinggiPilihan));
return b;
}
public static void main(String[] args) {
JPanel panel = new JPanel(new BorderLayout(4, 4));
panel.add(tombol("Utara", 30), BorderLayout.NORTH);
panel.add(tombol("Barat", 0), BorderLayout.WEST);
panel.add(tombol("Tengah", 0), BorderLayout.CENTER);
panel.add(tombol("Timur", 0), BorderLayout.EAST);
panel.add(tombol("Selatan", 30), BorderLayout.SOUTH);
panel.setSize(200, 120);
panel.doLayout();
String[] wilayah = { "Utara", "Barat", "Tengah", "Timur", "Selatan" };
for (int i = 0; i < wilayah.length; i++) {
var c = panel.getComponent(i);
System.out.printf("%-7s -> x=%d y=%d lebar=%d tinggi=%d%n",
wilayah[i], c.getX(), c.getY(), c.getWidth(), c.getHeight());
}
}
}Output yang Dihasilkan:
Utara -> x=0 y=0 lebar=200 tinggi=30
Barat -> x=0 y=34 lebar=60 tinggi=52
Tengah -> x=64 y=34 lebar=72 tinggi=52
Timur -> x=140 y=34 lebar=60 tinggi=52
Selatan -> x=0 y=90 lebar=200 tinggi=30Keluaran tersebut membuktikan tiga aturan kerja BorderLayout. Pertama, Utara dan Selatan memang tinggi tepat 30 (ukuran pilihan yang kita setel) namun selebar 200 — wilayah horizontal selalu merentang penuh. Kedua, Barat dan Timur berlebar tepat 60, sedangkan tingginya 52 = 120 − 30 − 30 − 2×4 (celah vertikal 4 piksel dua kali). Ketiga, Tengah menyerap sisa: lebar 72 = 200 − 60 − 60 − 8, posisi x = 64. Jika tidak ada komponen di satu wilayah, wilayah itu bubar dan CENTER makin luas — sifat yang membuat BorderLayout pas sebagai kerangka luar aplikasi.
Komponen sudah bisa ditaruh rapi; kini antarmuka kita masih bisu karena belum ada kode yang bergerak saat tombol ditekan. Chapter berikutnya membuka dunia event-driven programming: listener, sumber kejadian, dan cara Swing mengantarkan klik pengguna ke method kita.
Referensi #
- Oracle: Panduan A Visual Guide to Layout Managers
- Oracle: Kelas BorderLayout (JDK 25)
- Oracle: Kelas GridBagLayout (JDK 25)
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
TataBorder.java
Unduh berkasimport java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JPanel;
/** Mensimulasikan BorderLayout: lima wilayah dengan prioritas ukuran berbeda. */
public class TataBorder {
static JButton tombol(String teks, int tinggiPilihan) {
JButton b = new JButton(teks);
b.setPreferredSize(new Dimension(60, tinggiPilihan));
return b;
}
public static void main(String[] args) {
JPanel panel = new JPanel(new BorderLayout(4, 4));
panel.add(tombol("Utara", 30), BorderLayout.NORTH);
panel.add(tombol("Barat", 0), BorderLayout.WEST);
panel.add(tombol("Tengah", 0), BorderLayout.CENTER);
panel.add(tombol("Timur", 0), BorderLayout.EAST);
panel.add(tombol("Selatan", 30), BorderLayout.SOUTH);
panel.setSize(200, 120);
panel.doLayout();
String[] wilayah = { "Utara", "Barat", "Tengah", "Timur", "Selatan" };
for (int i = 0; i < wilayah.length; i++) {
var c = panel.getComponent(i);
System.out.printf("%-7s -> x=%d y=%d lebar=%d tinggi=%d%n",
wilayah[i], c.getX(), c.getY(), c.getWidth(), c.getHeight());
}
}
}
TataGrid.java
Unduh berkasimport java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
/** Mensimulasikan GridLayout: sel sama besar, terisi kiri ke kanan. */
public class TataGrid {
public static void main(String[] args) {
JPanel panel = new JPanel(new GridLayout(2, 3, 5, 5));
String[] nama = { "A", "B", "C", "D", "E", "F" };
for (String n : nama) {
panel.add(new JButton(n));
}
panel.setSize(160, 90); // ukuran panel tetap, bukan hasil ukur font
panel.doLayout(); // paksa layout manager bekerja sekarang
for (int i = 0; i < panel.getComponentCount(); i++) {
var c = panel.getComponent(i);
System.out.printf("%s -> x=%d y=%d lebar=%d tinggi=%d%n",
nama[i], c.getX(), c.getY(), c.getWidth(), c.getHeight());
}
}
}