0

Series Java Swing Bài 3: Phân tích JFrame: Khởi tạo, các thuộc tính vòng đời của một cửa sổ

JFrame là bệ phóng của mọi ứng dụng Desktop viết bằng Java Swing. Nó đóng vai trò là một Top-Level Container (Vật chứa cấp cao nhất) — nghĩa là nó có thể tồn tại độc lập trên màn hình hệ điều hành, sở hữu thanh tiêu đề (title bar), viền (border), và các nút điều khiển (thu nhỏ, phóng to, đóng).


1. Khởi Tạo Và Các Thuộc Tính Cơ Bản

Một cửa sổ JFrame khi mới được khởi tạo bằng từ khóa new JFrame() sẽ hoàn toàn vô hình và có kích thước 0x0. Bạn phải thiết lập các thuộc tính vật lý để nó xuất hiện đúng ý muốn.

JFrame frame = new JFrame("Phần mềm Quản lý Kho");

// 1. Đặt kích thước (Chiều rộng, Chiều cao) tính bằng pixel
frame.setSize(800, 600); 

// 2. Căn giữa màn hình (Phải gọi sau khi setSize)
frame.setLocationRelativeTo(null); 

// 3. Ngăn người dùng kéo giãn hoặc thu nhỏ kích thước cửa sổ
frame.setResizable(false); 

// 4. Hiển thị cửa sổ lên màn hình (Luôn để ở cuối cùng)
frame.setVisible(true); 

2. Quản Lý Vòng Đời: Khi Người Dùng Bấm Nút "X"

Một trong những lỗi phổ biến nhất của người mới học là: Bấm nút "X" (đóng cửa sổ) trên giao diện, cửa sổ biến mất, nhưng ứng dụng vẫn tiếp tục chạy ngầm trong Task Manager và ngốn RAM.

Lý do là bạn chưa cấu hình phương thức setDefaultCloseOperation(). Java cung cấp 4 hằng số quản lý hành vi đóng cửa sổ:

Hằng số (Thuộc lớp JFrame) Trạng thái vòng đời ứng dụng Ứng dụng thực tế
HIDE_ON_CLOSE (Mặc định) Cửa sổ bị ẩn đi (tương đương setVisible(false)). Ứng dụng vẫn chạy ngầm. Các app chạy dưới khay hệ thống (System Tray) như Zalo, Unikey.
EXIT_ON_CLOSE Tắt ngay lập tức toàn bộ chương trình (Kill JVM). Cửa sổ chính của phần mềm (Main Form). Đóng cửa sổ này là tắt app.
DISPOSE_ON_CLOSE Tiêu hủy cửa sổ hiện tại và giải phóng bộ nhớ (RAM). Nếu đây là cửa sổ cuối cùng, app sẽ dừng. Các cửa sổ phụ, hộp thoại mở lên từ cửa sổ chính.
DO_NOTHING_ON_CLOSE Vô hiệu hóa nút X, không làm gì cả. Kết hợp với WindowListener để hiển thị hộp thoại cảnh báo: "Bạn có dữ liệu chưa lưu, có chắc muốn thoát?".

Ví dụ cấu hình cho cửa sổ chính:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

3. Bản Chất Bên Trong: ContentPane

Khi bạn thêm một nút bấm vào JFrame bằng lệnh frame.add(button), thực chất nút bấm đó không được gắn trực tiếp lên lớp vỏ ngoài của JFrame.

Bên trong JFrame có một lớp kính vô hình chịu trách nhiệm chứa mọi Component, gọi là ContentPane. Lệnh frame.add() ở các phiên bản Java mới chỉ là một hàm viết tắt cho frame.getContentPane().add().

Để thay đổi màu nền của toàn bộ cửa sổ, bạn không thể gọi frame.setBackground(Color.RED), mà phải can thiệp vào ContentPane:

frame.getContentPane().setBackground(Color.WHITE);

4. Best Practice: Kế Thừa (Inheritance) Thay Vì Khởi Tạo Trực Tiếp

Thay vì viết code gom cục toàn bộ UI vào hàm main(), chuẩn thiết kế OOP quy định bạn nên tạo một class riêng kế thừa từ JFrame. Cách này giúp bạn tách biệt giao diện, dễ bảo trì và dễ gọi từ các luồng khác.

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

public class MainAppFrame extends JFrame {

    // Constructor: Nơi thiết lập UI
    public MainAppFrame() {
        initComponents();
    }

    private void initComponents() {
        setTitle("Dashboard Quản Trị");
        setSize(1024, 768);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // Thêm các Component khác vào đây...
    }

    public static void main(String[] args) {
        // Áp dụng quy tắc EDT (Event Dispatch Thread)
        SwingUtilities.invokeLater(() -> {
            MainAppFrame app = new MainAppFrame();
            app.setVisible(true);
        });
    }
}

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí