0

Hello I have created a Java program in that I want to display some data in table run time.

Using below function the data displays perfectly, but I can't click on JTable data like check box or text.

Thanks.

My code is:

    public void TableDataModel()
    {
        String[] cols = {"<html>Task<br>Name</html>", "<html>Start<br>Time</html>", "Finished"};

        DefaultTableModel model = new DefaultTableModel(data, cols) 
        {
            @Override
            public Class<?> getColumnClass(int col)
            {
                return col == 2 ? Boolean.class : String.class;
            }

            @Override
            public boolean isCellEditable(int row, int column) 
            { 
                return column==2 ? true : false;
            } 
        };

        JTable table = new JTable(model)
        {
            @Override
            public boolean isCellEditable(int row, int column) {
                return column==2 ? true : false;
            }
        };            

        table.setFont(new java.awt.Font("Times New Roman", 0, 14));
        table.getTableHeader().setFont(new java.awt.Font("Times New Roman", 0, 14));        
        table.getTableHeader().enable(false);

        JCheckBox jcheckBox=new JCheckBox();                
        TableColumnModel columnModel = table.getColumnModel();        
        columnModel.getColumn(2).setCellEditor(new DefaultCellEditor(jcheckBox));      

        jcheckBox.addChangeListener(new ChangeListener() 
        {
            @Override
            public void stateChanged(ChangeEvent e) 
            {
                int rowCount = model.getRowCount();
                for(int i=0; i<rowCount; i++) 
                {
                    Boolean selected = (Boolean)model.getValueAt(i, 2);
                    if(selected != null && selected) 
                    {
                        System.out.println("Removed:"+i);
                        model.removeRow(i);
                        i--;
                    }
                } 
            }
        });

        JScrollPane jScrollpane=new JScrollPane(table);      
        jScrollpane.setViewportView(table);
        this.add(jScrollpane);
        jScrollpane.setFont(new java.awt.Font("Times New Roman", 0, 14));        
        jScrollpane.setBounds(10, 130, 295, 190);          
    }

1 Answers1

0

I think its a logical issue in the change listener.

jcheckBox.addChangeListener(new ChangeListener() 
    {
        @Override
        public void stateChanged(ChangeEvent e) 
        {
            int rowCount = model.getRowCount();
            for(int i=0; i<rowCount; i++) 
            {
                Boolean selected = (Boolean)model.getValueAt(i, 2);
                if(selected != null && selected) 
                {
                    System.out.println("Removed:"+i);
                    model.removeRow(i);
                    i--;
                }
            } 
        }
    });

Here first you take the rowCount and iterate through it and inside you are removing row. This changes the row count. So you need to update the rowCount variable at this point. Try adding rowCount = model.getRowCount(); after i--;

Sample

import java.awt.GridLayout;

import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class SimpleTableDemo extends JPanel {

    public SimpleTableDemo() {
        super(new GridLayout(1, 0));
        TableDataModel();
    }

    public void TableDataModel() {
        String[] cols = { "<html>Task<br>Name</html>",
                "<html>Start<br>Time</html>", "Finished" };
        Object[][] data = {
                { "Kathy", "", new Boolean(false) },
                { "John", "", new Boolean(false) },
                { "Sue", "", new Boolean(false) },
                { "Jane", "", new Boolean(false) },
                { "Joe", "", new Boolean(false) } };

        DefaultTableModel model = new DefaultTableModel(data, cols) {
            @Override
            public Class<?> getColumnClass(int col) {
                return col == 2 ? Boolean.class : String.class;
            }

            @Override
            public boolean isCellEditable(int row, int column) {
                return column == 2 ? true : false;
            }
        };

        JTable table = new JTable(model) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return column == 2 ? true : false;
            }
        };

        table.setFont(new java.awt.Font("Times New Roman", 0, 14));
        table.getTableHeader().setFont(
                new java.awt.Font("Times New Roman", 0, 14));
        table.getTableHeader().enable(false);

        JCheckBox jcheckBox = new JCheckBox();
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(2)
                .setCellEditor(new DefaultCellEditor(jcheckBox));

        jcheckBox.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int rowCount = model.getRowCount();
                System.out.println("*************" + rowCount);
                for (int i = 0; i < rowCount; i++) {
                    System.out.println(i);
                    Boolean selected = (Boolean) model.getValueAt(i, 2);
                    if (selected != null && selected) {
                        System.out.println("Removed:" + i);
                        model.removeRow(i);
                        i--;
                        rowCount = model.getRowCount();
                    }
                }
            }
        });

        JScrollPane jScrollpane = new JScrollPane(table);
        jScrollpane.setViewportView(table);
        this.add(jScrollpane);
        jScrollpane.setFont(new java.awt.Font("Times New Roman", 0, 14));
        jScrollpane.setBounds(10, 130, 295, 190);
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SimpleTableDemo newContentPane = new SimpleTableDemo();
        newContentPane.setOpaque(true); // content panes must be opaque
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Syam S
  • 8,421
  • 1
  • 26
  • 36
  • it's ok @Syam S, bur when I call this fuction second time I can't click on any checkbox –  May 23 '14 at 12:16
  • That may be unrelated issue. I just created a sample with your code. It works fine.. Posted above. Can you post your full code? – Syam S May 23 '14 at 12:20
  • When I call this method first time it works well, but in second time it displays data properly but I can't click on it. –  May 23 '14 at 12:23
  • Which method? `TableDataModel()` ?? – Syam S May 23 '14 at 13:04
  • can you share the snippet where its called second time? Calling this method results in adding more and more tables to the container. Still that shouldn't cause a problem like you mentioned. It might depend on the way you call it. – Syam S May 24 '14 at 13:47