Эффективный способ добавления JMenuItems

ОК, так что до того, как моя программа INV должна была УДАЛИТЬ пункты меню, но потом я подумал... это слишком много. Так что, если бы я ДОБАВЛЯЛ пункты меню для определенных элементов, щелкаемых правой кнопкой мыши, ВМЕСТО удаления каждый раз?

Таким образом, если вы щелкнете правой кнопкой мыши на элементе 1, в меню будут добавлены «Использовать» и «Удалить». Затем, КОГДА вы выберете свой вариант, JMenu удалит все, чтобы оно было там, где мы начали. Затем, если вы щелкнете правой кнопкой мыши на Item 2, он добавит «Использовать» и «Отмена». Видишь, куда я иду?

Я пытался сделать это сам, но я просто не могу понять, как это сделать — например, чтобы добавить новый JMenuItem, вам нужно сделать это:

popup.add(item = new JMenuItem("Cancel"));
item.addActionListener(menuListener);

и, как видите, добавьте прослушиватель действий. Я не могу сделать это под if (actItemx == "Item 1") {, так что... что мне делать?

В любом случае, вот что у меня есть до сих пор:

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;

public class inv extends JApplet implements MouseListener
{
    public JList listbox;
    public JPopupMenu popup;
    public JMenuItem item;

    public void init()
    {
        ActionListener menuListener = new ActionListener()
        {
            public void actionPerformed(ActionEvent event)
            {
                String invAction = event.getActionCommand();


                int itemSelect = listbox.getSelectedIndex();
                Object actItem = listbox.getModel().getElementAt(itemSelect);

                System.out.println("Popup menu item [" + invAction + "] [ " + actItem + " ] was pressed.");
            }
        };

        popup = new JPopupMenu();

        popup.add(item = new JMenuItem("Use"));
        item.addActionListener(menuListener);

        popup.add(item = new JMenuItem("Drop"));
        item.addActionListener(menuListener);

        popup.add(item = new JMenuItem("Cancel"));
        item.addActionListener(menuListener);



        String listData[] =
        {
            "Item 1","Item 2","Item 3","Item 4"
        };

        listbox = new JList( listData );
        listbox.addMouseListener( new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
                if ( SwingUtilities.isRightMouseButton(e) )
                {
                    System.out.println("Row: " + getRow(e.getPoint()));
                    listbox.setSelectedIndex(getRow(e.getPoint()));
                }
            }
        }
        );

        listbox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        add(listbox);
        listbox.setVisible(true);
        listbox.setFocusable(false);


        listbox.addMouseListener(new MousePopupListener());
    }

    class MousePopupListener extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            checkPopup(e);
        }

        public void mouseClicked(MouseEvent e)
        {
            checkPopup(e);
        }

        public void mouseReleased(MouseEvent e)
        {
            checkPopup(e);
        }

        private void checkPopup(MouseEvent e)
        {
            if (e.isPopupTrigger())
            {

                int itemSelectx = listbox.getSelectedIndex();
                Object actItemx = listbox.getModel().getElementAt(itemSelectx);
                System.out.println("You pressed on " + actItemx);

            if (actItemx == "Item 1") {
                System.out.println("Removed cancel for " + actItemx);
                popup.remove(itemSelectx); // So upon right-click on Item 1, you won't see "Cancel" menu.
            }

                popup.show(inv.this, e.getX(), e.getY());
                popup.revalidate();
            }
        }
    }

    private int getRow(Point point)
    {
        return listbox.locationToIndex(point);
    }

    public void mouseEntered(MouseEvent e)
    {
    }

    public void mouseReleased(MouseEvent e)
    {
    }

    public void mousePressed(MouseEvent e)
    {
    }

    public void mouseClicked(MouseEvent e)
    {
    }

    public void mouseExited(MouseEvent e)
    {
    }
}

person test    schedule 02.02.2011    source источник


Ответы (2)


Как насчет настройки разных меню JPopup для каждого типа элемента. Я имею в виду, что у вас есть что-то вроде этого:

public JPopupMenu useDropPopup;
public JPopupMenu useCancelPopup;

public void init() {
   ActionListener menuListener = new ActionListener()
        {
            public void actionPerformed(ActionEvent event)
            {
                String invAction = event.getActionCommand();


                int itemSelect = listbox.getSelectedIndex();
                Object actItem = listbox.getModel().getElementAt(itemSelect);

                System.out.println("Popup menu item [" + invAction + "] [ " + actItem + " ] was pressed.");
            }
        };

   useDropPopup = new JPopupMenu();
   useCancelPopup = new JPopupMenu();

   JMenuItem useMenuItem = new JMenuItem("Use");
   useMenuItem.addActionListener(menuListener);
   JMenuItem dropMenuItem = new JMenuItem("Drop");
   dropMenuItem.addActionListener(menuListener);
   JMenuItem cancelMenuItem = new JMenuItem("Cancel");
   cancelMenuItem.addActionListener(menuListener);

   useDropPopup.add(useMenuItem);
   useDropPopup.add(dropMenuItem);

   useCancelPopup.add(useMenuItem);
   useCancelPopup.add(cancelMenuItem);

   // ... etc bring up the appropriate popup depending on the item.
}

Кроме того, вы не должны назначать JMenuItem элементу внутри вызова метода. Это плохая практика. Также рассмотрите возможность использования разных прослушивателей действий для каждого пункта меню, чтобы вы могли разделить функциональный код каждого пункта меню, например:

useMenuItem.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent event) {
      useMenuAction(event);
   }
};

// ... after the init method

public void useMenuAction(ActionEvent evt) {
   // Add specific use menu code here.
}
person jluzwick    schedule 02.02.2011

В основном это дополнение к ответу jluzwick:

Вместо того, чтобы создавать JMenuItem и добавлять к нему ActionListener, вы можете использовать Action — это в основном комбинация ActionListener с именем, опционально Icon и некоторыми другими свойствами. (Большинство просто расширяются от AbstractAction, переопределяя actionPerformed-Method.)

Затем добавьте Action в свой JMenu, и он создаст сам JMenuItem. (Вы также можете использовать тот же объект Action в других местах, таких как кнопки, «обычная» строка меню и т. д.)

person Paŭlo Ebermann    schedule 02.02.2011