如果我理解这个问题...
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JListToggleLogicTest {
private final ClearSelectionListener listener = new ClearSelectionListener();
public JComponent makeUI() {
JList<String> list = new JList<String>(makeModel()) {
@Override public void setSelectionInterval(int anchor, int lead) {
if(anchor==lead && lead>=0 && anchor>=0) {
if(listener.isDragging) {
addSelectionInterval(anchor, anchor);
} else if(!listener.isCellInsideDragging) {
if(isSelectedIndex(anchor)) {
removeSelectionInterval(anchor, anchor);
} else {
addSelectionInterval(anchor, anchor);
}
listener.isCellInsideDragging = true;
}
} else {
super.setSelectionInterval(anchor, lead);
}
}
};
list.setCellRenderer(new CheckBoxCellRenderer());
list.addMouseListener(listener);
list.addMouseMotionListener(listener);
JPanel p = new JPanel(new GridLayout(1,2));
p.add(makeTitledPanel("Default", new JList<String>(makeModel())));
p.add(makeTitledPanel("SelectionInterval", list));
return p;
}
private static DefaultListModel<String> makeModel() {
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("aaaaaaa");
model.addElement("bbbbbbbbbbbbb");
model.addElement("cccccccccc");
model.addElement("ddddddddd");
model.addElement("eeeeeeeeee");
return model;
}
private static JComponent makeTitledPanel(String title, JComponent c) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
p.add(new JScrollPane(c));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new JListToggleLogicTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ClearSelectionListener extends MouseAdapter {
private static void clearSelectionAndFocus(JList list) {
list.getSelectionModel().clearSelection();
list.getSelectionModel().setAnchorSelectionIndex(-1);
list.getSelectionModel().setLeadSelectionIndex(-1);
}
private static boolean contains(JList list, Point pt) {
for(int i=0; i<list.getModel().getSize(); i++) {
Rectangle r = list.getCellBounds(i, i);
if(r.contains(pt)) return true;
}
return false;
}
private boolean startOutside = false;
private int startIndex = -1;
public boolean isDragging = false;
public boolean isCellInsideDragging = false;
@Override public void mousePressed(MouseEvent e) {
JList list = (JList)e.getSource();
startOutside = !contains(list, e.getPoint());
startIndex = list.locationToIndex(e.getPoint());
if(startOutside) {
clearSelectionAndFocus(list);
}
}
@Override public void mouseReleased(MouseEvent e) {
startOutside = false;
isDragging = false;
isCellInsideDragging = false;
startIndex = -1;
}
@Override public void mouseDragged(MouseEvent e) {
JList list = (JList)e.getSource();
if(!isDragging && startIndex == list.locationToIndex(e.getPoint())) {
isCellInsideDragging = true;
} else {
isDragging = true;
isCellInsideDragging = false;
}
if(contains(list, e.getPoint())) {
startOutside = false;
isDragging = true; //add:2012-06-01
} else if(startOutside) {
clearSelectionAndFocus(list);
}
}
}
class CheckBoxCellRenderer extends JCheckBox implements ListCellRenderer<String> {
@Override public Component getListCellRendererComponent(
JList<? extends String> list, String value, int index,
boolean isSelected, boolean cellHasFocus) {
setOpaque(true);
if(isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
setSelected(true);
}else{
setBackground(list.getBackground());
setForeground(list.getForeground());
setSelected(false);
}
setText(value);
return this;
}
}