本帖最后由 amis 于 2010-11-08 16:42:06 编辑

解决方案 »

  1.   


    ....
    JCheckBox cb = (JCheckBox) ce.getComponent();
    cb.setSelected(true);  //
    cb.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
    jCheckBox1ItemStateChanged(evt);
    }
    });
    .....
      

  2.   

    加这个有什么用?cb.setSelected(true);
      

  3.   

    加这个有什么用?cb.setSelected(true);
      

  4.   

    楼主 建议你还是重载DefaultTableModel的setValueAt方法比较好
    jTable1.setModel(new javax.swing.table.DefaultTableModel(
    new Object[][] { { new Boolean("true"), null, null, null },
    { new Boolean("true"), null, null, null }, { new Boolean("true"), null, null, null },
    { new Boolean("true"), null, null, null } }, new String[] { "Title 1",
    "Title 2", "Title 3", "Title 4" }) {
    public void setValueAt(Object value, int row, int col) {
    super.setValueAt(value, row, col);
    if (value instanceof Boolean) {
    if ((Boolean)value) {
    for(int x = 0, y = jTable1.getRowCount(); x < y; x++) {
    System.out.println(jTable1.getValueAt(x, 0));
    }
    System.out.println("----------------------------");
    }
    }
    }
    });
    然后把你给cb加的那个listener去掉
      

  5.   

    其实我的用意就是想对jtable里面的jcheckbox进行监听啊,怎么叫我去掉了呢
      

  6.   

    不要添加ItemListener,改成ActionListenercb.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent arg0) {
                for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
                    System.out.println(jTable1.getValueAt(x, 0));
                }
                System.out.println("----------------------------");
        }}); 
    但是还存在一个问题,就是打印的结果总是落后一步,打印的是上一次的结果。
    因为该监听器总是在celleditor想JTable写入之前调用。
      

  7.   

    终于找到了完美解决方案,修改TableModel的setValueAt方法即可,JCheckBox的监听器也可以去掉了。
    修改后的代码如下:import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;import javax.swing.DefaultCellEditor;
    import javax.swing.JCheckBox;
    import javax.swing.event.ChangeEvent;
    import javax.swing.table.TableColumn;public class AccountMode extends javax.swing.JFrame {
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JTable jTable1;    public AccountMode() {
            initComponents();
        }    private void initComponents() {        jScrollPane1 = new javax.swing.JScrollPane();
            jTable1 = new javax.swing.JTable();        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);        jTable1.setModel(new javax.swing.table.DefaultTableModel(
                    new Object[][] { { new Boolean("true"), null, null, null },
                            { new Boolean("true"), null, null, null },
                            { new Boolean("true"), null, null, null },
                            { new Boolean("true"), null, null, null } },
                    new String[] { "Title 1", "Title 2", "Title 3", "Title 4" }) {
                //***********看这里 看这里 看这里***************************
                public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                    super.setValueAt(aValue, rowIndex, columnIndex);
                    for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
                        System.out.println(jTable1.getValueAt(x, 0));
                    }
                    System.out.println("----------------------------");
                }
            });
            // 将boolean转为jcheckbox
            TableColumn tc = jTable1.getColumnModel().getColumn(0);
            tc.setCellEditor(jTable1.getDefaultEditor(Boolean.class));
            tc.setCellRenderer(jTable1.getDefaultRenderer(Boolean.class));        jScrollPane1.setViewportView(jTable1);
            // 这里是关于布局,可以不看start
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
                    getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(layout.createParallelGroup(
                    javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                    javax.swing.GroupLayout.Alignment.TRAILING,
                    layout.createSequentialGroup()
                            .addContainerGap(15, Short.MAX_VALUE)
                            .addComponent(jScrollPane1,
                                    javax.swing.GroupLayout.PREFERRED_SIZE, 375,
                                    javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addContainerGap()));
            layout.setVerticalGroup(layout.createParallelGroup(
                    javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                    layout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(jScrollPane1,
                                    javax.swing.GroupLayout.PREFERRED_SIZE, 275,
                                    javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addContainerGap(15, Short.MAX_VALUE)));
            // 这里是关于布局,可以不看end
            pack();
        }    public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new AccountMode().setVisible(true);
                }
            });
        }
    }
      

  8.   


    我没有叫你去掉jcheckbox,只是叫你去掉你自己新加的监听方法,
    然后重载系统已经默认存在的监听方法
    这个jcheckbox的事件,直接触发了TableModel的setValueAt()方法
    可以翻译成这样,在你生成了这样一个TableModel后,
    jcheckbox已经有了一个默认存在的ItemListener
    jcheckbox.addItemListener(ItemListener() {
        public void itemStateChanged(ItemEvent evt) {
            ……
            setValueAt();
            ……
        }
    });
    你只要把你自己先实现的代码放到setValueAt();里面,就实现了对jcheckbox的事件监听
    对JDK研究一段时间后,你可以发现很多的东西都是互通的
    不要限死自己的思维,JDK给实现一个目标留下了无数的入口
    你从哪个入口进去都可以,关键是看从哪个入口进去对你来说最方便
      

  9.   

    呵呵。上面的诸位说的都有道理。而且也已经明确指出了问题所在。
    这个监听会在更改model的数据之前被触发。此时的数据,尚未更改,因此,你看起来就好像打印出的数据总是落后一个步骤一样,但是实际上,你所打印的,的确是更改前的数据。不了解你的想法,要在这里做些什么。但是一般很少这样去做这个监听。
    对于表格里面的东西,
    第一,可以如上述各位所言,在model里面setvalueat方法之后去做。这个可以保证取到的值一定是最新的同步数据。而且可以得到表格更改的row,column,value信息。但是这样,可能结构不太好,代码看起来不太齐整。第二,你可以在编辑器里面做文章。不知你有没有发现,如果你点鼠标,按下,抬起,这会触发两个itemstatechanged事件。一个就是你写的selected,另一个当然是unselected。只有当你完成按下又抬起的过程,才算是完成了一次编辑。这之后才会更新model的数据,你从model取得的才会是新值。可是你仔细看一下你的过程,原先选中的,你按下鼠标的时候就已经打印了,可是这时候根问没有完成编辑过程啊。
    上面有人说,在监听里面调用setvalueat方法,不可取。这样,相当于你的这个操作过程,改变了两次model的值,而第一次,是不对的。你可以写一个自己的editor,其中有stopCellEditing()方法。在stopCellEditing之后你再调用即可保证获得同步数据。
    第三,既然可以通过观察是否结束编辑来确定是否数据已经跟新,自然可以给编辑器加监听。但是,幸运的是,JTable自己已经实现了CellEditorListener这个接口,也就是说,JTable自身就是这样的一个很好的监听器。你没有写自己的editor,那么第二种方法我也就不多说了,留待你日后体会。你看一下这种方法:import javax.swing.DefaultCellEditor;
    import javax.swing.JCheckBox;
    import javax.swing.event.ChangeEvent;
    import javax.swing.table.TableColumn;public class AccountMode extends javax.swing.JFrame {
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1; public AccountMode() {
    initComponents();
    } private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane();
    jTable1 = new javax.swing.JTable() {
    @Override
    public void editingStopped(ChangeEvent e) {
    // TODO Auto-generated method stub
    super.editingStopped(e); for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
    System.out.println(jTable1.getValueAt(x, 0));
    }
    System.out.println("----------------------------");
    }
    }; setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jTable1.setModel(new javax.swing.table.DefaultTableModel(
    new Object[][] { { new Boolean("true"), null, null, null },
    { new Boolean("true"), null, null, null },
    { new Boolean("true"), null, null, null },
    { new Boolean("true"), null, null, null } },
    new String[] { "Title 1", "Title 2", "Title 3", "Title 4" }));
    // 将boolean转为jcheckbox
    TableColumn tc = jTable1.getColumnModel().getColumn(0);
    tc.setCellEditor(jTable1.getDefaultEditor(Boolean.class));
    tc.setCellRenderer(jTable1.getDefaultRenderer(Boolean.class)); DefaultCellEditor ce = (DefaultCellEditor) jTable1
    .getDefaultEditor(Boolean.class);
    JCheckBox cb = (JCheckBox) ce.getComponent();
    cb.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
    jCheckBox1ItemStateChanged(evt);
    }
    }); jScrollPane1.setViewportView(jTable1);
    // 这里是关于布局,可以不看start
    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
    getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(layout.createParallelGroup(
    javax.swing.GroupLayout.Alignment.LEADING).addGroup(
    javax.swing.GroupLayout.Alignment.TRAILING,
    layout.createSequentialGroup().addContainerGap(15,
    Short.MAX_VALUE).addComponent(jScrollPane1,
    javax.swing.GroupLayout.PREFERRED_SIZE, 375,
    javax.swing.GroupLayout.PREFERRED_SIZE)
    .addContainerGap()));
    layout.setVerticalGroup(layout.createParallelGroup(
    javax.swing.GroupLayout.Alignment.LEADING).addGroup(
    layout.createSequentialGroup().addContainerGap().addComponent(
    jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE,
    275, javax.swing.GroupLayout.PREFERRED_SIZE)
    .addContainerGap(15, Short.MAX_VALUE)));
    // 这里是关于布局,可以不看end
    pack();
    } private void jCheckBox1ItemStateChanged(java.awt.event.ItemEvent evt) { // if (evt.getStateChange() == ItemEvent.SELECTED) {
    // for (int x = 0, y = jTable1.getRowCount(); x < y; x++) {
    // System.out.println(jTable1.getValueAt(x, 0));
    // }
    // System.out.println("----------------------------");
    // }
    } public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
    new AccountMode().setVisible(true);
    }
    });
    }
    }
      

  10.   

    观摩学习。借楼主宝地问一下。
    有没有JTable 单键编辑,而且带光标的方法?谢谢。