[英]ListSelectionEvent, firing an event when clicking the currently selected item in JList
[英]JList - deselect when clicking an already selected item
如果单击JList上的选定索引,我希望它取消选择。 换句话说,点击索引实际上切换了他们的选择。 看起来不支持,所以我试过了
list.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
java.awt.Point point = evt.getPoint();
int index = list.locationToIndex(point);
if (list.isSelectedIndex(index))
list.removeSelectionInterval(index, index);
}
});
这里的问题是在 JList已经对鼠标事件起作用之后调用它,因此它取消选择所有内容。 然后我尝试删除所有JList的MouseListeners,添加我自己的,然后添加所有默认侦听器。 这不起作用,因为在我取消选择后,JList会重新选择索引。 无论如何,我最终想出的是
MouseListener[] mls = list.getMouseListeners();
for (MouseListener ml : mls)
list.removeMouseListener(ml);
list.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
java.awt.Point point = evt.getPoint();
final int index = list.locationToIndex(point);
if (list.isSelectedIndex(index))
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
list.removeSelectionInterval(index, index);
}
});
}
});
for (MouseListener ml : mls)
list.addMouseListener(ml);
......那很有效。 但我不喜欢它。 有没有更好的办法?
在此处查看示例“ListSelectionModel:启用切换选择模式”: http : //java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html
我已经针对多选列表框略微修改了它(将setSelectionInterval更改为addSelectionInterval)并且如果在鼠标停止时单击取消选择并移动鼠标,则消除了重新选择的问题(移动了gestureStarted检查添加和去掉)。
objList.setSelectionModel(new DefaultListSelectionModel() {
private static final long serialVersionUID = 1L;
boolean gestureStarted = false;
@Override
public void setSelectionInterval(int index0, int index1) {
if(!gestureStarted){
if (isSelectedIndex(index0)) {
super.removeSelectionInterval(index0, index1);
} else {
super.addSelectionInterval(index0, index1);
}
}
gestureStarted = true;
}
@Override
public void setValueIsAdjusting(boolean isAdjusting) {
if (isAdjusting == false) {
gestureStarted = false;
}
}
});
这个怎么样?
import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
public class A {
public static void main(String[] args) {
JFrame f = new JFrame("Test");
final JList list = new JList(new String[] {"one","two","three","four"});
list.setSelectionModel(new DefaultListSelectionModel(){
@Override
public void setSelectionInterval(int index0, int index1) {
if (index0==index1) {
if (isSelectedIndex(index0)) {
removeSelectionInterval(index0, index0);
return;
}
}
super.setSelectionInterval(index0, index1);
}
@Override
public void addSelectionInterval(int index0, int index1) {
if (index0==index1) {
if (isSelectedIndex(index0)) {
removeSelectionInterval(index0, index0);
return;
}
super.addSelectionInterval(index0, index1);
}
}
});
f.getContentPane().add(list);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
它有效,但注意一个副作用...例如,如果你将模式设置为多重选择,例如:
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION );
您无法通过鼠标拖动选择多个对象。 Ctrl(或shift)单击工作。 我确定它可以修复,但我假设你问这个单选列表...如果不修改你的问题,我们就可以开始考虑多选问题的解决方案了。
我知道这个问题已经有了一个可接受的答案,但我认为我会扩展一点,因为我最终坚持这个任务几个小时。
我试图对所选项目实施点击取消选择操作,但我的列表实现需要使用单选模式,由
JList jlist = new JList(new DefaultListModel());
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
不幸的是,这导致许多SO问题上的点击取消选择问题的许多解决方案的异常和冗余调用,包括上面的FuryComptuers的 这个答案 。 由于DefaultListSelectionModel.class
代码,特别是在addSelectionInterval(int index0, int index1)
和removeSelectionInterval(int index0, int index1)
方法中,这些方法调用回setSelectionInterval(int index0, int index1)
方法,导致循环调用导致(显然)例外。 这个“问题”代码可以在下面看到。
// If we only allow a single selection, channel through
// setSelectionInterval() to enforce the rule.
if (getSelectionMode() == SINGLE_SELECTION) {
setSelectionInterval(index0, index1);
return;
}
Sawas Dalkitsis的回答解决了这个问题,但是当在所选项目上拖动鼠标时仍然会很奇怪(所选项目将在拖动鼠标时反复选择和取消选择)。 这似乎不是一个问题,但(显然)我有一个颤抖的手,点击时轻微的鼠标移动导致不必要的行为。 我结合了Sawas Dalkitsis的 回答和FuryComptuers的回答来获得以下代码,这似乎符合要求:
JList jlist = new JList(new DefaultListModel());
jList.setSelectionModel(new DefaultListSelectionModel() {
private static final long serialVersionUID = 1L;
boolean gestureStarted = false;
@Override
public void setSelectionInterval(int index0, int index1) {
if(!gestureStarted){
if (index0==index1) {
if (isSelectedIndex(index0)) {
removeSelectionInterval(index0, index0);
return;
}
}
super.setSelectionInterval(index0, index1);
}
gestureStarted = true;
}
@Override
public void addSelectionInterval(int index0, int index1) {
if (index0==index1) {
if (isSelectedIndex(index0)) {
removeSelectionInterval(index0, index0);
return;
}
super.addSelectionInterval(index0, index1);
}
}
@Override
public void setValueIsAdjusting(boolean isAdjusting) {
if (isAdjusting == false) {
gestureStarted = false;
}
}
});
jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
注意:我没有像Sawas Dalkitsis那样针对ListSelectionModel.SINGLE_INTERVAL_SELECTION
检查,因此如果在这种情况下实现它,请谨慎使用。
我扩展了FuryComptuers的答案以支持多项选择,并修复了如果直接调用setSelectionInterval
不起作用的问题。
public class ToggleableListSelectionModel extends DefaultListSelectionModel {
private static final long serialVersionUID = 1L;
private boolean mGestureStarted;
@Override
public void setSelectionInterval(int index0, int index1) {
// Toggle only one element while the user is dragging the mouse
if (!mGestureStarted) {
if (isSelectedIndex(index0)) {
super.removeSelectionInterval(index0, index1);
} else {
if (getSelectionMode() == SINGLE_SELECTION) {
super.setSelectionInterval(index0, index1);
} else {
super.addSelectionInterval(index0, index1);
}
}
}
// Disable toggling till the adjusting is over, or keep it
// enabled in case setSelectionInterval was called directly.
mGestureStarted = getValueIsAdjusting();
}
@Override
public void setValueIsAdjusting(boolean isAdjusting) {
super.setValueIsAdjusting(isAdjusting);
if (isAdjusting == false) {
// Enable toggling
mGestureStarted = false;
}
}
}
您可以始终使用ListSelectionListener而不是解密单击的点,然后将其转换为所选项。
http://java.sun.com/docs/books/tutorial/uiswing/examples/events/index.html#ListSelectionDemo
http://java.sun.com/docs/books/tutorial/uiswing/events/listselectionlistener.html
在上面的java文件链接中有一个实现,可以很容易地改进来做“取消选择”:)
当按下Shift键的同时使用鼠标点击一次选择多个项目时, Nick Dandoulakis的回答对我来说并不适用。
以下ListSelectionModel
在使用带有Shift或Ctrl的鼠标点击选择项目时的行为与我期望的一样。
此外,按住Shift + Ctrl并按→或←按照我想要的方式选择项目。
public static class ToggleableListSelectionModel extends DefaultListSelectionModel {
private static final long serialVersionUID = 1L;
@Override
public void setSelectionInterval(int startIndex, int endIndex) {
if (startIndex == endIndex) {
if (multipleItemsAreCurrentlySelected()) {
clearSelection();
}
if (isSelectedIndex(startIndex)) {
clearSelection();
}
else {
super.setSelectionInterval(startIndex, endIndex);
}
}
// User selected multiple items
else {
super.setSelectionInterval(startIndex, endIndex);
}
}
private boolean multipleItemsCurrentlyAreSelected() {
return getMinSelectionIndex() != getMaxSelectionIndex();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.