如何覆盖 JPopupMenu 方法显示?

How to override the JPopupMenu method show?

我的目标是在右键单击后突出显示 jlist 项目,然后显示 jpopupmenu.. 我读到的建议是重写方法 show 是 .. 在我的例子中,我在 class

的开头声明了我的 jpopupmenu
     JPopupMenu popupMenu = new JPopupMenu();
     JMenuItem masterlist,settings;

然后我有一个方法来设置我的 menuItems

    public void setPopupMenu(int depth//ignore this var){
    //popupMenu = new JPopupMenu();
    popupMenu.removeAll();

        masterlist = new JMenuItem("Masterlist");
        settings = new JMenuItem("Settings");

        //action for marsterlist
        masterlist.addActionListener(new ActionListener(){
            //stuff here
            }
        });
        //action for settings
        settings.addActionListener(new ActionListener(){
            //stuff here
            }
        });

        popupMenu.add(masterlist);
        popupMenu.add(settings);
 }

我的列表采用不同的方法

list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.setVisibleRowCount(-1);
list.setComponentPopupMenu(popupMenu);

我尝试将它放在列表的鼠标适配器上,但弹出菜单首先触发并忽略突出显示...

   if ( SwingUtilities.isRightMouseButton(mouseEvent) )//highlight the right clicked item
                 {

                    int row = list.locationToIndex(mouseEvent.getPoint());
                    list.setSelectedIndex(row); 
                    String val = (String)list.getSelectedValue();
                    System.out.println(val);
                 }

我知道覆盖是这样的

  popupmenu = new JPopupMenu(){
  @Override
  public void show(){}
  }

但我不能那样做,因为我在一个方法上操纵菜单项... 或者有没有任何人可以建议的任何其他方法...

与其尝试修改 JPopupMenu 的状态,不如在检测到右键单击时简单地修改菜单项的状态...

所以,基本上,我利用 Actions APIJPopupMenu 定义一个菜单项,这允许它向基础 JList 注册一个 ListSelectionListener ]...

public class ShowItemAction extends AbstractAction {

    private JList list;

    public ShowItemAction(JList list) {
        this.list = new JList();
        putValue(NAME, "Showing ...");

        list.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                    int index = list.getSelectedIndex();
                    String value = list.getSelectedValue().toString();
                    putValue(NAME, "Showing " + value + " @ " + index);
                }
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // The actual action to be performed when selected
    }

}

All this does is, when the selection is changed, is change the text (NAME) of the action, which changes the text of the menu item, based on the currently selected row.

当我创建JList时,我通过setComponentPopupMenu方法给它分配了一个JPopupMenu,这意味着我不再需要关心它,它会根据它适当地显示关于当前的外观要求

JList list = new JList(model);
JPopupMenu popupMenu = new JPopupMenu();
popupMenu.add(new ShowItemAction(list));
list.setComponentPopupMenu(popupMenu);

然后我将 MouseListener 添加到 JList,当您右键单击 JList...

时,我用它来更改行选择
list.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        JList list = (JList)e.getComponent();
        if (SwingUtilities.isRightMouseButton(e)) {
            int row = list.locationToIndex(e.getPoint());
            list.setSelectedIndex(row);
        }
    }
});

这不是万无一失的,就好像你在弹出窗口可见时右键单击 JListMouseListener 似乎没有收到通知:P

可运行示例...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                DefaultListModel model = new DefaultListModel();
                model.addElement("One");
                model.addElement("Two");
                model.addElement("Three");
                model.addElement("Four");
                JList list = new JList(model);
                JPopupMenu popupMenu = new JPopupMenu();
                popupMenu.add(new ShowItemAction(list));
                list.setComponentPopupMenu(popupMenu);

                list.addMouseListener(new MouseAdapter() {

                    @Override
                    public void mousePressed(MouseEvent e) {
                        if (SwingUtilities.isRightMouseButton(e)) {
                            int row = list.locationToIndex(e.getPoint());
                            list.setSelectedIndex(row);
                        }
                    }

                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(list));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ShowItemAction extends AbstractAction {

        private JList list;

        public ShowItemAction(JList list) {
            this.list = new JList();
            putValue(NAME, "Showing ...");

            list.addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    if (!e.getValueIsAdjusting()) {
                        int index = list.getSelectedIndex();
                        String value = list.getSelectedValue().toString();
                        putValue(NAME, "Showing " + value + " @ " + index);
                    }
                }
            });
        }

        @Override
        public void actionPerformed(ActionEvent e) {
        }

    }

}