ฉันกำลังสร้างเมนูบริบทคลิกขวาโดยสร้างอินสแตนซ์ใหม่JMenu
เมื่อคลิกขวาและตั้งค่าตำแหน่งเป็นตำแหน่งของเมาส์ ... มีวิธีที่ดีกว่านี้ไหม
ฉันกำลังสร้างเมนูบริบทคลิกขวาโดยสร้างอินสแตนซ์ใหม่JMenu
เมื่อคลิกขวาและตั้งค่าตำแหน่งเป็นตำแหน่งของเมาส์ ... มีวิธีที่ดีกว่านี้ไหม
คำตอบ:
คุณอาจเรียกsetVisible(true)
เมนูด้วยตนเอง ซึ่งอาจทำให้เกิดพฤติกรรมบั๊กกี้ที่น่ารังเกียจในเมนู
show(Component, int x, int x)
วิธีการจับทุกสิ่งที่คุณจำเป็นต้องเกิดขึ้น (เน้นสิ่งที่เกี่ยวกับการวางเมาส์และปิดป๊อปอัพเมื่อมีความจำเป็น) ที่ใช้setVisible(true)
แค่แสดงให้เห็นเมนูโดยไม่ต้องเพิ่มพฤติกรรมใด ๆ เพิ่มเติม
ในการสร้างเมนูป๊อปอัพคลิกขวาให้สร้างไฟล์JPopupMenu
.
class PopUpDemo extends JPopupMenu {
JMenuItem anItem;
public PopUpDemo() {
anItem = new JMenuItem("Click Me!");
add(anItem);
}
}
จากนั้นสิ่งที่คุณต้องทำคือเพิ่มแบบกำหนดเองMouseListener
ให้กับส่วนประกอบที่คุณต้องการให้เมนูป๊อปอัป
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());
แน่นอนว่าบทช่วยสอนมีคำอธิบายเชิงลึกมากกว่านี้เล็กน้อย
หมายเหตุ:หากคุณสังเกตเห็นว่าเมนูป๊อปอัปปรากฏขึ้นไม่ตรงจุดที่ผู้ใช้คลิกให้ลองใช้e.getXOnScreen()
และe.getYOnScreen()
วิธีการสำหรับพิกัด x และ y
PopClickListener
ขยายนั้น MouseAdapter
component
ยืน?
คำถามนี้ค่อนข้างเก่า - เช่นเดียวกับคำตอบ (และแบบฝึกหัดด้วย)
api ปัจจุบันสำหรับการตั้งค่า popupMenu ใน Swing คือ
myComponent.setComponentPopupMenu(myPopupMenu);
วิธีนี้จะแสดงโดยอัตโนมัติทั้งสำหรับทริกเกอร์เมาส์และคีย์บอร์ด (ขึ้นอยู่กับ LAF) นอกจากนี้ยังรองรับการใช้ป๊อปอัปเดียวกันซ้ำกับลูก ๆ ของคอนเทนเนอร์อีกด้วย ในการเปิดใช้งานคุณสมบัตินั้น:
myChild.setInheritsPopupMenu(true);
JTable
จึงจะปรากฏบนแถวที่เลือกหรือบนแถวที่คุณคลิกขวา หรือในสถานการณ์นี้จะต้องเลือกวิธีการแบบเก่า?
มีส่วนในการเรียกใช้เมนูป๊อปอัพในบทความวิธีใช้เมนูของThe Java Tutorialsซึ่งอธิบายวิธีใช้JPopupMenu
คลาส
โค้ดตัวอย่างในบทช่วยสอนจะแสดงวิธีการเพิ่มMouseListener
s ลงในส่วนประกอบซึ่งควรแสดงเมนูป๊อปอัปและแสดงเมนูตามนั้น
(วิธีการที่คุณอธิบายค่อนข้างคล้ายกับวิธีที่บทช่วยสอนนำเสนอวิธีการแสดงเมนูป๊อปอัปบนส่วนประกอบ)
โค้ดต่อไปนี้ใช้เมนูบริบทเริ่มต้นซึ่งรู้จักจากWindows
ฟังก์ชันคัดลอกตัดวางเลือกทั้งหมดเลิกทำและทำซ้ำ นอกจากนี้ยังใช้งานได้Linux
และ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);
}
}
การใช้งาน:
JTextArea textArea = new JTextArea();
DefaultContextMenu.addDefaultContextMenu(textArea);
ตอนนี้textArea
จะมีเมนูบริบทเมื่อคลิกขวา
releasedEvent.isPopupTrigger()
แทนreleasedEvent.getButton() == MouseEvent.BUTTON3
การทำงานอย่างถูกต้องบนทุกแพลตฟอร์ม
pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
สิ่งเหล่านี้ต้องเป็นทั้งสองอย่างEx
หรือไม่Ex
ก็ได้ Ex
รุ่นgetMenuShortcutKeyMask()
จะใช้ได้เฉพาะตั้งแต่ Java 10+
ฉันจะแก้ไขการใช้งานสำหรับวิธีการนั้นที่ @BullyWillPlaza แนะนำ เหตุผลก็คือเมื่อฉันพยายามเพิ่ม add textArea ลงใน contextMenu เท่านั้นมันไม่สามารถมองเห็นได้และถ้าฉันเพิ่มลงในทั้งสองรายการไปยัง contextMenu และบางพาเนลมันจะมีตัวนับ: การเชื่อมโยงคู่หลักที่แตกต่างกันหากฉันพยายามเปลี่ยนไปใช้ตัวแก้ไขการออกแบบ
TexetObjcet.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)){
contextmenu.add(TexetObjcet);
contextmenu.show(TexetObjcet, 0, 0);
}
}
});
ทำให้เมาส์ฟังเช่นนี้สำหรับวัตถุข้อความที่คุณต้องมีป๊อปอัป สิ่งนี้จะทำคือเมื่อคุณคลิกขวาที่วัตถุข้อความของคุณจากนั้นจะเพิ่มป๊อปอัปนั้นและแสดงขึ้น วิธีนี้คุณจะไม่พบข้อผิดพลาดนั้น วิธีแก้ปัญหาที่ @BullyWillPlaza ทำนั้นดีมากรวยและรวดเร็วในการนำไปใช้ในโปรแกรมของคุณดังนั้นคุณควรลองใช้ดูว่าคุณชอบอย่างไร