Aplikasi desktop — program berjendela yang terpasang di komputer pengguna — adalah ranah pertama Java sebelum web dan backend menjadi pucuk utamanya. Java menyediakan dua toolkit antarmuka grafis resmi: Swing yang telah menyertai JDK sejak 1998, dan JavaFX yang dirancang sebagai penerus modern namun sejak JDK 11 dipisahkan menjadi proyek mandiri OpenJFX. Keduanya membangun antarmuka dari konsep yang sama: pohon komponen di dalam jendela, pengaturan tata letak oleh layout manager, dan aliran kejadian (event) dari pengguna ke kode kita. Chapter ini memetakan sejarah kedua toolkit, posisinya hari ini, dan konsep pohon kontainer yang menjadi fondasi seluruh Section ini.
Garis Waktu Toolkit UI Java #
Perjalanan toolkit UI Java berlangsung dalam tiga gelombang besar. Tabel berikut merangkum tonggak-tonggaknya:
| Tahun | Toolkit | Peristiwa penting |
|---|---|---|
| 1996 | AWT | Toolkit pertama; komponennya memakai widget asli sistem operasi (heavyweight) |
| 1998 | Swing | Bagian JDK 1.2; komponen digambar sendiri oleh Java (lightweight), tampilan konsisten lintas platform |
| 2008 | JavaFX 1.0 | Rilis awal oleh Sun sebagai platform UI baru dengan bahasa skrip sendiri |
| 2014 | JavaFX 8 | Menyatu penuh ke JDK 8, skrip FXML + controller Java |
| 2018 | JDK 11 | JavaFX dikeluarkan dari JDK; sejak itu didistribusikan terpisah lewat OpenJFX |
| Kini | Swing + JavaFX | Keduanya aktif dirawat; Swing tetap terpasang di JDK, JavaFX diambil sebagai dependensi terpisah |
Perpisahan JavaFX dari JDK bukan tanda penghentian. Swing tetap terawat di dalam modul java.desktop pada setiap rilis JDK — termasuk JDK 25 yang kita pakai — sedangkan JavaFX berkembang sebagai modul terpisah di proyek OpenJFX dengan rilisnya sendiri. Konsekuensinya praktis: kode Swing dapat langsung dikompilasi dengan javac tanpa dependensi tambahan, sedangkan aplikasi JavaFX membutuhkan pustaka OpenJFX dari Maven Central atau SDK terpisah.
Dua Toolkit, Satu Model Berpikir #
Memilih antara Swing dan JavaFX sebaiknya didasarkan pada kebutuhan proyek, bukan selera. Tabel berikut membandingkan keduanya:
| Aspek | Swing | JavaFX |
|---|---|---|
| Status distribusi | Terpasang di JDK (java.desktop) | Dependensi terpisah (OpenJFX) |
| Model komponen | JFrame, JPanel, JButton | Stage, Scene, node tree |
| Penataan letak | Layout manager (BorderLayout, GridBagLayout) | Layout panes (BorderPane, GridPane) |
| Data reaktif | PropertyChangeListener + Swing worker | Property + Bindings bawaan |
| Deklaratif UI | Tidak ada format standar | FXML (+ alat visual Scene Builder) |
| Grafis modern | Terbatas (Java 2D) | Akselerasi hardware, efek, CSS |
Aplikasi internal perusahaan dan IDE berumur panjang umumnya tetap berbasis Swing — IntelliJ IDEA, NetBeans, dan JetBrains Toolbox adalah contoh nyata produk besar yang berjalan di atas Swing. JavaFX dipilih ketika tim butuh tampilan modern, animasi, atau alat desain visual seperti Scene Builder.
Pohon Kontainer sebagai Fondasi #
Baik Swing maupun JavaFX menyusun antarmuka sebagai pohon kontainer: satu komponen akar menampung komponen anak, yang pada gilirannya menampung anak lain. Pada Swing, JFrame adalah jendela akar; di dalamnya bertengger JPanel pembawa label dan tombol. Kode berikut membangun pohon tersebut dan mencetak strukturnya — tanpa membuka jendela nyata, sehingga bisa dijalankan di lingkungan tanpa layar:
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** Menggambar pohon kontainer Swing tanpa membuka jendela nyata. */
public class HierarkiDemo {
public static void main(String[] args) {
JPanel panelTengah = new JPanel();
panelTengah.add(new JLabel("Nama:"));
panelTengah.add(new JButton("Simpan"));
JPanel panelInduk = new JPanel();
panelInduk.add(new JLabel("Aplikasi Data Siswa"));
panelInduk.add(panelTengah);
cetak(panelInduk, 0);
}
/** Cetak komponen dan seluruh anak-anaknya dengan indentasi bertingkat. */
private static void cetak(java.awt.Container induk, int kedalaman) {
System.out.println(" ".repeat(kedalaman) + induk.getClass().getSimpleName());
for (var anak : induk.getComponents()) {
if (anak instanceof java.awt.Container kontainerAnak) {
cetak(kontainerAnak, kedalaman + 1);
} else {
System.out.println(" ".repeat(kedalaman + 1) + anak.getClass().getSimpleName());
}
}
}
}Output yang Dihasilkan:
JPanel
JLabel
JPanel
JLabel
JButtonMari kita telaah bagian-bagian pentingnya:
- Baris 9-11 (
panelTengah.add(...)): methodaddmilikJPanelmendaftarkan komponen anak ke dalam daftar anak milik panel. Urutan pemanggilanaddmenentukan urutan anak dalam pohon. - Baris 13-16 (
panelInduk.add(...)): sebuahJPaneljuga bisa menjadi anak dari panel lain — panelpanelTengahdimasukkan kepanelInduk, membentuk percabangan dua tingkat. - Baris 21 (
getComponents()): method padajava.awt.Containermengembalikan seluruh komponen anak dalam urutan penambahan. Inilah pintu untuk menelusuri pohon secara program. - Baris 22-24 (
instanceof ... kontainerAnak): pattern matching mengecek apakah anak bertipe kontainer; bila ya, fungsicetakmemanggil dirinya sendiri (rekursif) agar cabang ditelusuri sampai ujung.
Perhatikan bahwa program di atas tidak pernah membuat JFrame. Konstruksi JPanel, JLabel, dan JButton tidak membutuhkan layar — hanya pembukaan jendela (new JFrame()) yang membutuhkan tampilan grafis nyata. Untuk itulah seluruh contoh runnable pada Section ini menguji logika dan struktur komponen, sementara kode jendela lengkap ditampilkan sebagai contoh bacaan seperti berikut:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public class HaloDuniaSwing {
public static void main(String[] args) {
JFrame jendela = new JFrame("Halo Dunia");
jendela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jendela.setSize(320, 160);
JLabel label = new JLabel("Halo, Budi!", SwingConstants.CENTER);
jendela.add(label);
JButton tombol = new JButton("Tutup");
tombol.addActionListener(e -> jendela.dispose());
jendela.add(tombol, java.awt.BorderLayout.SOUTH);
jendela.setVisible(true); // membuka jendela nyata
}
}Struktur berkas HaloDuniaSwing.java mencerminkan pola yang akan kita pakai berulang: buat jendela, susun komponen ke dalam pohon, pasang listener pada tombol, lalu tampilkan. Setiap unsur tersebut dibedah tuntas pada chapter-chapter selanjutnya.
Desktop Java Hari Ini #
Ranah desktop modern didominasi teknologi web (Electron, Tauri) dan toolkit bawaan platform (SwiftUI, WinUI), namun Java tetap punya ceruk yang sehat. Aplikasi internal perusahaan — alat kasir, workstation laboratorium, klien trading — kerap memilih Java karena timnya sudah menguasai bahasanya dan kode bertahan puluhan tahun berkat kompatibilitas mundur JDK. Basis kode Swing berukuran besar tetap dirawat, sementara proyek baru yang butuh visual modern cenderung memilih JavaFX atau memindahkan UI ke web.
Dengan peta di tangan, saatnya turun ke bengkel. Chapter berikutnya membahas Swing secara fundamental: hierarki JFrame-JPanel-komponen, peran Event Dispatch Thread, dan program jendela pertama Anda.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
HierarkiDemo.java
Unduh berkasimport javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** Menggambar pohon kontainer Swing tanpa membuka jendela nyata. */
public class HierarkiDemo {
public static void main(String[] args) {
JPanel panelTengah = new JPanel();
panelTengah.add(new JLabel("Nama:"));
panelTengah.add(new JButton("Simpan"));
JPanel panelInduk = new JPanel();
panelInduk.add(new JLabel("Aplikasi Data Siswa"));
panelInduk.add(panelTengah);
cetak(panelInduk, 0);
}
/** Cetak komponen dan seluruh anak-anaknya dengan indentasi bertingkat. */
private static void cetak(java.awt.Container induk, int kedalaman) {
System.out.println(" ".repeat(kedalaman) + induk.getClass().getSimpleName());
for (var anak : induk.getComponents()) {
if (anak instanceof java.awt.Container kontainerAnak) {
cetak(kontainerAnak, kedalaman + 1);
} else {
System.out.println(" ".repeat(kedalaman + 1) + anak.getClass().getSimpleName());
}
}
}
}