0

I used to display my database data in a JTable and it was working fine. I found out that I need to implement AbstractTableModel or DefaultTableModel to update the data instantly.

I am not sure what I should write in getValueAt()? Where should I add fireDataChanged()? Any guidance is appreciated, thanks!

I used to retrieve my database data with this code:

Vector columnNames = new Vector();
Vector data = new Vector();  

try
{
    Class.forName("com.mysql.jdbc.Driver");
    Connection con = DriverManager.getConnection ("jdbc:mysql://localhost:3306/watchlist","root","root");                   

    String sql = "SELECT * FROM watchlist";
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
    ResultSetMetaData md = rs.getMetaData();

    int columns = md.getColumnCount();
    for (int i = 1; i <= columns; i++)
    {
        columnNames.addElement( md.getColumnName(i));
    }                               

    int rowCount = md.getColumnCount();             
    while (rs.next())
    {
        Vector row = new Vector(rowCount);

        for (int i=1; i <= rowCount; i++)
        {
            row.addElement( rs.getObject(i) );
        }

        data.addElement( row );
    }

    rs.close();
    stmt.close();
    con.close();                                      
}

catch(Exception e)
{
    System.out.println(e);
} 

My AbstractTableModel:

public class MyTableModel extends AbstractTableModel 
{
    Vector columnNames = new Vector(); 
    Vector data = new Vector(); 

    public void connectionDB()
    {
        try
        {                               
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/watchlist","root","root");

             String sql = "SELECT * FROM watchlist";
             Statement stmt = con.createStatement();
             ResultSet rs = stmt.executeQuery(sql);
             ResultSetMetaData md = rs.getMetaData();   
        }

        catch(Exception e)
        {
            System.out.println(e);
        }
    }

    public int getColumnCount() 
    {
        return columnNames.size(); 
    }

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

    public Object getValueAt()
    {
        return data;    
    }

    public boolean isCellEditable(int row, int col)
    {
        return false; 
    }

}
Lily S
  • 245
  • 1
  • 8
  • 18
  • 3
    Have you gone through the official tutorial? Are there any specific things in the tutorial that you don't understand? – Hovercraft Full Of Eels May 11 '12 at 21:46
  • 3
    `public Object getValueAt() { return data; ..` Do you have any idea what you are doing? At least use the `@Override` notation. – Andrew Thompson May 11 '12 at 21:49
  • thanks for the kind remarks. i have no idea what i am doing, that's why i asked. have been looking through loads of examples but i still don't fully understand. – Lily S May 11 '12 at 22:17

2 Answers2

1

Here is a sample of using AbstractTableModel:

public class CustomTableModel extends AbstractTableModel
{
    private static final long serialVersionUID = 1L;
    private static final String[] columnNames = new String[]{"ID", "Name", "Number", "Yes/No"};
    protected List<Foo> lstFoo;
    protected Class<?>[] types = new Class[]{Integer.class, String.class, String.class, Boolean.class};

    public CustomTableModel(List<Foo> lstFoo)
    {
        this.lstFoo = lstFoo;
        fireTableDataChanged();
    }

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

    @Override
    public Class<?> getColumnClass(int columnIndex)
    {
        return types[columnIndex];
    }

    @Override
    public boolean isCellEditable(int row, int columnIndex)
    {
        return false;
    }

    @Override
    public Object getValueAt(int row, int column)
    {
        if(row < 0 || row >= lstFoo.size()) return null;
        Foo obj = lstFoo.get(row);
        switch(column)
        {
            case 0: return obj.getId();
            case 1: return obj.getName();
            case 2: return obj.getNumber();
            case 3: return obj.isYes();
            default: return null;
        }
    }

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

    @Override
    public int getColumnCount()
    {
        return columnNames.length;
    }
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • please no, I'm sorry 1) add [setXxx with fireXxxXxx](http://stackoverflow.com/a/6901508/714968), 2) delete this answer :-) – mKorbel May 11 '12 at 22:18
  • s/he wants to add data to the JTable instantly, and if is there AbstractTableModel then setXxx add / change /modify value in/to the JTable's view, why refresh whole JTables structures (for example) if you want to edit only one Cell, and Vector bases Model is better for SQL whatever as List (same premature array type), then (Hash)Map could be way, but again Vector> is better and very similair to SQL :-) – mKorbel May 11 '12 at 22:26
  • Thanks @mKorbel and trashgod for the tips, I won't remove this answer, just to let people see your comments :) – Eng.Fouad May 11 '12 at 22:36
  • See also this related example that discusses implementing `setValueAt()`, which is required for a mutable `TableModel`. – trashgod May 12 '12 at 03:49
0

just one point, two many connections to a database will reduce the speed and too much overhead. I had this issue and was able to solve it.

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58