0

Series Java Swing Bài 19: JSplitPane: Chia đôi màn hình có thanh kéo kích thước (như VS Code).

Nếu bạn mở bất kỳ phần mềm chuyên nghiệp nào (VS Code, IntelliJ, hay Windows File Explorer), bạn sẽ thấy một đặc điểm chung: Màn hình được chia làm hai nửa (ví dụ: thanh Sidebar bên trái và khu vực soạn thảo bên phải), và ở giữa có một đường viền mà bạn có thể dùng chuột kéo để thu hẹp hoặc mở rộng không gian.

Trong Java Swing, Component tạo ra sức mạnh đó chính là JSplitPane.

1. Hai chiều phân chia không gian (Orientation)

JSplitPane chỉ có thể chứa tối đa 2 Component. Khi khởi tạo, bạn phải quyết định sẽ "chặt" màn hình theo chiều ngang hay chiều dọc.

  • JSplitPane.HORIZONTAL_SPLIT (Chia ngang): Tạo ra không gian Trái (Left) và Phải (Right). Thường dùng làm Sidebar và Main Content.

  • JSplitPane.VERTICAL_SPLIT (Chia dọc): Tạo ra không gian Trên (Top) và Dưới (Bottom). Thường dùng làm Main Content phía trên và cửa sổ Terminal/Console Log phía dưới.

Java

// Khởi tạo JSplitPane chia theo chiều ngang
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

// Nhét 2 Component vào 2 bên
splitPane.setLeftComponent(new JButton("Trái"));
splitPane.setRightComponent(new JButton("Phải"));

2. Các tuyệt chiêu kiểm soát thanh kéo (Divider)

Thanh kéo nằm giữa 2 Component được gọi là Divider. Bạn có toàn quyền can thiệp vào cách thanh kéo này hoạt động.

Vị trí xuất phát của thanh kéo

Mặc định, JSplitPane sẽ cố gắng tự chia đôi không gian (50/50). Tuy nhiên, với giao diện như VS Code, Sidebar bên trái thường chỉ chiếm khoảng 200 pixel. Bạn có thể ép vị trí thanh kéo bằng phương thức setDividerLocation():

Java

// Đặt thanh kéo cách lề trái đúng 200 pixel
splitPane.setDividerLocation(200);

// HOẶC: Chia theo tỷ lệ phần trăm (0.3 = 30% cho bên trái, 70% cho bên phải)
// LƯU Ý: Lệnh này chỉ hoạt động SAU KHI cửa sổ JFrame đã hiển thị (setVisible(true))
splitPane.setDividerLocation(0.3);

Thu gọn nhanh (One-Touch Expandable)

Bạn có muốn trên thanh kéo xuất hiện 2 mũi tên nhỏ? Khi người dùng click vào mũi tên đó, một bên màn hình sẽ bị "sập" (thu gọn) lại hoàn toàn để nhường 100% diện tích cho bên kia. Chỉ cần 1 dòng code:

Java

splitPane.setOneTouchExpandable(true);

Chỉnh độ dày của thanh kéo

Nếu bạn thấy thanh kéo mặc định quá mỏng (khó click chuột) hoặc quá dày (xấu giao diện), bạn có thể thay đổi kích thước của nó:

Java

splitPane.setDividerSize(5); // Chỉnh độ dày thanh kéo thành 5 pixel

3. Lỗi kinh điển: Tại sao tôi không thể kéo thanh Divider sát vào lề?

Khi bạn chạy thử JSplitPane, rất có thể bạn sẽ gặp tình trạng kéo thanh Divider đến một mức nào đó thì nó bị "khựng" lại, không thể kéo nhỏ hơn được nữa.

Nguyên nhân: Bất kỳ Component nào trong Swing cũng có một thuộc tính ngầm là MinimumSize (Kích thước tối thiểu). JSplitPane cực kỳ tôn trọng thuộc tính này và sẽ không cho phép bạn ép một Component nhỏ hơn mức tối thiểu của nó.

Cách khắc phục: Ép MinimumSize của Component về 0.

Java

JPanel leftPanel = new JPanel();
leftPanel.setMinimumSize(new Dimension(0, 0)); // Chìa khóa giải quyết vấn đề
splitPane.setLeftComponent(leftPanel);

4. Source Code Thực Chiến: Giao diện VS Code Mini

Đoạn code dưới đây sẽ mô phỏng lại cấu trúc màn hình của VS Code: Bên trái là một danh sách file (JList), bên phải là khu vực gõ code (JTextArea). Chúng được phân tách bằng một JSplitPane chia ngang, có mũi tên thu gọn nhanh.

Java

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

public class JSplitPaneDemo extends JFrame {

    public JSplitPaneDemo() {
        setTitle("Giao diện VS Code Mini - JSplitPane");
        setSize(800, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // ==========================================
        // 1. COMPONENT BÊN TRÁI: SIDEBAR DANH SÁCH FILE
        // ==========================================
        String[] files = {"Main.java", "JSplitPaneDemo.java", "Config.xml", "README.md"};
        JList<String> fileList = new JList<>(files);
        fileList.setFont(new Font("Consolas", Font.PLAIN, 14));
        fileList.setBackground(new Color(45, 52, 54)); // Nền xám đậm
        fileList.setForeground(new Color(223, 230, 233)); // Chữ xám sáng

        // Bọc vào JScrollPane để có thanh cuộn nếu danh sách quá dài
        JScrollPane leftScroll = new JScrollPane(fileList);
        leftScroll.setMinimumSize(new Dimension(0, 0)); // Chống lỗi khựng Divider

        // ==========================================
        // 2. COMPONENT BÊN PHẢI: KHU VỰC SOẠN THẢO
        // ==========================================
        JTextArea codeEditor = new JTextArea();
        codeEditor.setText("public class Main {\n    public static void main(String[] args) {\n        System.out.println(\"Hello Swing!\");\n    }\n}");
        codeEditor.setFont(new Font("Consolas", Font.PLAIN, 16));
        codeEditor.setBackground(new Color(30, 30, 30)); // Nền đen (Dark Theme)
        codeEditor.setForeground(new Color(138, 226, 52)); // Chữ màu xanh lục ngọc
        codeEditor.setCaretColor(Color.WHITE); // Con trỏ nhấp nháy màu trắng

        JScrollPane rightScroll = new JScrollPane(codeEditor);
        rightScroll.setMinimumSize(new Dimension(0, 0));

        // ==========================================
        // 3. KHỞI TẠO VÀ CẤU HÌNH JSPLITPANE
        // ==========================================
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(leftScroll);
        splitPane.setRightComponent(rightScroll);

        // Các thuộc tính "ăn tiền"
        splitPane.setOneTouchExpandable(true); // Hiện 2 mũi tên thu gọn nhanh
        splitPane.setDividerLocation(200); // Fix cứng bên trái 200px lúc mới mở
        splitPane.setDividerSize(8); // Độ dày thanh kéo là 8px

        // Đưa SplitPane vào làm giao diện chính của cửa sổ
        add(splitPane, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new JSplitPaneDemo().setVisible(true));
    }
}

Hãy copy chạy thử. Bạn hãy rê chuột vào đường viền nằm giữa màn hình, kéo sang trái/phải, hoặc click vào biểu tượng 2 mũi tên nhỏ trên đường viền đó để thấy cách Sidebar thu gọn và mở ra mượt mà như thế nào.


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í