Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / July 2008

Tip: Looking for answers? Try searching our database.

display a TableModel as a JTable

Thread view: 
thufir - 03 Jul 2008 11:16 GMT
Given three classes:

View               JFrame for the GUI
MyTableModel       represents the data
DBDemo             has db connection

In View there's:

private javax.swing.JTable db;
db.setModel(MyTableModel.getInstance());

Should DBDemo, which connects to the actual database, morph into an inner
class for MyTableModel, perhaps?

From the view, how do I make the JTable synchronize with the MyTableModel
instance?  A listener of some sort?

code:

thufir@arrakis:~$
thufir@arrakis:~$ cat NetBeansProjects/ubuntu-jdbc/src/a00720398/model/
MyTableModel.java
package a00720398.model;

import javax.swing.table.*;

public class MyTableModel extends AbstractTableModel {

   private static final TableModel INSTANCE = new MyTableModel();
 
   private MyTableModel() {}
   
   public static TableModel getInstance() {
       return INSTANCE;
   }

   public int getColumnCount() {
       return 1;  //dummy
   }

   public String getColumnName(int i) {
       return "foo";
   }

   public int getRowCount() {
       return 3;
   }

   public Object getValueAt(int row, int col) {
       return new Object();  //critical to fill this in
   }

}
thufir@arrakis:~$
thufir@arrakis:~$ cat NetBeansProjects/ubuntu-jdbc/src/a00720398/model/
DBDemo.java
package a00720398.model;

import java.sql.*;
import java.util.Properties;

public class DBDemo {

   private static final String DBCLASSNAME = "com.mysql.jdbc.Driver";
   private static final String CONNECTION = "jdbc:mysql://localhost/
COFFEEBREAK";

   public void db() throws ClassNotFoundException, SQLException {

       Class.forName(DBCLASSNAME);

       Properties p = new Properties();
       p.put("user", "java");
       p.put("password", "password");

       Connection c = DriverManager.getConnection(CONNECTION, p);

       Statement stmt = c.createStatement();

       stmt.executeUpdate("CREATE TABLE COFFEES " +
               "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " +
               "SALES INTEGER, TOTAL INTEGER)");

       stmt.executeUpdate("INSERT INTO COFFEES " +
               "VALUES ('Colombian', 101, 7.99, 0, 0)");
       stmt.executeUpdate("INSERT INTO COFFEES " +
               "VALUES ('French_Roast', 49, 8.99, 0, 0)");
       stmt.executeUpdate("INSERT INTO COFFEES " +
               "VALUES ('Espresso', 150, 9.99, 0, 0)");
       stmt.executeUpdate("INSERT INTO COFFEES " +
               "VALUES ('Colombian_Decaf', 101, 8.99, 0, 0)");
       stmt.executeUpdate("INSERT INTO COFFEES " +
               "VALUES ('French_Roast_Decaf', 49, 9.99, 0, 0)");

       String query = "SELECT COF_NAME, PRICE FROM COFFEES";
       ResultSet rs = stmt.executeQuery(query);
       while (rs.next()) {
           String s = rs.getString("COF_NAME");
           float n = rs.getFloat("PRICE");
           System.out.println(s + "   " + n);
       }

       String updateString = "UPDATE COFFEES " +
               "SET SALES = 75 " +
               "WHERE COF_NAME LIKE 'Colombian'";
       stmt.executeUpdate(updateString);

       c.close();
   }
}

thufir@arrakis:~$
thufir@arrakis:~$

thanks,

Thufir
RedGrittyBrick - 03 Jul 2008 14:14 GMT
> Given three classes:
>
[quoted text clipped - 4 lines]
> From the view, how do I make the JTable synchronize with the MyTableModel
> instance?  A listener of some sort?

For a model that implements AbstractTableModel, as your's does, the
usual method is to pass the model to the table's constructor:

JTable table = new JTable(MyTableModel.getInstance())

Signature

RGB

Mark Space - 03 Jul 2008 16:16 GMT
> From the view, how do I make the JTable synchronize with the MyTableModel
> instance?  A listener of some sort?

First, I think I'd keep anything which has a DB connection away from
Swing.  This feels like mixing layers.  I'd invent a bean that contained
the actual data, then compose the Swing table model with that bean.

Also, the static fields in MyTableModel smell bad to me.

public class MyJFrame extends JFrame

  private MyTableModel tableModel;
  private JTable viewTable;

  public MyJFrame( MyBean b ) {
    tableModel = new MyTableModel( b ); // Make table model with data
    viewTable = new JTable( tableModel );
    // ... etc. finish JFrame here...
  }

  public static main( String ... args ) {
    // Set up database connection and query...

    ResultSet rs = //...

    MyBean bean = new MyBean( rs ); // build bean from result set
    new MyJFrame( bean ).setVisible( true ); // show the result
  }

}

class MyTableModel extends AbstractTableModel {

  private MyBean data;

  public MyTableModel( MyBean b ) {
    data = b.clone(); // defensive copy
  }
  // Other methods pretty much as you had them...

}

// MyBean is "whatever" ... just some data with getters and setters.

So after sketching out the program above, I found that my
"synchronization" came from making a defensive copy.  So I avoid any
actual synchronization.   This seems like the best way, as a general
case.  If you could produce something that's closer to your actual code
or explain why you think you need synchronization, we might be able to
help with some specifics.

Listeners in Swing run on the EDT, so there's no need to synchronize
with any Swing internal data (like models like AbstractTableModel).  The
EDT is of course not synchronized with any events external to Swing, so
you have to deal with those yourself.  It's this latter case -- events
external to Swing -- that I don't feel like I have enough information on.
thufir - 03 Jul 2008 21:48 GMT
> So after sketching out the program above, I found that my
> "synchronization" came from making a defensive copy.  So I avoid any
[quoted text clipped - 9 lines]
> external to Swing -- that I don't feel like I have enough information
> on.

Oh, to clarify, I mean synchronize as in what's seen in the view matches
the underlying data, I wasn't referring to the Synchronized interface.  
Sorry, poor word choice which looks to have confused things.

I just read a bit of Dietel, it looks like he uses

http://java.sun.com/javase/6/docs/api/javax/swing/table/
AbstractTableModel.html#fireTableChanged
(javax.swing.event.TableModelEvent)

to get the JTable to match the underlying db.

-Thufir
Mark Space - 03 Jul 2008 23:22 GMT
> I just read a bit of Dietel, it looks like he uses
>
> http://java.sun.com/javase/6/docs/api/javax/swing/table/
> AbstractTableModel.html#fireTableChanged
> (javax.swing.event.TableModelEvent)

Remember, this still might require synchronization, as in the keyword.

If you do your update of the model data in the EDT, then it's possible
the the result set or whatever object you use is being updated by the
database object at the same time.  If you work eternally to the EDT, the
the model itself (accessed by the AbstractTableModel object) might be
updated by the GUI while trying to respond to some external user event.

You maybe way ahead of me here, I haven't used JTables explicitly, but
I've done a little work some some of the other Swing objects, and they
do require attention to the EDT.  Usually, you end up passing a Runnable
to java.awt.EventQueue.invokeLater to synchronize updating the model,
but you might have a more efficient way of doing it.
thufir - 05 Jul 2008 11:23 GMT
> If you do your update of the model data in the EDT, then it's possible
> the the result set or whatever object you use is being updated by the
> database object at the same time.  If you work eternally to the EDT, the
> the model itself (accessed by the AbstractTableModel object) might be
> updated by the GUI while trying to respond to some external user event.

Of course, but that's an immediate concern :)

-Thufir
Mark Space - 04 Jul 2008 00:20 GMT
> I just read a bit of Dietel, it looks like he uses
>
> http://java.sun.com/javase/6/docs/api/javax/swing/table/
> AbstractTableModel.html#fireTableChanged
> (javax.swing.event.TableModelEvent)

Also, read the docs.  This says:

"Forwards the given notification event to all TableModelListeners that
registered themselves as listeners for this table model. "

So all it does is kick off the listeners, which you have to add yourself
anyway.

Most Swing methods are not thread-safe either, so check carefully before
calling this method when you are not executing on the EDT.  I don't
think fire* methods are on the safe list, although several types of
listener methods are thread-safe, so a careful investigation might
reveal some documentation saying this one is.  Otherwise, you have to
assume it's not.

<http://java.sun.com/docs/books/tutorial/uiswing/concurrency/initial.html>

There should be a part of the Java doc where it explains (briefly) the
Swing threading model, and what methods are thread-safe.  I don't see it
right now however, so no link, sorry.
Nick - 17 Jul 2008 03:52 GMT
[...]
> First, I think I'd keep anything which has a DB connection away from
> Swing.  This feels like mixing layers.  I'd invent a bean that contained
> the actual data, then compose the Swing table model with that bean.

[...]

Aha.  If the underlying data is a bean, then just compose the Table
Model with that bean.  Can you use bean binding so that changes to the
underlying data percolate up to the Table Model and then to the
JTable?

thanks,

Thufir
Lew - 04 Jul 2008 02:00 GMT
> I wasn't referring to the Synchronized interface.  

That's good, because I don't think any of us have heard of the Synchronized
interface.  I'm going to guess that you meant something different, though, not
actually an interface called "Synchronized".

> I mean synchronize as in what's seen in the view matches
> the underlying data

Yes, that would be synchronization as the other respondents meant it, the
thing that gets coordinated via the 'synchronized' keyword and other mechanisms.

Signature

Lew

Thufir - 12 Jul 2008 10:28 GMT
[...]
> Yes, that would be synchronization as the other respondents meant it, the
> thing that gets coordinated via the 'synchronized' keyword and other mechanisms.
[...]

Here's the usage I meant:

Beans Binding is a Java platform library defined by Java Specification
Request 295. JSR 295 is an open source project that tries to simplify
how developers synchronize two properties, usually in two different
objects. The JSR has a reference implementation available as the Beans
Binding project on java.net. Additionally, NetBeans IDE 6 includes the
latest release of the Beans Binding library, making it easy for
NetBeans users to try out the new library.

Synchronizing Properties with Beans Binding (JSR 295)
by John O'Conner
03/20/2008

-Thufir
Nick - 17 Jul 2008 02:55 GMT
[...]
> First, I think I'd keep anything which has a DB connection away from
> Swing.  This feels like mixing layers.  I'd invent a bean that contained
> the actual data, then compose the Swing table model with that bean.
[...]

Aha.  If the underlying data is a bean, then just compose the Table
Model with that bean.  Can you use bean binding so that changes to the
underlying data percolate up to the Table Model and then to the
JTable?

thanks,

Thufir
thufir - 17 Jul 2008 06:13 GMT
>  I'd invent a bean that contained
> the actual data, then compose the Swing table model with that bean.

Aha.  If the underlying data is a bean (or accessed via a bean?), then
just compose the Table Model with that bean?  Can you use bean binding so
that changes to the underlying data percolate up to the Table Model and
then to the JTable?

thanks,

Thufir


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.