【问题标题】:JList Right-click shows menu (Use, drop, cancel)JList 右键单击​​显示菜单(使用、删除、取消)
【发布时间】:2011-06-18 18:12:31
【问题描述】:

我一直在网上搜索这个答案。我有一个简单的 JList,里面有项目。当我右键单击时,我希望弹出一个菜单,上面写着“使用、删除、取消”或类似的东西。但是,我被难住了。

下面的代码将生成一个简单的 JList,其中包含一些项目。我尝试在代码中添加右键单击,但它不起作用。帮忙?

这是我目前所拥有的:

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



public class inv extends JApplet implements MouseListener {

    JList listbox;



     public void init()
     {


    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) )
            {
                listbox.setSelectedIndex(getRow(e.getPoint()));
            }
        }
     });

    listbox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);


        add(listbox);
                    listbox.setVisible(true);

            listbox.setFocusable(false);

     }



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

      public void mousePressed(MouseEvent e) {
      }

      public void mouseReleased(MouseEvent e) {
      }

      public void mouseEntered(MouseEvent e) {
      }

      public void mouseExited(MouseEvent e) {
      }

      public void mouseClicked(MouseEvent e) {
      }


     public void stop()
     {
     }

     public void paint(Graphics g)
     {
     }

}

【问题讨论】:

    标签: java swing popup jlist japplet


    【解决方案1】:

    我不明白你的意思。这里的代码似乎与您指定的一样工作,但除了删除任何数量的冗余或错误语句之外,它几乎就是您发布的内容。

    /*
    <applet code='inv' width='200' height='200'>
    </applet>
    */
    import java.awt.*;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseAdapter;
    import javax.swing.*;
    
    public class inv extends JApplet { //implements MouseListener {
    
        JList listbox;
    
         public void init()
         {
    
    
        String  listData[] = { "Item 1","Item 2","Item 3","Item 4" };
    listbox = new JList( listData );
    
         listbox.addMouseListener( new MouseAdapter()
         {
            public void mousePressed(MouseEvent e)
            {
                System.out.println(e);
                if ( SwingUtilities.isRightMouseButton(e) )
                {
                    System.out.println("Row: " + getRow(e.getPoint()));
                    listbox.setSelectedIndex(getRow(e.getPoint()));
                }
            }
         });
    
        listbox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            add(listbox);
                        // unnecessary
                        //listbox.setVisible(true);
    
                listbox.setFocusable(false);
         }
    
    
    
         private int getRow(Point point)
         {
            return listbox.locationToIndex(point);
    }
    
    /** Why implement MouseListener, while adding a MouseAdapter?
    Do you have ANY idea what your doing?
    
          public void mousePressed(MouseEvent e) {
          }
    
          public void mouseReleased(MouseEvent e) {
          }
    
          public void mouseEntered(MouseEvent e) {
          }
    
          public void mouseExited(MouseEvent e) {
          }
    
          public void mouseClicked(MouseEvent e) {
          }
    */
    
        /** What is this nonsense supposed to achieve?
        Don't override empty methods with empty implementations!
         public void stop()
         {
         }
         */
    
        /** What is this nonsense supposed to achieve?
         public void paint(Graphics g)
         {
         }
         */
    }
    

    输出

    java.awt.event.MouseEvent[MOUSE_PRESSED,(31,22),absolute(39,72),button=3,modifiers=Meta+Button3,extModifiers=Button3,clickCount=1] on javax.swing.JList[,0,0,200x200,alignmentX=0.0,alignmentY=0.0,border=,flags=50331944,maximumSize=,minimumSize=,preferredSize=,fixedCellHeight=-1,fixedCellWidth=-1,horizontalScrollIncrement=-1,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],visibleRowCount=8,layoutOrientation=0]
    Row: 1
    java.awt.event.MouseEvent[MOUSE_PRESSED,(29,39),absolute(37,89),button=3,modifiers=Meta+Button3,extModifiers=Button3,clickCount=1] on javax.swing.JList[,0,0,200x200,alignmentX=0.0,alignmentY=0.0,border=,flags=50331944,maximumSize=,minimumSize=,preferredSize=,fixedCellHeight=-1,fixedCellWidth=-1,horizontalScrollIncrement=-1,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],visibleRowCount=8,layoutOrientation=0]
    Row: 2
    java.awt.event.MouseEvent[MOUSE_PRESSED,(36,65),absolute(468,192),button=3,modifiers=Meta+Button3,extModifiers=Button3,clickCount=1] on javax.swing.JList[,0,0,200x200,alignmentX=0.0,alignmentY=0.0,border=,flags=50331944,maximumSize=,minimumSize=,preferredSize=,fixedCellHeight=-1,fixedCellWidth=-1,horizontalScrollIncrement=-1,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],visibleRowCount=8,layoutOrientation=0]
    Row: 3
    java.awt.event.MouseEvent[MOUSE_PRESSED,(45,11),absolute(477,138),button=3,modifiers=Meta+Button3,extModifiers=Button3,clickCount=1] on javax.swing.JList[,0,0,200x200,alignmentX=0.0,alignmentY=0.0,border=,flags=50331944,maximumSize=,minimumSize=,preferredSize=,fixedCellHeight=-1,fixedCellWidth=-1,horizontalScrollIncrement=-1,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],visibleRowCount=8,layoutOrientation=0]
    Row: 0
    
    Tool completed successfully
    

    【讨论】:

    • 对不起我的所有废话。这就是我被教导的方式。 (高中班)
    【解决方案2】:

    一个典型的错误可能是打电话给JPopupMenu.setVisible(true) 并期望会发生一些事情。该组件需要不同的方法来启动它。重写你的鼠标监听器:

        listbox.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    JPopupMenu menu = new JPopupMenu();
                    JMenuItem item = new JMenuItem("Say hello");
                    item.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            JOptionPane.showMessageDialog(inv.this, "Hello "
                                    + listbox.getSelectedValue());
                        }
                    });
                    menu.add(item);
                    menu.show(inv.this, 5, listbox.getCellBounds(
                            listbox.getSelectedIndex() + 1,
                            listbox.getSelectedIndex() + 1).y);
                }
            }
        });
    

    为了简短起见,我只添加了一项,但肯定可以添加更多。我使用的 show 方法还需要指定菜单应该出现在组件上的哪个位置。如本例所示,可以从列表本身获取位置。

    【讨论】:

    • not to se answer by @kleopatra,逻辑相同,JOptionPane 应该在 invokeLater 中延迟(不重要)
    • 否,因为仅在从非 Swing 线程调用 Swing 对象的方法时才需要 invokeLater 包装方法。在我们的例子中 addActionListener 已经在 Swing 线程中被调用了。
    • 当试图在列表中的最后一项上弹出菜单时,此代码会引发异常。 listbox.getSelectedIndex() + 1 在这种情况下是指一个不存在的列表元素。
    【解决方案3】:

    根据前面的答案,下面的代码将立即选择项目(右键单击),并在鼠标单击旁边显示弹出窗口。

    listbox.addMouseListener( new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            if ( SwingUtilities.isRightMouseButton(e) ) {      
               listbox.setSelectedIndex(listbox.locationToIndex(e.getPoint()));
    
                JPopupMenu menu = new JPopupMenu();
                JMenuItem itemRemove = new JMenuItem("Remove");
                itemRemove.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
    
                        // This could probably be improved, but assuming you
                        // also keep the values in an ArrayList, you can 
                        // remove the element with this:
                        //array_list.remove(listbox.getSelectedValue());
                        //listbox.setListData((String[]) array_list.toArray(new String[array_list.size()]));
    
                        System.out.println("Remove the element in position " + listbox.getSelectedValue());
    
                    }
                });
                menu.add(itemRemove);
                menu.show(listbox, e.getPoint().x, e.getPoint().y);            
            }
        }
    });
    

    有一个注释部分显示了删除该项目的可能方法;它假定存在一个ArrayList(称为array_list),其中包含JList 上元素的副本。它使用方法to_array 来刷新JList。应该有更有效的方法,但如果你的列表很短,应该就足够了。

    【讨论】:

      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 2010-09-21
      • 2017-12-02
      • 2019-05-08
      相关资源
      最近更新 更多