Search code examples
javamacosswingjtableabstracttablemodel

JTable in JScrollPane not displaying properly in Mac OS X


The following code does not work on Mac OS X 10.6.8 but does on everything else I test, Mac OS X Lion and Windows 7. The obvious explanation would be differences in Apple's java. The table data does not show properly, if at all, on Mac. Here is the code

package com.dramble.dance;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

public class TableDemo extends JPanel {

    public TableDemo() {
        super(new GridLayout(1,0));

        TableModel tableModel = new TableModel();

        JTable table = new JTable(tableModel);

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);

        for(int i = 0 ; i <= 1900 ; i ++) {
            DataRow row = new DataRow(i,"Firstname"+i,"Lastname"+i);
            tableModel.appendRow(row);
            tableModel.fireTableRowsInserted(i, i);
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TableDemo newContentPane = new TableDemo();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private class DataRow {
        private String fname, lname;
        private Integer id;
        public String getFname() {
            return fname;
        }
        public String getLname() {
            return lname;
        }
        public Integer getId() {
            return id;
        }
        public DataRow(Integer id, String fname, String lname) {
            super();
            this.fname = fname;
            this.lname = lname;
            this.id = id;
        }
    }

    private class TableModel extends AbstractTableModel {
        List<DataRow> data;
        private String[] columnNames = {"ID #","First Name","Last Name"};
        private Class[] columnTypes = {int.class, String.class, String.class};


        public TableModel() {
            this.data = new ArrayList<DataRow>();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public int getRowCount() {
            return this.data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            DataRow dataRow = this.data.get(row);
            Object returnValue = null;

            switch (col) {
            case 0:
                returnValue = dataRow.getId();
                break;
            case 1:
                returnValue = dataRow.getFname();
                break;
            case 2:
                returnValue = dataRow.getLname();
                break;
            }
            return returnValue;
        }

        public void appendRow(DataRow row) {
            this.data.add(row);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int vColIndex) {
            return false;
        }

        @Override
        public Class getColumnClass(int col) {
            return columnTypes[col];
        }
    }
}

Here is an image of the expected behavior as exhibited in Windows Working table on Windows

Here is the same code on Mac OS X 10.6.8 Broken on Mac OS X


Solution

  • The problem lies in the AbstractTableModel, which came as a surprise to me for some reason, I figured it would be EDT and thread related for sure. The problem is in my array for the columnTypes and using int.class. Changing this to Integer.class fixed my issue.