0

I'm trying to create a Jtable that takes displays SQL queries. I have inserted a column before the data is shows and I have set it to the Boolean class. When I run the code instead of showing checkboxes, it displays 'class java.lang.Boolean' instead.

Ive tried calling the isCellEditable() and getColumnClass() methods.

public static void FillTable(JTable table, String Query){
    try
    {   
        Connection conn = DriverManager.getConnection(databaseTest.main_conn,"root",databaseTest.db_usrPW);
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery(Query);

      //Define new model
        DefaultTableModel tableModel = new DefaultTableModel();

        //Get MetaData from rs
        ResultSetMetaData metaData = rs.getMetaData();

        //Get number of columns from meta data
        int columnCount = (metaData.getColumnCount()+1);

        //Add Boolean column
        tableModel.addColumn(Boolean.class);
        tableModel.getColumnClass(0);

        //Get all column names from meta data and add columns to table model
        for (int columnIndex = 1; columnIndex < columnCount; columnIndex++){
            tableModel.addColumn(metaData.getColumnLabel(columnIndex));
        }

        //Create array of Objects with size of column count from meta data
        Object[] row = new Object[columnCount];

        //Scroll through result set
        while (rs.next()){
            row[0] = Boolean.class;
            tableModel.addRow(row);
            //Get object from column with specific index of result set to array of objects
            for (int i = 1; i < columnCount; i++){
                row[i] = rs.getObject(i);
                }            
            //Now add row to table model with that array of objects as an argument
            tableModel.addRow(row);
        }
        db_table.setModel(tableModel);
        rs.close();
    }catch(Exception e){
        e.printStackTrace();
    }   
}
coder188642
  • 145
  • 2
  • 5
  • 15
  • `row[0]` should NOT be assigned a `Boolean.class`, it should be assigned a `Boolean` value (either `true` or `false` depending on the state you want the checkbox to be in – MadProgrammer May 06 '19 at 21:50
  • You should also check [How to Use Tables](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html) as it has examples for this kind of thing – MadProgrammer May 06 '19 at 21:51
  • Ive changed it to false as that's the default I want it to be. They are now displaying 'false' instead of the class name. – coder188642 May 06 '19 at 21:52
  • `tableModel.addColumn(Boolean.class);` is "adding" the column to the end of the column model, might want to check on that. I prefer to use my own `TableModel`, as it gives you much more control, [for example](https://stackoverflow.com/questions/23822376/display-jcheckbox-in-jtable/23822410#23822410) – MadProgrammer May 06 '19 at 21:53
  • You'll also want to look at the JavaDocs for [`DefaultTableModel#addColumn`](https://docs.oracle.com/javase/8/docs/api/javax/swing/table/DefaultTableModel.html#addColumn-java.lang.Object-), as you're not passing the expected value – MadProgrammer May 06 '19 at 21:55
  • @MadProgrammer In your code because you've put it in the run method you can put the getColumnClass method in it. It wont let me do that, and if I put it in its own method body then where do I call it? Also how do you know the column is added last? It is added before the other columns – coder188642 May 06 '19 at 22:01
  • First of all, so what? It's an example intended to demonstrate the basic requirements, you're going to have to make the effort to adapt it to your needs. Second of all, I'm trying to piece your code together from simply glancing at it. So, while technically, `add` does add it to the end of the model, I missed your loop which was adding the other columns – MadProgrammer May 06 '19 at 22:08
  • @MadProgrammer, sorry, I was just confused on the positioning of the method. – coder188642 May 06 '19 at 22:23

1 Answers1

0

As the JavaDocs for DefaultTableModel highlights

Warning: DefaultTableModel returns a column class of Object... If you use DefaultTableModel ... you are strongly encouraged to override getColumnClass to return the appropriate type.

While the comment relates to the use of TableRowSorter it highlights the underlaying cause of your issue. getColumnClass is returning a type of Object, which means that it won't allow for the use of default renders for types like Boolean.

Instead, you will need to create a custom implementation of TableModel (I prefer AbstractTableModel, but you can still use DefaultTableModel) and override the getColumnClass and return a more appropriate value for the specific column, for example...

Picky

import java.awt.EventQueue;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class Test extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                DefaultTableModel model = new DefaultTableModel() {
                    @Override
                    public Class<?> getColumnClass(int columnIndex) {
                        return Boolean.class;
                    }
                };
                model.addColumn("Pick");

                Random rnd = new Random();
                for (int index = 0; index < 10; index++) {
                    Object[] row = new Object[1];
                    row[0] = rnd.nextBoolean();
                    model.addRow(row);
                }
                JTable table = new JTable(model);

                JFrame frame = new JFrame();
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

Note This is a simple example, if you have multiple columns, you will need to make a decision about what to return for each column

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366