java – JTable中的单选按钮无法正常工作

我有以下代码的问题.我的任务是,我必须在第一列中有单选按钮,当用户选择该单选按钮时,该行被选中并被发送以进行处理.但我的问题是,我能够选择第一列中的单选按钮,但之后当用户点击表格的任何部分时,我的单击单选按钮将被取消选中.我无法想象,为什么会发生这种情况.我真的很困惑这个问题.需要帮助.以下代码显示了我的问题.

import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class DisplayTable extends JDialog {
public void initialize() {
    SourceTableModel stm = new SourceTableModel();
    JTable sourceTable = new JTable(stm);

    sourceTable.getColumnModel().getColumn(0).setCellRenderer(new RadioButtonRenderer());
    sourceTable.getColumnModel().getColumn(0).setCellEditor(new RadioButtonEditor(new JCheckBox ()));

    JPanel panel = new JPanel();
    panel.add(new JScrollPane(sourceTable));
    add(panel);

    setModal(true);
    pack();
    setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new DisplayTable().initialize();
        }
    });
}
}


class SourceTableModel extends AbstractTableModel{

private static final long serialVersionUID = 1L;

private List<SourceModel> sourceList = new ArrayList<SourceModel>(); 
private String[] columnNamesList = {"Select", "Group", "Work"};

public SourceTableModel() {
    this.sourceList = getSourceDOList();
}

public String getColumnName(int column) {
    return columnNamesList[column];
}

public int getRowCount() {
    return sourceList.size();
}

public int getColumnCount() {
    return columnNamesList.length;
}

public Class<?> getColumnClass(int columnIndex) {
    return (columnIndex == 0 ? Boolean.class : String.class);
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
    return (columnIndex == 0 ? true : false);
}

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    SourceModel model = (SourceModel) sourceList.get(rowIndex);
    switch (columnIndex) {
    case 0: 
        model.setSelect((Boolean)aValue);
        break;
    case 1: 
        model.setFactory((String) aValue);
        break;
    case 2: 
        model.setSupplier((String) aValue);
        break;
    }
    fireTableCellUpdated(rowIndex, columnIndex);
}


public Object getValueAt(int rowIndex, int columnIndex) {
    SourceModel source = sourceList.get(rowIndex);
    switch(columnIndex){
    case 0:
        return source.isSelect();
    case 1:
        return source.getFactory();
    case 2:
        return source.getSupplier();
    default:
        return null;
    }
}

private List<SourceModel> getSourceDOList() {
    List<SourceModel> tempSourceList=new ArrayList<SourceModel>();
    for (int index = 0; index < 5; index++) {

        SourceModel source = new SourceModel();
        source.setSelect(false);
        source.setFactory("group");
        source.setSupplier("Work");

        tempSourceList.add(source);
    }
    return tempSourceList;
}
}


class SourceModel {

private boolean select;
private String factory;
private String supplier;

public SourceModel() {
    // No Code;
}

public SourceModel(boolean select, String factory, String supplier) {
    super();
    this.select = select;
    this.factory = factory;
    this.supplier = supplier;
}

public boolean isSelect() {
    return select;
}

public void setSelect(boolean select) {
    this.select = select;
}

public String getFactory() {
    return factory;
}

public void setFactory(String factory) {
    this.factory = factory;
}

public String getSupplier() {
    return supplier;
}

public void setSupplier(String supplier) {
    this.supplier = supplier;
}
}

class RadioButtonEditor extends DefaultCellEditor implements ItemListener {

public JRadioButton btn = new JRadioButton();

public RadioButtonEditor(JCheckBox checkBox) {
    super(checkBox);
}

public Component getTableCellEditorComponent(JTable table, Object 
value, boolean isSelected, int row, int column) {

if (value==null) 
          return null;
btn.addItemListener(this);
if (( (Boolean) value).booleanValue())
    btn.setSelected(true);
else
    btn.setSelected(false);

    return btn;
}

public Object getCellEditorValue() {
    if(btn.isSelected() == true)
        return new Boolean(true);
    else 
        return new Boolean(false);
}

public void itemStateChanged(ItemEvent e) {
    super.fireEditingStopped();
}
}

class RadioButtonRenderer implements TableCellRenderer {
  public JRadioButton btn = new JRadioButton();
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
      if (value==null) return null;

      if(((Boolean)value).booleanValue())
      btn.setSelected(true);
      else
      btn.setSelected(false);

      if (isSelected) {
      btn.setForeground(table.getSelectionForeground());
      btn.setBackground(table.getSelectionBackground());
      } else {
      btn.setForeground(table.getForeground());
      btn.setBackground(table.getBackground());
      } 
      return btn;

  }
}

编辑:
我已经更新了我的代码,我在第一列使用了布尔类.我面临的问题是,如果我删除super.fireEditingStopped();从RadioButtonEditor类然后我能够检查然后如果我点击表的任何部分然后检查一个我未选中.如果我保留super.fireEditingStopped();然后我甚至无法检查单选按钮.

我知道super.fireEditingStopped();将停止编辑.但我的问题是如何检查它?

P.S:对不起,我已经发布了我的整个代码.我认为一个人很容易看到这个问题.

这是该程序的屏幕截图.

解决方法:

从您的插图中可以看出,您希望在JTable的行之间强制互斥,其中每行都有一个JRadioButton.由于ButtonGroup不合适,因此@Jillaume Polet使用的这个example使用自定义管理器.

上一篇:java – 用于过滤/搜索的Swing JTable自定义


下一篇:java – 如何将图像渲染到JTable单元格