Jawaban:
Anda mungkin memanggil setVisible(true)
menu secara manual . Itu dapat menyebabkan beberapa perilaku buggy yang buruk di menu.
The show(Component, int x, int x)
Metode menangani semua hal yang Anda perlu terjadi, (Menyoroti hal-hal di mouseover dan menutup popup bila perlu) di mana menggunakansetVisible(true)
hanya menunjukkan menu tanpa menambahkan perilaku tambahan.
Untuk membuat menu popup klik kanan, cukup buat file JPopupMenu
.
class PopUpDemo extends JPopupMenu {
JMenuItem anItem;
public PopUpDemo() {
anItem = new JMenuItem("Click Me!");
add(anItem);
}
}
Kemudian, yang perlu Anda lakukan adalah menambahkan kustom MouseListener
ke komponen yang Anda inginkan untuk menu pop-up.
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());
Tentu saja tutorialnya memiliki penjelasan yang sedikit lebih mendalam .
Catatan: Jika Anda melihat bahwa menu popup muncul jauh dari tempat pengguna mengklik, coba gunakan metode e.getXOnScreen()
dan e.getYOnScreen()
untuk koordinat x dan y.
PopClickListener
meluas MouseAdapter
?
component
?
Pertanyaan ini agak tua - begitu pula jawabannya (dan juga tutorialnya)
Api saat ini untuk menyetel popupMenu di Swing adalah
myComponent.setComponentPopupMenu(myPopupMenu);
Dengan cara ini akan ditampilkan secara otomatis, baik untuk pemicu mouse dan keyboard (yang terakhir bergantung pada LAF). Plus, ini mendukung penggunaan kembali popup yang sama di seluruh anak wadah. Untuk mengaktifkan fitur itu:
myChild.setInheritsPopupMenu(true);
JTable
sehingga muncul di baris yang dipilih atau di baris di mana Anda klik kanan? Atau dalam skenario ini, metode lama yang akan dipilih?
Ada bagian tentang Memunculkan Menu Popup di artikel Cara Menggunakan Menu dari Tutorial Java yang menjelaskan cara menggunakanJPopupMenu
kelas.
Kode contoh dalam tutorial menunjukkan cara menambahkan MouseListener
s ke komponen yang seharusnya menampilkan menu pop-up, dan menayangkan menu yang sesuai.
(Metode yang Anda gambarkan cukup mirip dengan cara tutorial menyajikan cara menampilkan menu pop-up pada suatu komponen.)
Kode berikut mengimplementasikan menu konteks default yang dikenal Windows
dengan fungsi salin, potong, tempel, pilih semua, batalkan, dan ulangi. Ini juga berfungsi pada Linux
dan 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);
}
}
Pemakaian:
JTextArea textArea = new JTextArea();
DefaultContextMenu.addDefaultContextMenu(textArea);
Sekarang textArea
akan memiliki menu konteks saat diklik kanan.
releasedEvent.isPopupTrigger()
alih-alih releasedEvent.getButton() == MouseEvent.BUTTON3
berfungsi dengan baik di semua platform.
pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
harus ada keduanya Ex
atau tidak Ex
. The Ex
versi getMenuShortcutKeyMask()
ini hanya tersedia sejak java 10 +.
Saya akan mengoreksi penggunaan untuk metode yang disarankan @BullyWillPlaza. Alasannya adalah ketika saya mencoba menambahkan textArea ke hanya contextMenu itu tidak terlihat, dan jika saya menambahkannya ke kedua contextMenu dan beberapa panel itu ecounters: Asosiasi ganda induk yang berbeda jika saya mencoba untuk beralih ke editor Desain.
TexetObjcet.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)){
contextmenu.add(TexetObjcet);
contextmenu.show(TexetObjcet, 0, 0);
}
}
});
Jadikan pendengar mouse seperti ini untuk objek teks yang perlu Anda aktifkan popupnya. Apa yang akan dilakukan adalah ketika Anda mengklik kanan pada objek teks Anda, ia akan menambahkan popup itu dan menampilkannya. Dengan cara ini Anda tidak menemukan kesalahan itu. Solusi yang dibuat oleh @BullyWillPlaza sangat bagus, kaya, dan cepat diimplementasikan di program Anda sehingga Anda harus mencobanya, lihat seberapa suka Anda.