JList 右键单击显示菜单(使用、删除、取消)
Posted
技术标签:
【中文标题】JList 右键单击显示菜单(使用、删除、取消)【英文标题】:JList Right-click shows menu (Use, drop, cancel) 【发布时间】: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)
【问题讨论】:
【参考方案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
。应该有更有效的方法,但如果你的列表很短,应该就足够了。
【讨论】:
以上是关于JList 右键单击显示菜单(使用、删除、取消)的主要内容,如果未能解决你的问题,请参考以下文章
右键单击以选择 Datagridview 中的一行并显示一个菜单以将其删除