比如下面这个tabel(第一列是boolean,tabel会自动将绘制器和编辑器设置为checkbox)
我想让第一列实现动态的灰化,也就是让里面的checkbox.setEnable(false);
比如用两个按钮来控制,一个灰化按钮,一个亮化按钮
点击灰化按钮,第一列就不可编辑,点击亮化按钮,第一列变为可编辑jTable1 = new javax.swing.JTable();jTable1.setModel(new javax.swing.table.DefaultTableModel(
    new Object [][] {
        {null, null, null},
        {null, null, null},
        {null, null, null},
        {null, null, null}
    },
    new String [] {
        "选择", "用户名", "密码"
    }
) {
    Class[] types = new Class [] {
        java.lang.Boolean.class, java.lang.String.class, java.lang.String.class
    };    public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
    }
});

解决方案 »

  1.   

    覆写 isCellEditable 方法,在按钮点击后修改model里面的数据,例如第一行按钮点击后,把第一行的Boolean值改为true,在isCellEditable中按行返回Boolean值,table在重新setModel一下。你的model拿出来单独写一个类。
      

  2.   


    isCellEditable只是不可编辑,但单元格里checkbox还是亮化的,
    我需要让checkbox灰化,也就是调用它的setEnable方法,
    是不是应该着手修改Renderer和Editor,而不是model:我的想法是表格初始化完毕后,拿到表格这一列的Renderer和Editor,
    然后通过Renderer和Editor获取到单元格内的组件getTableCellEditorComponent,并设置它setEnabled
    这样就能保持原有表格的Renderer和Editor,而我只是改变了组件的Enabled属性下面是我的实现,效果做到了,只不过代码太恶心了,我一定相信有更好的办法
    有谁用过知道吗?
    // 主类
        private final TableCellRenderer oldR;
        private final TableCellEditor oldE;
        private final TableModel oldM;    public MainFrame() {
            initComponents();
            // 表格初始化后,获取表格的m、v、c
            oldR = jTable1.getCellRenderer(0, 0);
            oldE = jTable1.getCellEditor(0, 0);
            oldM = jTable1.getModel();
        }
    // 新建一个model,包含老的model
    public class MyTableModel implements TableModel {
        private boolean isCellEditable;
        private TableModel old;    public MyTableModel(boolean isCellEditable,TableModel old) {
            this.old = old;
            this.isCellEditable = isCellEditable;
        }    @Override
        public int getRowCount() {
            return old.getRowCount();
        }    @Override
        public int getColumnCount() {
            return old.getColumnCount();
        }   // ...省略的其他方法都是通过old来调用    @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            if (!isCellEditable && columnIndex == 0) {
                return false;
            }
            return true;
        }
    }// 新建一个renderer,包含老的renderer
    public class MyTableCellRenderer implements TableCellRenderer {
        private boolean isEnable;
        private TableCellRenderer old;
        public MyTableCellRenderer(boolean isEnable,TableCellRenderer old) {
            this.isEnable = isEnable;
            this.old = old;
        }
        
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = old.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            c.setEnabled(isEnable);
            return c;
        }
    }
    // 新建一个editor,包含老的editor
    public class MyTableCellEditor implements TableCellEditor {
        private TableCellEditor old;
        private boolean isCellEditable;    public MyTableCellEditor(boolean isCellEditable,TableCellEditor old) {
            this.isCellEditable = isCellEditable;
            this.old = old;
        }    @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            Component c = old.getTableCellEditorComponent(table, value, isSelected, row, column);
            c.setEnabled(isCellEditable);
            return c;
        }    @Override
        public boolean isCellEditable(EventObject anEvent) {
            return isCellEditable;
        }    @Override
        public Object getCellEditorValue() {
            return old.getCellEditorValue();
        }   // ...省略的其他方法都是通过old来调用
    }// 两个测试按钮,用来灰化、亮化第一列的checkbox
        private void setDisableBtnActionPerformed(java.awt.event.ActionEvent evt) {                                             
            // TODO add your handling code here:
            jTable1.setModel(new MyTableModel(false, oldM));
            jTable1.getColumnModel().getColumn(0).setCellRenderer(new MyTableCellRenderer(false, oldR));
            jTable1.getColumnModel().getColumn(0).setCellEditor(new MyTableCellEditor(false, oldE));
        }                                                private void setEnableBtnActionPerformed(java.awt.event.ActionEvent evt) {                                              
            // TODO add your handling code here:
            jTable1.setModel(new MyTableModel(true, oldM));
            jTable1.getColumnModel().getColumn(0).setCellRenderer(new MyTableCellRenderer(true, oldR));
            jTable1.getColumnModel().getColumn(0).setCellEditor(new MyTableCellEditor(true, oldE));
        }                                             
      

  3.   

    全部代码,包括测试类代码如下:
    package mine.test;import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JTable;public class TestMain {
    public static void main(String[] args){
    JFrame frame=new JFrame();
    frame.getContentPane().setLayout(new BorderLayout());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MyModel model=new MyModel(5,6);
    final JTable table=new JTable(model);
    table.setDefaultRenderer(Boolean.class, new MyRenderer());
    frame.getContentPane().add(table,BorderLayout.CENTER);

    JButton buttong=new JButton("disable");
    buttong.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    MyModel mode=(MyModel) table.getModel();
    mode.setCheckEnable(false);
    mode.fireTableDataChanged();
    }
    });

    frame.getContentPane().add(buttong,BorderLayout.NORTH);
    frame.pack();
    frame.setVisible(true);
    }
    }package mine.test;import javax.swing.table.DefaultTableModel;public class MyModel extends DefaultTableModel{
    private boolean editable=true;

    public MyModel(int c ,int r){
    super(c,r);
    }
    @Override
    public boolean isCellEditable(int row, int column) {
    // TODO Auto-generated method stub
    //假设checkbox在第一列
    return column==0 ?  editable : super.isCellEditable(row, column);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
    // TODO Auto-generated method stub
    return columnIndex==0? Boolean.class: super.getColumnClass(columnIndex);
    }

    public void setCheckEnable(boolean b){
    this.editable=b;
    }
    }
    package mine.test;import java.awt.Component;import javax.swing.JCheckBox;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.border.Border;
    import javax.swing.border.EmptyBorder;
    import javax.swing.table.TableCellRenderer;public class MyRenderer  extends JCheckBox implements TableCellRenderer{    private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);    public MyRenderer() {
            super();
            setHorizontalAlignment(JLabel.CENTER);
            setBorderPainted(true);
        }    public Component getTableCellRendererComponent(JTable table, Object value,
                                                       boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                super.setBackground(table.getSelectionBackground());
            }
            else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
            }
            setSelected((value != null && ((Boolean)value).booleanValue()));        if (hasFocus) {
                setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
            } else {
                setBorder(noFocusBorder);
            }
            
            setEnabled(table.getModel().isCellEditable(row, column));        return this;
        }}
    renderer那部分因为原来类被保护不能访问,又懒得自己写,所以大部分是考jdk的代码