Tôi hiện đang tạo menu ngữ cảnh nhấp chuột phải bằng cách khởi tạo JMenu
mới khi nhấp chuột phải và đặt vị trí của nó thành vị trí của con chuột ... Có cách nào tốt hơn không?Làm cách nào để tạo menu ngữ cảnh nhấp chuột phải trong Java Swing?
Trả lời
Bạn có lẽ bằng tay gọi setVisible(true)
trên menu. Điều đó có thể gây ra một số hành vi buggy khó chịu trong menu.
Phương pháp show(Component, int x, int x)
xử lý mọi thứ bạn cần xảy ra, (Làm nổi bật mọi thứ khi di chuột qua và đóng cửa sổ bật lên khi cần) khi sử dụng setVisible(true)
chỉ hiển thị menu mà không thêm bất kỳ hành vi bổ sung nào.
Để tạo menu bật lên nhấp chuột phải, chỉ cần tạo JPopupMenu
.
class PopUpDemo extends JPopupMenu {
JMenuItem anItem;
public PopUpDemo(){
anItem = new JMenuItem("Click Me!");
add(anItem);
}
}
Sau đó, tất cả những gì bạn cần làm là thêm tùy chỉnh MouseListener
vào các thành phần bạn muốn trình đơn bật lên.
class PopClickListener extends MouseAdapter {
public void mousePressed(MouseEvent e){
if (e.isPopupTrigger())
doPop(e);
}
public void mouseReleased(MouseEvent e){
if (e.isPopupTrigger())
doPop(e);
}
private void doPop(MouseEvent e){
PopUpDemo menu = new PopUpDemo();
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
// Then on your component(s)
component.addMouseListener(new PopClickListener());
Tất nhiên, hướng dẫn có giải thích slightly more in-depth.
Lưu ý: Nếu bạn nhận thấy rằng các menu popup xuất hiện cách khỏi nơi người dùng nhấn vào, hãy thử sử dụng e.getXOnScreen()
và e.getYOnScreen()
phương pháp để tọa độ x và y.
Có một phần trên Bringing Up a Popup Menu trong bài viết How to Use Menus của The Java Tutorials giải thích cách sử dụng lớp JPopupMenu
.
Mã ví dụ trong hướng dẫn cho biết cách thêm MouseListener
giây vào các thành phần sẽ hiển thị menu bật lên và hiển thị menu tương ứng.
(Phương pháp bạn mô tả là khá tương tự như cách hướng dẫn trình bày các cách để hiển thị một menu pop-up trên một thành phần.)
Câu hỏi này là một chút cũ - như là những câu trả lời (và hướng dẫn cũng)
Các api hiện để thiết lập một popupMenu trong Swing là
myComponent.setComponentPopupMenu(myPopupMenu);
Bằng cách này nó sẽ được hiển thị Automagically , cho cả kích hoạt chuột và bàn phím (sau này phụ thuộc vào LAF). Ngoài ra, nó hỗ trợ tái sử dụng cùng một cửa sổ bật lên trên con của vùng chứa. Để bật tính năng đó:
myChild.setInheritsPopupMenu(true);
Các mã sau đây thực hiện một menu ngữ cảnh mặc định được biết đến từ Windows
với sao chép, cắt, dán, chọn tất cả, undo và redo chức năng. Nó cũng hoạt động trên Linux
và Mac OS X
:
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DefaultContextMenu extends JPopupMenu
{
private Clipboard clipboard;
private UndoManager undoManager;
private JMenuItem undo;
private JMenuItem redo;
private JMenuItem cut;
private JMenuItem copy;
private JMenuItem paste;
private JMenuItem delete;
private JMenuItem selectAll;
private JTextComponent textComponent;
public DefaultContextMenu()
{
undoManager = new UndoManager();
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
addPopupMenuItems();
}
private void addPopupMenuItems()
{
undo = new JMenuItem("Undo");
undo.setEnabled(false);
undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
undo.addActionListener(event -> undoManager.undo());
add(undo);
redo = new JMenuItem("Redo");
redo.setEnabled(false);
redo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
redo.addActionListener(event -> undoManager.redo());
add(redo);
add(new JSeparator());
cut = new JMenuItem("Cut");
cut.setEnabled(false);
cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
cut.addActionListener(event -> textComponent.cut());
add(cut);
copy = new JMenuItem("Copy");
copy.setEnabled(false);
copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
copy.addActionListener(event -> textComponent.copy());
add(copy);
paste = new JMenuItem("Paste");
paste.setEnabled(false);
paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
paste.addActionListener(event -> textComponent.paste());
add(paste);
delete = new JMenuItem("Delete");
delete.setEnabled(false);
delete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
delete.addActionListener(event -> textComponent.replaceSelection(""));
add(delete);
add(new JSeparator());
selectAll = new JMenuItem("Select All");
selectAll.setEnabled(false);
selectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
selectAll.addActionListener(event -> textComponent.selectAll());
add(selectAll);
}
private void addTo(JTextComponent textComponent)
{
textComponent.addKeyListener(new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent pressedEvent)
{
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Z)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canUndo())
{
undoManager.undo();
}
}
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Y)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canRedo())
{
undoManager.redo();
}
}
}
});
textComponent.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
@Override
public void mouseReleased(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
});
textComponent.getDocument().addUndoableEditListener(event -> undoManager.addEdit(event.getEdit()));
}
private void handleContextMenu(MouseEvent releasedEvent)
{
if (releasedEvent.getButton() == MouseEvent.BUTTON3)
{
processClick(releasedEvent);
}
}
private void processClick(MouseEvent event)
{
textComponent = (JTextComponent) event.getSource();
textComponent.requestFocus();
boolean enableUndo = undoManager.canUndo();
boolean enableRedo = undoManager.canRedo();
boolean enableCut = false;
boolean enableCopy = false;
boolean enablePaste = false;
boolean enableDelete = false;
boolean enableSelectAll = false;
String selectedText = textComponent.getSelectedText();
String text = textComponent.getText();
if (text != null)
{
if (text.length() > 0)
{
enableSelectAll = true;
}
}
if (selectedText != null)
{
if (selectedText.length() > 0)
{
enableCut = true;
enableCopy = true;
enableDelete = true;
}
}
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor) && textComponent.isEnabled())
{
enablePaste = true;
}
undo.setEnabled(enableUndo);
redo.setEnabled(enableRedo);
cut.setEnabled(enableCut);
copy.setEnabled(enableCopy);
paste.setEnabled(enablePaste);
delete.setEnabled(enableDelete);
selectAll.setEnabled(enableSelectAll);
// Shows the popup menu
show(textComponent, event.getX(), event.getY());
}
public static void addDefaultContextMenu(JTextComponent component)
{
DefaultContextMenu defaultContextMenu = new DefaultContextMenu();
defaultContextMenu.addTo(component);
}
}
Cách sử dụng:
JTextArea textArea = new JTextArea();
DefaultContextMenu.addDefaultContextMenu(textArea);
Bây giờ textArea
sẽ có một menu ngữ cảnh khi nó là phải nhấp vào.
Tôi sẽ sửa cách sử dụng cho phương thức mà @BullyWillPlaza đề xuất.Lý do là khi tôi cố gắng thêm textArea vào chỉ contextMenu nó không hiển thị, và nếu tôi thêm nó vào cả hai contextMenu và một số bảng nó ecounters: cha mẹ khác nhau đôi hiệp hội nếu tôi cố gắng để chuyển sang thiết kế trình soạn thảo.
TexetObjcet.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)){
contextmenu.add(TexetObjcet);
contextmenu.show(TexetObjcet, 0, 0);
}
}
});
Làm cho người nghe chuột như thế này cho đối tượng văn bản bạn cần bật lên bật lên. Điều này sẽ làm là khi bạn nhấp chuột phải vào đối tượng văn bản của bạn sau đó nó sẽ thêm popup và hiển thị nó. Bằng cách này bạn không gặp phải lỗi đó. Giải pháp mà @BullyWillPlaza thực hiện rất tốt, phong phú và nhanh chóng để triển khai trong chương trình của bạn, do đó bạn nên thử cách chúng tôi thấy bạn thích nó như thế nào.
Cũng đừng quên bạn vẫn cần phải nhập ngữ cảnh đóMenu và tạo cá thể mới. –
- 1. Làm cách nào để thiết lập menu ngữ cảnh Nhấp chuột phải trong Silverlight?
- 2. Làm cách nào để thêm menu senstive ngữ cảnh vào NSOutlineView (tức là menu chuột phải)
- 3. Cách tạo menu ngữ cảnh nhấp chuột phải cho một nút trong WPF
- 4. Cách thêm mục menu vào menu ngữ cảnh nhấp chuột phải mặc định
- 5. Thêm văn bản tối ưu 2 vào menu ngữ cảnh nhấp chuột phải trong Ubuntu 12.04
- 6. Làm cách nào để thêm menu ngữ cảnh vào ListBoxItem?
- 7. Hiển thị menu ngữ cảnh trên nhấn ctrl/nhấp chuột phải vào tiêu đề của NSTableView
- 8. Tìm nút được nhấp trong menu ngữ cảnh
- 9. xul: tạo một mục trình đơn ngữ cảnh nhấp chuột phải chỉ với siêu liên kết
- 10. Làm thế nào để tạo một shortcut chuột phải trong ngữ cảnh "edit with Emacs"?
- 11. PyQt và menu ngữ cảnh
- 12. Thay đổi kích chuột phải vào tùy chọn menu ngữ cảnh trong VS2008
- 13. Qt QListView - menu ngữ cảnh?
- 14. TabControl Menu ngữ cảnh
- 15. Cấu hình trình đơn ngữ cảnh nhấp chuột phải jstree cho các loại nút khác nhau
- 16. Nhấp chuột phải để chọn các mục trong ListBox
- 17. Có thể thêm mục vào menu ngữ cảnh nhấp chuột phải của Mac OS theo lập trình không?
- 18. Silverlight Datagrid chọn trên nhấp chuột phải
- 19. Java Swing JTable; Menu Nhấp chuột phải (Làm thế nào để làm cho nó "chọn" hay còn gọi là tô sáng hàng)
- 20. VSTO (Cấp tài liệu): Trình đơn ngữ cảnh riêng lẻ trong Excel (menu chuột phải)
- 21. Menu ngữ cảnh tab QTabWidget
- 22. Thời gian chạy MS Access 2010 - Thiếu chuột phải Nhấp vào Menu ngữ cảnh ở dạng liên tục
- 23. Làm cách nào để tìm ra tab nào tôi đang nhấp chuột phải trong tabcontrol của winforms?
- 24. jQuery Nhấp chuột phải vào Trình đơn ngữ cảnh Trợ giúp!
- 25. Có sai cho một menu ngữ cảnh (nhấp chuột phải) là cách duy nhất để người dùng có thể thực hiện một tác vụ nào đó không?
- 26. Làm cách nào để mở menu ngữ cảnh trên thanh bên SublimeText 2 bằng bàn phím?
- 27. Tạo menu ngữ cảnh cho win32 API
- 28. Menu chuột phải trong ứng dụng Console
- 29. Có cách nào để lấy từ trong menu ngữ cảnh trong phần mở rộng firefox không?
- 30. Làm cách nào để tạo Menu ngữ cảnh bằng tệp XML?
Sau khi sử dụng mã trên, tôi nhận được lỗi nói rằng "Phương thức addMouseListener (MouseListener) trong loại Hình không áp dụng cho các đối số (PopClickListener)" Trân trọng, Vinay –
@ user1035905 Bạn có chắc chắn rằng ' PopClickListener' mở rộng 'MouseAdapter'? – jjnguy
Làm cách nào để bạn làm việc với phím menu ngữ cảnh trên bàn phím? –