JList Right-click shows menu (Use, drop, cancel)

15,942

Solution 1

I do not know what you mean. Here is code that seems to work like you specify, but apart from taking out any number of redundant or buggy statements, it is pretty much what you posted.

/*
<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)
     {
     }
     */
}

Output

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

Solution 2

One of the typical mistakes may be to call JPopupMenu.setVisible(true) and expect something to happen. This component needs a different method to bring it up. Rewrite your mouse listener along the lines:

    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);
            }
        }
    });

To make example short, I add one item only but surely more can be added. The show method I use also requires to specify where on the component the menu should appear. The location can be obtained from the list itself as seen in this example.

Solution 3

Based in the previous to answers, the below code would immediately select the item (on right click), and display the pop up next to the mouse click.

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);            
        }
    }
});

There is a commented section that shows a possible way of removing the item; it assumes the existence of an ArrayList (called array_list) that contains a copy of the elements on the JList. It used the method to_array in order to refresh the JList. There should be a more efficient way, but if your list is short, it should be sufficient.

Share:
15,942

Related videos on Youtube

test
Author by

test

I'm a human being. Always learning.

Updated on June 04, 2022

Comments

  • test
    test over 1 year

    I've been scouring the internet for this answer. I have a simple JList with items inside it. When I right-click, I want a menu to pop-up that says "Use, drop, cancel" or something of that nature. HOWEVER, I'm stumped.

    The code below will produce a simple JList with a few items inside. I tried adding a right-click in the code but it doesn't work. Help?

    Here is what I have so far:

    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)
         {
         }
    
    }
    
  • test
    test almost 13 years
    Sorry about all of my nonsense. It's just how I was taught. (highschool class)
  • mKorbel
    mKorbel over 10 years
    not to se answer by @kleopatra, logics is the same, JOptionPane should be delayed in invokeLater (not important)
  • Audrius Meškauskas
    Audrius Meškauskas over 10 years
    No, as invokeLater wrapper method is only required when calling a method on Swing object from non Swing thread. In our case addActionListener will already be called in the Swing thread.
  • Clyde
    Clyde over 10 years
    This code throws an exception when trying to pop up a menu on the last item in the list. listbox.getSelectedIndex() + 1 in that case refers to a non-existent list element.

Related