Series Java Swing Bài 23: JPopupMenu - Menu ngữ cảnh (Chuột phải)
Bên cạnh thanh menu chính (JMenuBar) cố định ở trên cùng, các phần mềm hiện đại luôn cung cấp một loại menu thứ hai: Context Menu (Menu ngữ cảnh). Đây là một menu ẩn, chỉ xuất hiện ngay tại vị trí con trỏ khi bạn click chuột phải vào một thành phần nào đó trên màn hình (như ô nhập liệu, danh sách, hoặc nền cửa sổ).
Trong Java Swing, Component đảm nhận vai trò này là JPopupMenu.
1. Khởi tạo và thiết kế JPopupMenu
Cấu trúc của JPopupMenu giống hệt JMenu (Bài 21). Nó cũng đóng vai trò là một "vật chứa", và bạn sẽ nhét các JMenuItem vào bên trong nó.
Java
// 1. Khởi tạo Popup Menu
JPopupMenu popupMenu = new JPopupMenu();
// 2. Tạo các Item
JMenuItem itemCopy = new JMenuItem("Copy");
JMenuItem itemPaste = new JMenuItem("Paste");
JMenuItem itemDelete = new JMenuItem("Delete");
// Đổi icon hoặc gán phím tắt nếu muốn
// itemCopy.setIcon(...);
// 3. Đưa Item vào Popup
popupMenu.add(itemCopy);
popupMenu.add(itemPaste);
popupMenu.addSeparator(); // Đường phân cách
popupMenu.add(itemDelete);
Tuy nhiên, khác với JMenuBar được gắn chết vào cửa sổ bằng hàm setJMenuBar(), JPopupMenu mặc định là tàng hình và sống trôi nổi trong bộ nhớ. Bạn phải chủ động gọi nó ra.
2. Cách triệu hồi JPopupMenu (Có 2 phương pháp)
Phương pháp 1: Gọi thủ công bằng Sự kiện Chuột (MouseListener) - Dành cho cấu hình phức tạp
Đây là cách cổ điển nhất. Bạn gắn một MouseListener vào cái Component mà bạn muốn nó lắng nghe chuột phải (ví dụ: JTextArea hoặc JTable). Khi người dùng click, bạn kiểm tra xem đó có phải là click chuột phải không, lấy tọa độ X, Y và ép menu xuất hiện.
Java
textArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
// e.isPopupTrigger() tự động kiểm tra xem có phải là thao tác click chuột phải
// (tùy thuộc vào hệ điều hành Windows/Mac)
if (e.isPopupTrigger()) {
// Hiển thị menu ở đúng Component đó, tại tọa độ x, y của con chuột
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
Phương pháp 2: Gọi tự động (ComponentPopupMenu) - Siêu nhanh, khuyên dùng từ Java 5+
Kể từ Java 5, việc gắn PopupMenu trở nên nhàn hạ hơn rất nhiều. Mọi Component trong Swing đều được tích hợp sẵn một ngăn chứa riêng cho PopupMenu. Bạn chỉ cần gọi đúng 1 dòng code, Swing sẽ tự lo toàn bộ phần logic tính toán tọa độ và bắt sự kiện chuột phải.
Java
// Gắn popupMenu trực tiếp vào textArea
textArea.setComponentPopupMenu(popupMenu);
(Lưu ý: Mặc dù Phương pháp 2 cực nhanh, nhưng Phương pháp 1 vẫn tồn tại vì khi bạn làm việc với JTable hoặc JTree, bạn cần biết chính xác người dùng vừa click chuột phải vào hàng số mấy để load menu tương ứng. Lúc đó bắt buộc phải dùng Phương pháp 1).
3. Ứng dụng thực tế: Xóa toàn bộ nội dung Form
Một tính năng rất hữu ích của JPopupMenu là gán nó vào vùng nền (Background) của một Form hoặc vào chính cửa sổ. Khi người dùng click chuột phải vào chỗ trống, menu "Clear Form" sẽ hiện lên.
Java
// Gắn thẳng PopupMenu vào lớp kính của JFrame (áp dụng cho mọi chỗ trống)
frame.getContentPane().setComponentPopupMenu(popupMenu);
4. Source Code Thực Chiến: Giao diện Text Editor với Menu Chuột Phải
Đoạn code dưới đây tạo ra một khung soạn thảo văn bản. Khi bạn click chuột phải vào khu vực gõ chữ, một menu sẽ xổ ra cho phép bạn: Chữ in đậm, Chữ màu đỏ, và Xóa sạch (Clear).
Java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class JPopupMenuDemo extends JFrame {
public JPopupMenuDemo() {
setTitle("Menu Ngữ Cảnh - Chuột Phải");
setSize(500, 350);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
// ==========================================
// 1. KHU VỰC SOẠN THẢO VĂN BẢN
// ==========================================
JTextArea textArea = new JTextArea("Hãy click CHUỘT PHẢI vào không gian này để thấy phép màu!");
textArea.setFont(new Font("Arial", Font.PLAIN, 18));
textArea.setLineWrap(true);
textArea.setMargin(new Insets(10, 10, 10, 10)); // Lùi lề vào 10px
add(new JScrollPane(textArea), BorderLayout.CENTER);
// ==========================================
// 2. KHỞI TẠO JPOPUPMENU VÀ CÁC ITEM
// ==========================================
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem itemBold = new JMenuItem("Đổi sang In Đậm");
JMenuItem itemRedText = new JMenuItem("Đổi chữ sang Màu Đỏ");
JMenuItem itemClear = new JMenuItem("Xóa sạch nội dung");
// Đưa các Item vào Popup
popupMenu.add(itemBold);
popupMenu.add(itemRedText);
popupMenu.addSeparator(); // Dấu gạch kẻ phân cách
popupMenu.add(itemClear);
// ==========================================
// 3. LOGIC XỬ LÝ SỰ KIỆN KHI BẤM MENU
// ==========================================
itemBold.addActionListener((ActionEvent e) -> {
Font currentFont = textArea.getFont();
// Lấy tên font cũ, đổi style thành BOLD, giữ nguyên kích thước
textArea.setFont(new Font(currentFont.getName(), Font.BOLD, currentFont.getSize()));
});
itemRedText.addActionListener(e -> {
textArea.setForeground(Color.RED);
});
itemClear.addActionListener(e -> {
textArea.setText(""); // Xóa rỗng text
// Trả lại định dạng mặc định nếu muốn
textArea.setFont(new Font("Arial", Font.PLAIN, 18));
textArea.setForeground(Color.BLACK);
});
// ==========================================
// 4. GẮN POPUP VÀO TEXT AREA (PHƯƠNG PHÁP NHANH)
// ==========================================
textArea.setComponentPopupMenu(popupMenu);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new JPopupMenuDemo().setVisible(true));
}
}
Bạn hãy chạy chương trình, di chuyển trỏ chuột vào vùng chữ và bấm chuột phải. Giao diện Menu sẽ bung ra mượt mà và thực hiện các chức năng định dạng văn bản đúng chuẩn như trong Microsoft Word.
All Rights Reserved