要实现的功能,在table的cell中顺序放如对象,每个cell中都是放相同的对象,对象中有一个字段属性是boolean型,希望通过checkbox的选中状态来表示次对象是否被选中,后台接收所有这些对象,再根据boolean值来决定此对象是否加到列表中.cell中的checkbox能否如frame中checkbox一样,点击一次为选中,再点击为取消选中??我选中能做到有显示,但是在点击的时候如果cell能编辑,而cell中的checkbox却不能选中,即,cell中的checkbox不响应事件?那我要把事件响应的代码加到哪里呢?在table上?CellRender?CellEditor?还是都加?代码如下:
//**********************TableModel***********************************//
class CheckBoxTableModel extends AbstractTableModel {
private Object [][]array;
public void setArray(Object [][]array){
this.array = array;
}
public CheckBoxTableModel(){
super();
}
//行数根据数据的list长度来确定
private int getRow(int size){
int row = 0;
if(size<=1)return row = 1;
if(size>1){
if(size%4==0){
row = size/4;
}else{
row = (size/4)+1;
}
}
return row;
}
public int getColumnCount() {
//列数固定为每行四列
return 4;
} public int getRowCount() {
return array.length;
}
public Object getValueAt(int row, int column) {
return array[row][column];
}
public void setValueAt(Object value,int row,int column){
if(null != value){
                 ((Equipment)array[row][column])
                           .setBoolean(((Boolean)value).booleanValue());
}
}
public Class getColumnClass(int columnIndex){
return Boolean.class;
}
//cell是否能编辑,如果cell中的数据不为空,则可编辑,否则不能编辑
public boolean isCellEditable(int row, int column){
if(null != getValueAt(row,column)){
return true;
}else{
return false;
}
}
}
//******************Table,CellRenderer和CellEditor**********************//
public class CheckBoxTable extends JTable implements TableModelListener{
public CheckBoxTable(Object[][] array,String[]columnName){
super(array,columnName);
initCheckBoxTable();
}
private void initCheckBoxTable() {
this.setCellSelectionEnabled(true);
this.setCellEditor(getCellEditor());
this.setDefaultRenderer(Boolean.class, new CheckBoxRenderer());
this.setUI(new BasicTableUI());
this.setRowHeight(22);
}
//getCelleditor,是用DefaultCellEditor呢?还是用我自己定义的呢?
public TableCellEditor getCellEditor() {
final JCheckBox checkBox = new JCheckBox();
        return new DefaultCellEditor(checkBox);
    }
//********CellRenderer表示cell的表现外观**************//
        //********作为table的内部类来定义*********************//
class CheckBoxRenderer extends JCheckBox implements 
                                          TableCellRenderer,ItemListener{
private JCheckBox checkBox = new JCheckBox();
public Component getTableCellRendererComponent(JTable table, 
                                      Object value, boolean isSelected,
                                 boolean hasFocus, int row, int column) {

      if(null != value){
                  //将cell中checkbox的text设为Equipment对象的文字//
this.setText(((Equipment)value).toString());                 //cell中checkbox的状态决定于Equipment的boolean属性值
this.setSelected(((Equipment)value).getBoolean());
      }else{
this.setText("");
      }
      return this;
               }
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange()==e.SELECTED){
}else if(e.getStateChange()==e.DESELECTED){
}
}
}


//*******自定义的CellEditor****************************//
      //*******不知道用DefaultCellEditor还是这个自定义的CellEditor******//
class CheckBoxTableCellEditor extends AbstractCellEditor implements TableCellEditor,ActionListener, ItemListener{
Equipment equipment;
final  JCheckBox checkBox;
public CheckBoxTableCellEditor(){
checkBox = new JCheckBox();
}
  public Component getTableCellEditorComponent(JTable table, 
                                     Object value, boolean isSelected, 
                                     int row, int column) {
equipment = (Equipment)value;
equipment.setBoolean(checkBox.isSelected());
checkBox.setText(equipment.toString()); return checkBox;
}
public Object getCellEditorValue() {
        //***********存疑??返回boolean呢还是equipment??*****************//
return equipment;
                  
}
public void setCellEditorValue(Object value){
if(null != value){
equipment.setBoolean(((Boolean)value).booleanValue());
}
}
public boolean stopCellEditing() { 
    fireEditingStopped(); 
    return true;
}
public void cancelCellEditing() { 
   fireEditingCanceled(); 
   }
public void actionPerformed(ActionEvent e) {
stopCellEditing();
}
public void itemStateChanged(ItemEvent e) {
stopCellEditing();
}

}
//*************************整个table的UI******************************//
class CheckBoxListUI extends BasicTableUI implements MouseInputListener{ public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub

} public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub

} public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub

} public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
} public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub

} public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub

} public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub

}

}}
//**********************************************************************//
//*****************Equipment是在外面单独定义的*********************//
public class Euipment{
       private boolean selected;
       private int code;
       private String type;
       private String name;       public Equipment(){
}
//...............setter and getter.....................//
       public boolean getBoolean(){
          return this.selected;
       }
//..........此处省略去其他setter和getter...................//
       public Sting toString(){
           return this.name;
       }
}

解决方案 »

  1.   

    本人对Swing 这套MVC或者称为M-UI模式不熟悉,也是刚接触,所以思路还是比较混乱.所一对于时间响应放在哪没有个概念.所一在CellRenderer,CellEditor和TableUI都加上了事件响应.要是哪为大哥清楚,table中cell的表现模式和编辑模式及这两种之间的转换和关系的话,希望能指点指点小弟!万分感谢!
    主要迷惑点:cell中的checkbox如何独立于cell而响应事件?既能点击选中和取消选中.
               当可编辑的时候,点击cell进入编辑状态,编辑状态的改变如何表现到表现?既看到的
               checkbox的状态为selected或deselected?并且要把这些状态改变返回到后台,既后 
               台的equipment对象的selected属性要保存相应的值??***********table的事件,cell的事件,表现模式Renderer的事件,编辑模式editor的事件******
      

  2.   

    checkbox通过add(new Boolean(true))即可实现
      

  3.   

    在哪加呢?
    响应事件加在哪呢?
    CellRenderer?CellEditor?UI?
      

  4.   

    checkbox.add(new Boolean(true))???
    好象没这个方法吧!?
      

  5.   

    表模型数据
    Vector row = new Vector();
    row.add("0,0");
    row.add("0,1");
    row.add("0,2");
    row.add(new Boolean(true));
      

  6.   

    还是不明白.我现在已经做到了,cell里的checkbox如果没有选中,点击能够显示选中.但是选中的再点击一下却不能取消!?唉!CellRenderer和CellEditor两种状态之间是怎么切换的!?
      

  7.   

    http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#combobox
    http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#editor
      

  8.   

    如果在cell中的数据是单纯的Boolean值的话,就很简单了.但选中放到cell中的数据是一个对象,而要显示的是boolean的值.唉,怎么CSDN的论坛不能贴图呢!?要不把图贴一下,免得解释不清楚.
      

  9.   

    import java.awt.Component;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.EventObject;import javax.swing.AbstractCellEditor;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.event.CellEditorListener;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    public class JTableDemo{
    static JFrame f ;
    static JTable table;
    public static void main(String []args){
    f = new JFrame("Test");
    Container c = f.getContentPane();

    Model m = new Model();
    table = new JTable(m);
    table.setCellEditor(getCellEditor());
    // table.setCellEditor(new CellEditor());
    table.setDefaultRenderer(Boolean.class, new CellRenderer());

    c.add(table);

    f.pack();
    f.setPreferredSize(new Dimension(400,400));
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0);
    }
    });
    }
    public static TableCellEditor getCellEditor(){
    JCheckBox cb = new JCheckBox();
    return new DefaultCellEditor(cb);
    }
    }
    //*****************************CellRenderer********************************//
    class CellRenderer extends JCheckBox implements TableCellRenderer{ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    if(null != value){
    Equipment e = (Equipment)value;
    this.setText(e.toString());
    this.setSelected(e.selected);
    }
    return this;
    }}//*******************************Model***********************************//
    class Model extends AbstractTableModel {
    Equipment e1 = new Equipment("1","GPS",false);

    Equipment e2 = new Equipment("2","CSC",true);
    Equipment e3 = new Equipment("2","ABS",false);
    Equipment e4 = new Equipment("2","GCR",true);

    Object [][]data = {{e1,e2,e3,e4},{new Equipment(),new Equipment(),new Equipment(),new Equipment()}};
    String [] columnName = {"A","B","C","D"}; public int getColumnCount() {
    return columnName.length;
    } public int getRowCount() {
    return data.length;
    } public Object getValueAt(int r, int c) {
    // System.out.println("getValueAt::row:"+r+"::column:"+c);
    // return ((Equipment)data[r][c]).getBoolean();
    return data[r][c];
    }

    public void setValueAt(Object value,int r,int c){
    ((Equipment)data[r][c]).selected = (Boolean)value;
    // System.out.println("setValue:row:"+r+"::column:"+c);
    fireTableCellUpdated(r,c);
    }

    public Class getColumnClass(int c){
    // return Equipment.class;
    return Boolean.class;
    }

    public String getColumnName(int c){
    return columnName[c];
    }

    public boolean isCellEditable(int r,int c){
    return true;
    }}
    //****************************Equipment************************************//
    class Equipment{
    public String id ;
    public String name;
    public boolean selected;
    public Equipment(){
    this.id = "1";
    this.name = "ABS";
    this.selected = false;
    }
    public Equipment(String id,String name,boolean b){
    this.id= id;
    this.name = name;
    this.selected = b;
    }
    public void setId(String id){
    this.id = id;
    }
    public void setName(String name){
    this.name = id;
    }
    public void setBoolean(boolean  b){
    this.selected = b;
    }
    public String getId(){
    return this.id;
    }
    public String getName(){
    return this.name;
    }
    public boolean getBoolean(){
    return this.selected;
    }
    public String toString(){
    return this.name;
    }
    }
    //你用上面的代码运行一下,看看效果,可能更清楚我说的问题吧
      

  10.   

    好象我的想法就是错的?!
    table中只能放简单类型的数据?
    或者只能对应某个字段或属性,而不是一整个对象?!
      

  11.   

    这一块的确是难题,好多高人都不语了. 我也遇到类似情况, 也只是渲染出来了,可没法很好地响应事件。 上述中的确可以用Boolean类型代替JCheckBox,但毕究在响应事件上处理起来太麻烦了。 问题应该是在渲染出来后,还需再编一个CellEditor类吧?     高手解决后能交流吗? QQ:307059755