Question

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);
    }
}
Was it helpful?

Solution

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.

OTHER TIPS

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;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top