问题
Hi I am having trouble with toggling a check box that is in a JList, I wish for when an item is clicked to have the check box tick, and if it is ticked again i want it to toggle to unticked. I want to have it possible to have multiple items to be ticked or unticked without the use of the ctrl or shift keys.
public class CustCellRenderer extends JCheckBox
implements ListCellRenderer
{
boolean selected = false;
void CustCellRenderer()
{
setOpaque(true);
setIconTextGap(12);
}
// allows a custom list cell rendering which will enable me to display an icon as well as filename
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
JCheckBox checkBox = (JCheckBox)value;
if (isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
if (!selected)
{
selected = true;
setSelected(selected);
}
else
{
selected = false;
setSelected(selected);
}
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
setSelected(selected);
}
setText(checkBox.getText());
return this;
}
}
Here is how I am trying to add data to the table, nothing appears for some reason, any thoughts?
public void addDirectoryLabelsToList()
{
// clears all the previous labels from the listModel to ensure only labels
// that refelect the current directory are shown
for (int x = 0; x < tableModel.getRowCount(); x++)
tableModel.removeRow(x);
// iterate through the dirLabels and add them to the listModel
for (JCheckBox j : dirLabels)
{
Vector<Object> obj = new Vector<>();
obj.add(Boolean.FALSE);
obj.add(j.getText());
tableModel.addRow(obj);
}
}
回答1:
JList
allows custom renderers, but you'll need a custom editor, too. As an alternative, consider a JTable
having a Boolean.class
column, illustrated here.
Addendum: I have altered my question, please check.
I'm not sure where things are going awry, but I suspect your model's getColumnClass()
method does not return Boolean.class
for the relevant column. You might compare your implementation with this related example and post an sscce.
回答2:
If I understand the question...
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;
}
}
来源:https://stackoverflow.com/questions/10792974/trouble-with-jcheckbox-checked-toggle-logic-in-a-jlist-in-java