मैं जावा स्विंग में राइट क्लिक संदर्भ मेनू कैसे बनाऊं?


110

मैं वर्तमान में JMenuराइट क्लिक पर एक नया इंस्टैंट करके और माउस के स्थान पर अपना स्थान सेट करके एक राइट-क्लिक संदर्भ मेनू बना रहा हूं ... क्या कोई बेहतर तरीका है?

जवाबों:


140

आप 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 निर्देशांक तरीकों।


उपर्युक्त कोड का उपयोग करने के बाद, मुझे यह कहते हुए त्रुटि मिलती है कि "प्रकार addMouseListener (माउस लिस्टनर) चित्र में तर्क (PopClickListener) के लिए लागू नहीं है" सादर, विनय

1
@ user1035905 क्या आपने यह सुनिश्चित किया है कि PopClickListenerविस्तार हो MouseAdapter?
jjnguy

आप इसे कीबोर्ड पर संदर्भ मेनू कुंजी के साथ कैसे काम कर सकते हैं?
क्रिस्टोफर हैमरस्ट्रॉम

एकमात्र मामला जिसमें यह समाधान kleopatra की तुलना में बेहतर है, जब आपको कुछ कस्टम लॉजिक होने की आवश्यकता होती है (जैसे अलग-अलग परिस्थितियों में अलग-अलग पॉपअप मेनू); फिर भी, आपको संदर्भ मेनू कुंजी के साथ काम करने के लिए कीबोर्ड श्रोता को जोड़ना होगा

2
क्या componentखड़ा है?

117

यह प्रश्न थोड़ा पुराना है - जैसे कि उत्तर हैं (और साथ ही ट्यूटोरियल)

स्विंगिंग में एक पॉपअपमेनु की स्थापना के लिए वर्तमान एपि है

myComponent.setComponentPopupMenu(myPopupMenu);

इस तरह यह स्वचालित रूप से दिखाया जाएगा, दोनों माउस और कीबोर्ड ट्रिगर्स के लिए (बाद वाला एलएएफ पर निर्भर करता है)। इसके अलावा, यह एक कंटेनर के बच्चों में एक ही पॉपअप का फिर से उपयोग करने का समर्थन करता है। उस सुविधा को सक्षम करने के लिए:

myChild.setInheritsPopupMenu(true);

2
@ user681159 किसी को भी नहीं पता है - और इसकी जरूरत नहीं है, IMO, बस एपीसी डॉक्टर पढ़ें:
kleopatra

2
आप इसका उपयोग कैसे करेंगे JTableताकि यह चयनित पंक्ति पर या उस पंक्ति पर पॉप हो जहां आप राइट क्लिक करते हैं? या इस परिदृश्य में पुरानी पद्धति को चुना जाना है?
एलेक्स बर्दुलस

1
@Burfee या तो है कि या उपवर्गीकरण के माध्यम से JTable बढ़ाने: ओवरराइड getPopupLocation (..) और बाद में उपयोग के लिए स्थान की दुकान, एक हाल ही में गुणवत्ता आश्वासन देखना जो सभी SwingX संग्रह घटकों में कार्यान्वित किया जाता है
Kleopatra

18

जावा ट्यूटोरियल के मेनू लेख का उपयोग करने के तरीके में एक पॉपअप मेनू लाने पर एक खंड है जो बताता है कि कक्षा का उपयोग कैसे करें ।JPopupMenu

ट्यूटोरियल में उदाहरण कोड दिखाता है कि MouseListenerघटकों को कैसे जोड़ना है जो पॉप-अप मेनू प्रदर्शित करना चाहिए, और तदनुसार मेनू प्रदर्शित करता है।

(आप जिस विधि का वर्णन करते हैं वह काफी हद तक उसी तरह से होता है जिस तरह से ट्यूटोरियल किसी घटक पर पॉप-अप मेनू दिखाने का तरीका प्रस्तुत करता है।)


8

निम्न कोड एक डिफ़ॉल्ट संदर्भ मेनू 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()केवल जावा 10+ के बाद से उपलब्ध है।
फ्रेडरिक लीटनबर्गर

1

मैं उस विधि का उपयोग सही करूँगा जो @BullyWillPlaza ने सुझाया था। कारण यह है कि जब मैं केवल संदर्भ के लिए textArea को जोड़ने का प्रयास करता हूं, तो यह दिखाई नहीं देता है, और अगर मैं इसे संदर्भमेनेनू और कुछ पैनल दोनों से जोड़ता हूं तो यह समान है: यदि मैं डिज़ाइन संपादक पर स्विच करने का प्रयास करता हूं तो अलग-अलग माता-पिता डबल एसोसिएशन।

TexetObjcet.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (SwingUtilities.isRightMouseButton(e)){
                contextmenu.add(TexetObjcet);
                contextmenu.show(TexetObjcet, 0, 0);
            }
        }
    }); 

माउस श्रोता को इस तरह बनाएं कि आपको जिस ऑब्जेक्ट पर पॉपअप करना है, उसके टेक्स्ट ऑब्जेक्ट के लिए। जब आप अपने टेक्स्ट ऑब्जेक्ट पर राइट क्लिक करेंगे तो यह उस पॉपअप को जोड़ देगा और उसे प्रदर्शित करेगा। इस तरह आप उस त्रुटि का सामना नहीं करते हैं। समाधान जो @BullyWillPlaza बनाया है वह बहुत अच्छा, समृद्ध और आपके कार्यक्रम में लागू करने के लिए तेज़ है, इसलिए आपको यह देखने की कोशिश करनी चाहिए कि आपको यह कैसे पसंद है।


यह भी मत भूलो कि आपको अभी भी उस संदर्भ को आयात करने की आवश्यकता है और नया उदाहरण बनाएं।
atumi स्प्रिंग ब्रनिस्लाव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.