如果单击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);
......这很有效。但我不喜欢它。还有更好的方法吗?
答案 0 :(得分:11)
在此处查看示例“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;
}
}
});
答案 1 :(得分:4)
这个怎么样?
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)单击工作。我确定它可以修复,但我假设你问这个单选列表...如果不修改你的问题,我们就可以开始考虑多选问题的解决方案了。
答案 2 :(得分:3)
我知道这个问题已经有了一个公认的答案,但我认为我会扩大一点,因为我最终坚持这个任务几个小时。
我正在尝试为所选项目实施点击取消选择操作,但我的列表实现需要使用单一选择模式,由
指定JList jlist = new JList(new DefaultListModel());
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
不幸的是,这导致针对许多SO问题的点击取消选择问题的许多解决方案的例外和冗余调用,包括this answer上面的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'answer解决了这个问题,但是当在所选项目上拖动鼠标时仍然会显得很奇怪(所选项目将在拖动鼠标时反复选择并取消选择) 。这似乎不是一个问题,但(显然)我有一个颤抖的手,点击时轻微的鼠标移动导致不必要的行为。我合并了Sawas Dalkitsis answer和FuryComptuers的answer以获取以下代码,该代码似乎可以正常工作:
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
进行检查,因此如果在这种情况下实施,请谨慎使用。
答案 3 :(得分:0)
您可以始终使用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文件的上述链接中,有一个实现可以很容易地进行“取消选择”:)
答案 4 :(得分:0)
我延长了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;
}
}
}
答案 5 :(得分:0)
Nick Dandoulakis' answer在按下 Shift 的同时使用鼠标单击一次选择多个项目时,对我来说不起作用。
以下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();
}
}