java - JCheckBox 的问题在 Java 的 JList 中检查了切换逻辑

标签 java swing jlist jcheckbox listcellrenderer

您好,我在切换 JList 中的复选框时遇到问题,我希望当单击某个项目时复选框会被选中,如果再次被选中,我希望它切换为未选中状态。我希望能够在不使用 ctrl 或 shift 键的情况下勾选或取消勾选多个项目。

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;
    }
}

以下是我尝试向表中添加数据的方式,由于某种原因什么都没有出现,有什么想法吗?

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);
    }
}

最佳答案

如果我理解问题...

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;
  }
}

关于java - JCheckBox 的问题在 Java 的 JList 中检查了切换逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10792974/

相关文章:

java - 如何销毁现有框架窗口的内存空间,同时在命令按钮中调用另一个框架

java安全不允许我使用Jfilechooser打开拍照

java - 将 jlist 选择转换为字符串

java - 从 jpanel 添加/删除 jlabel

Java 编译器目标代码(字节代码?)

java - 装饰设计和工厂设计模式

java - 在 Jlist 中编辑项目

java - 网格袋布局不会填充按钮

java - 重置按钮数组后无法更改java按钮颜色

java - 我有一个包含菜单项属性的类。我需要填充三个 JList。我怎样才能这样做呢?