views:

472

answers:

1

I am able to break this problem down into two questions:

  1. What is the best way to put the contents of a database (MS-Access) into a GlazedList/JTable?
  2. How do I make sure any changes made to the GlazedList/JTable are reflected on the database (MS-Access)?

Here are the things I know:

  1. I know how to retrieve/manipulate the information from a database using the JDBC method.
  2. I know that GlazedList's require reflection so I would need to make a class that contains every column/field in the database. This is not very expandable...

What is the best way to go about this problem?

edit:// I have managed to create a class generator. It takes the column headings and creates an instance field. This should resolve the #2 http://pastebin.ca/1770996 - It creates the class but I do not think I used reflection correctly... edit2:// Edited my code from above so it works... http://pastebin.ca/1776722

+1  A: 

I had a very similar problem, and I think my result was similar too, except it didn't need reflection (static DB schema). You need to create row objects for each row (which may just include row number and references to a ResultSet and column info).

Then write a ca.odell.glazedlists.gui.WritableTableFormat implementation to map these objects to table cells.

To avoid problems with #2, you can create a flexible row class that fetches column info once from the ResultSet and caches it for reuse.

Edit: I found an original and simpler implementation (fairly simple) that mine was based upon. You can view it here: ResultSet Table. It might be sufficient for your purposes. Then you add this to the AbstractTableModel implementation provided by the link.

public void setValueAt(Object ob, int row, int column) throws SQLException {
    resultSet.absolute(r+1);
    if (ob == null) {
        resultSet.updateNull(column+2);
    } else {
        resultSet.updateObject(column+2,ob);
    }
    rs.updateRow();
    this.fireTableCellUpdated(row,column);  
}
public boolean isCellEditable(int row, int col) {
    return true;
}

There are three catches though: your ResultSet needs to be updatable, support scrolling both directions, and be sensitive to updates to the DB. These are part of the JDBC spec, but not all drivers support them, and you need to make sure your ResultSet is created with them enabled. In that case, you just do this.fireTableDataChanged() periodically to force a full update of the table data. It's not the fastest approach, but it does work.


Edit2: Another approach

What about using one of the Object-relational mapper libraries, and then do the ca.odell.glazedlists.gui.WritableTableFormat like I suggested above?

BobMcGee
Could you please explain this a little bit more? Code snippets would be great or more links.
twodayslate
Now, THAT bounty makes it worth digging through source for my old code and combining it to create an implementation.
BobMcGee
I only have 53 rep points... I can't do anymore :\
twodayslate
Err, sorry: I'm not being sarcastic. It IS better than the 15 acceptance points, especially when the question is kind of complex. Question: do you know what DBMS you will be using, and can you guarantee that all the JDBC features will be supported? My previous implementation of an editable table ran to a couple thousand lines, and relied on updatable resultsets and JDBC metadata. Not all drivers will support these features, but doing it another way is... well, really messy.
BobMcGee
I will be using a MS-Access 2003 database on Windows XP so everything should be supported. The database is actually rather small compared to yours I would think. There are probably only 1000 elements total. So nothing huge by any means.
twodayslate
@twodayslate: it is considerably simpler if the whole DB fits in memory. Ok, I will be working on extending my existing implementation for your needs. Please give me a few days to get the code finished: bear in mind this can require significant coding, especially as I will be avoiding reflection for performance reasons.
BobMcGee
Wow! Thank you for your time. That sounds like a huge task and I wish I could give you more for your time. I look forward to seeing how you do this cause the only thing I managed to come up with used reflection. Have all the time you want!
twodayslate
Thank you for the wonderful linkage! I can see the resultsets but nothing else. I also get the following error `Error java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Syntax error in FROM clause.`Perhaps I do not meet the 3 catches? How do I ensure I meet them exactly?
twodayslate
Also it didn't like `Class.forName("com.pointbase.jdbc.jdbcDriver");` so I changed it to the driver I had before. How do I set it up for this driver exactly? It said it couldn't find this one...
twodayslate
If I knew how to do the Edit2 approach I would try it... :(
twodayslate
So from my understanding, it is better to accept the answer now so you get all the points right?
twodayslate
@twodayslate: yeah, I get more credit and I think you get a bit back too (to encourage people accepting answers). I wish I had a better answer for you. My initial approach runs into problems when you're only selecting part of the table, or when the DB gets modified by another thread.
BobMcGee
Alright, I accepted your answer. If you want to expand on the current answer later or post a new answer that would be great. ;)
twodayslate
How would you put glazedlist filters on this?
twodayslate
You can't apply a filter to this, unfortunately. To do that, you need an entity-based approach with one object per row. I've been thinking on a way to do this without the full complexity of a object-relational mapper, but it gets pretty complex pretty fast.
BobMcGee
I just decided to continue this in another question. This was getting rather long... http://stackoverflow.com/questions/2308743/editing-jtable-from-restulset-table
twodayslate