The Source for Java Technology Collaboration

Home » java.net Forums » Java Desktop Technologies » SwingLabs

Thread: DataBuffer's TableCommand fails with PostgreSQL schemas ?

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 15 - Last Post: Aug 10, 2006 8:04 AM by: dags
dags

Posts: 182
DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 10:16 AM
  Click to reply to this thread Reply

Hi,

I checked out databuffer from CVS today and tried to make a simple test.

I got some "read errors" and after following stack trace I realized that the error was in the select sql string generated by TableCommand. I created my TableCommand using accounting.currencies as table name. In postgresql, that means : schema accounting, table currencies and could be used a qualified table name in queries.

TableCommand quotes table name with ", so the resulting sql is :

select * from "accounting.currencies"

while postgresql server doesn't understand "accounting.currencies" as schema.table but as a quoted table name. Quoted table names are used to preserve case or some symbols in table name. Postgresql tries to find "accounting.currencies" table in schema public instead of finding currencies table in schema accounting.

After modifying TableCommand a little, I got string :

select * from accounting.currencies

and now my example works OK but this change could prevent using table names like Currencies (upper and lowercase mixed).

Maybe TableCommand should have another property, Schema, to make it able to work with PostgreSQL ?. Quoting doesn't need to change in that case. We could get :

select * from "accounting"."currencies"

if (!schemaName.isEmpty())
buffer.apend("\"").append(schemaName).append("\".");
buffer.apend("\"").append(tableName).append("\"");

schemaName default value should be set to an empty string.

Regards,
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 10:36 AM   in response to: dags
  Click to reply to this thread Reply

Hi Diego

You're quick! I only just moved code in this morning, hadn't announced
anything yet.

We definitely have an issue to resolve around how to handle SQL
specific to particular vendors. Can you file an RFE, please? I need a
few days to set the project up before and changes can been made.


Regards
Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 10:44 AM   in response to: Patrick Wright
  Click to reply to this thread Reply

Patrick,

I will file an RFE later, at home.

You may want to review package declared for DataSetTest.java (I guess). It is org.jdesktop.dataset instead of org.jdesktop.databuffer, if I recall correctly.

Could you point me to a TableModel implementation based on DataTable ? Or any other examples of databuffer usage ?.

Thanks.
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 11:05 AM   in response to: dags
  Click to reply to this thread Reply

Hi Diego

> You may want to review package declared for DataSetTest.java (I guess). It is org.jdesktop.dataset instead of org.jdesktop.databuffer, if I recall correctly.

Thanks, I clobbered the refactoring of the test package names
slightly. Will fix.

> Could you point me to a TableModel implementation based on DataTable ? Or any other examples of databuffer usage ?.

Ooof! This is old stuff, man. Meaning, yes, there used to be examples
and some running demos but most of it would need to be dusted off. You
can do a search in the incubator or swinglabs-demos for, say, DataSet
and DataTable. Richard had integrated it with the binding library, so
there was an adaptor that provided a TableModel to work with...As we
are just in the process of splitting the projects, there is no code I
can point to that is working right now, just the test cases, actually.
But--soon to come. Your input is very welcome!


Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


rbair

Posts: 1,830
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 10:40 AM   in response to: dags
  Click to reply to this thread Reply

Hey Diego,

Thanks for bringing this up. I think you are right and there should be a "schemaName" property. In addition it seems like there needs to be some support for SQL Dialects, because different databases understand different, well, dialects of SQL. You're definitely right that it isn't doing a very good job of it today :(

For example, like you pointed out, Postgres requires exact case matching for tables listed in quotes. I believe other databases (I don't remember which now, I think it was mysql or derby) don't.

What do you think of having a SqlDialect class, which the TableCommand and SqlCommand would delegate to for creating the SQL statements? The default one could be a bit more intelligent, perhaps. It would be nice if the proper dialect could be used based on the database driver, or overridden by the developer.

What do you think?
Richard

dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 10:57 AM   in response to: rbair
  Click to reply to this thread Reply

Hi Richard,

I think TableCommand and SQLCommand should be as close as SQL specifications as possible. That should work on most databases ?. I don't know but sticking to standards is a good start always.

SqlDialect seems interesting, if differences between databases are enough to justify it.

What is the point in quoting table names if databases don't care ?. Maybe the standard should be to quote only when case preservation is needed.

I will review some SQL specs to see what I am missing.

Regards,
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 11:09 AM   in response to: dags
  Click to reply to this thread Reply

> I think TableCommand and SQLCommand should be as close as SQL specifications as possible. That should work on most databases ?. I don't know but sticking to standards is a good start always.
>
> SqlDialect seems interesting, if differences between databases are enough to justify it.

There are real differences in what databases allow, in particular what
characters are allowed in column and table names. Some allow spaces
(if quoted), some do not, etc. I've never made a list and haven't
worked with them all myself. I'd say we have a decent base class and
make it easy to extend and override if the DB is picky about some
little iggly-piggly syntax issue. This problem came up before, one of
the TODOs is to create a test suite we can run against a number of
databases to find these sorts of problems.


Regards
Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 3:48 PM   in response to: Patrick Wright
  Click to reply to this thread Reply

Patrick:

in DataTable.java, line 720 ( private void enforceColumnName(String columnName) {)
            String msg = "Unknown Column \"{0]\" in table \"{1}\"";

should be
            String msg = "Unknown Column \"{0}\" in table \"{1}\"";


I managed to extend AbstractTableModel using DataTable as data source, for a quick test, but fails to update database table because TableCommand doesn't set key columns: all table rows contains the same updated value. Is like :

update mytable set mycolumn = 'newvalue';

I got the following warning too :

ADVERTENCIA: !!! No key columns were specified, the entire table {0} will be updated!!


How could I specify key columns in TableCommand ?.

Regards,
Diego.

dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 9, 2006 5:03 PM   in response to: dags
  Click to reply to this thread Reply

Never mind. I Found it !.

Here is my code. It work with sligthy modified databuffer code.

/*
 * DataBufferTest.java
 *
 * Created on 9 de agosto de 2006, 9:28
 */
 
package com.adminsa.accounting.model;
 
import com.adminsa.util.InitUI;
import org.jdesktop.databuffer.DataSet;
import org.jdesktop.databuffer.DataTable;
import org.jdesktop.databuffer.event.DataTableListener;
import org.jdesktop.databuffer.event.RowChangeEvent;
import org.jdesktop.databuffer.event.TableChangeEvent;
import org.jdesktop.databuffer.provider.sql.JDBCDataConnection;
import org.jdesktop.databuffer.provider.sql.SQLDataProvider;
import org.jdesktop.databuffer.provider.sql.TableCommand;
 
 
/**
 *
 * @author  dags
 */
public class DataBufferTest extends org.jdesktop.swingx.JXPanel implements DataTableListener {
    
    private CurrencyTableModel modelo = null;
    private SQLDataProvider dp = null;
    private JDBCDataConnection dc = null;
    private TableCommand tc = null;
    private DataSet ds = null;
    private DataTable dt = null;
    
    /** Creates new form BeanForm */
    public DataBufferTest() {
        initComponents();
 
        dc = new JDBCDataConnection("org.postgresql.Driver", "jdbc:postgresql://mi_servidor/mag", "dags", "");
        dc.setConnected(true);
        
        tc = new TableCommand("currencies");
        tc.setSchemaName("accounting");
        
        dp = new SQLDataProvider();
        dp.setConnection(dc);
        dp.setCommand(tc);
 
        ds = new DataSet("accounting");
        
        dt = new DataTable(ds, "monedas");
        dt.createColumn(String.class, "currency_id");
        dt.createColumn(String.class, "currency_name");
        dt.addDataTableListener(this);
        dt.setDataProvider(dp);
 
        dt.load();
        dt.getColumn("currency_id").setKeyColumn(true);
        
        modelo = new CurrencyTableModel(dt);
        jXTable1.setModel(modelo);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Código Generado ">
    private void initComponents() {
        jScrollPane1 = new javax.swing.JScrollPane();
        jXTable1 = new org.jdesktop.swingx.JXTable();
 
        setLayout(new java.awt.BorderLayout());
 
        jXTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Moneda", "Denominación"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };
 
            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jScrollPane1.setViewportView(jXTable1);
 
        add(jScrollPane1, java.awt.BorderLayout.CENTER);
 
    }// </editor-fold>
    
    
    // Declaración de variables - no modificar
    private javax.swing.JScrollPane jScrollPane1;
    private org.jdesktop.swingx.JXTable jXTable1;
    // Fin de declaración de variables
        public static void main(String args[]) {
        
        InitUI.initUI();
        
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                javax.swing.JFrame frame = new javax.swing.JFrame(" DataBufferTest ");
                frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new java.awt.BorderLayout());
                frame.add(new DataBufferTest(), java.awt.BorderLayout.CENTER);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
 
    public void rowChanged(RowChangeEvent evt) {
        //System.out.println("rowChanged " + evt.toString());
    }
 
    public void tableChanged(TableChangeEvent evt) {
        //System.out.println("tableChanged " + evt.toString());
        switch(evt.getEventType()) {
            case LOAD_COMPLETE:
                System.out.println("RowCount = " + dt.getRowCount());
                break;
            case COLUMN_CHANGED:
                break;
            case LOAD_STARTED:
                break;
            case ROW_ADDED:
                break;
            case ROW_DELETED:
                break;
            case ROW_DISCARDED:
                break;
            case SAVE_COMPLETE:
                break;
            case SAVE_STARTED:
                break;
            case TABLE_CLEARED:
                break;
        }
    }
}


Now, my database table gets updated OK using a JXTable !.

CurrencyTableModel is absolute dirty. If someone is interested, I will polish my code a little and will publish here.

Regards,
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 1:26 AM   in response to: dags
  Click to reply to this thread Reply

Hi Diego

Nice work, good to see that it all works in fairly few lines of code.

If you want, you could start an incubator example of how this works,
until we can get the databuffer code cleaned up and proper examples
built--having a simple TableModel that works with a DataTable would be
good for people walking up to the project. Dirty is OK! And besides, I
love seeing the Spanish mixed in with the English in the code.


Cheers
Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 4:11 AM   in response to: Patrick Wright
  Click to reply to this thread Reply

Hi,

Here is my CurrencyTableModel, while setting up an incubator example.

Critics are welcomed !.

package com.adminsa.accounting.model;
 
import org.jdesktop.databuffer.DataTable;
 
/**
 *
 * @author  dags
 */
public class CurrencyTableModel extends javax.swing.table.AbstractTableModel {
    
    private DataTable dt = null;
    
    // to hold header's titles, if needed
    private String[] columnTitles = null;
    
    private String[] columnNames = {
        "currency_id",
        "currency_name"};
    
    /** Creates a new empty instance of CurrencyTableModel */
    public CurrencyTableModel() {
    }
    
    /** Creates a new instance of CurrencyTableModel linked to a DataTable  */
    public CurrencyTableModel(DataTable dt) {
        this();
        setDataTable(dt);
    }
    
    public void setDataTable(DataTable dt) {
        this.dt = dt;
   
        // notify model has changed
        fireTableDataChanged();
    }
    
    public int getColumnCount() {
        return (dt == null ? 0 : dt.getColumns().size());
    }
    
    public int getRowCount() {
        return (dt == null ? 0 : dt.getRowCount());
    }
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        return (dt == null ? null : dt.getValue(rowIndex, columnNames[columnIndex]));
    }
 
    public void setValueAt(Object value, int row, int col) {
        
        if (dt == null) return;
        
        dt.setValue(row, columnNames[col], value);
        
        // save on every model's data change. Maybe is not needed if there is a Save button somewhere ...
        dt.save();
        
        //notify model has changed
        fireTableCellUpdated(row, col);
    }
    
    public String getColumnName(int columnIndex) {
        return columnTitles == null ? columnNames[columnIndex] : columnTitles[columnIndex];
    }
 
    public String[] getColumnTitles() {
        return columnTitles;
    }
 
    public void setColumnTitles(String[] columnTitles) {
        this.columnTitles = columnTitles;
    }
    
    public Class getColumnClass(int columnIndex) {
        return getValueAt(0, columnIndex).getClass();
    }
    
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return !dt.getColumn(columnNames[columnIndex]).isReadOnly();
    }
    
    public void populate() {
        if (dt == null) return;
        
        // clear DataTable and load again ...
        dt.refresh();
 
        //notify model has changed
        fireTableDataChanged();
    }
}


Regards,
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 4:14 AM   in response to: dags
  Click to reply to this thread Reply

Looks good--one thing, why not pull the default column names from the
DataTable, instead of hard-coding?

> private String[] columnNames = {
> "currency_id",
> "currency_name"};
>

Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 5:22 AM   in response to: Patrick Wright
  Click to reply to this thread Reply

Hi Patrick,

I told you it was dirty ! :-)

Now, it seems that is a more generic TableModel.

package com.adminsa.accounting.model;
 
import java.util.ArrayList;
import java.util.List;
import org.jdesktop.databuffer.DataColumn;
import org.jdesktop.databuffer.DataTable;
 
/**
 *
 * @author  dags
 */
public class CurrencyTableModel extends javax.swing.table.AbstractTableModel {
    
    private DataTable dt = null;
    
    // to hold header's titles, if needed
    private String[] columnTitles = null;
    
    // to hold column names, from DataTable
    private ArrayList<String> columnNames = null;
    
    /** Creates a new empty instance of CurrencyTableModel */
    public CurrencyTableModel() {
    }
    
    /** Creates a new instance of CurrencyTableModel linked to a DataTable  */
    public CurrencyTableModel(DataTable dt) {
        this();
        setDataTable(dt);
    }
    
    public void setDataTable(DataTable dt) {
        this.dt = dt;
   
        List<DataColumn> columns = dt.getColumns();
 
        columnNames = new ArrayList<String>();
        
        for (DataColumn column : columns)
            columnNames.add(column.getName());
 
        // notify model has changed
        fireTableDataChanged();
    }
    
    public int getColumnCount() {
        return (dt == null ? 0 : dt.getColumns().size());
    }
    
    public int getRowCount() {
        return (dt == null ? 0 : dt.getRowCount());
    }
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        return (dt == null ? null : dt.getValue(rowIndex, columnNames.get(columnIndex) ));
    }
 
    public void setValueAt(Object value, int row, int col) {
        
        if (dt == null) return;
        
        dt.setValue(row, columnNames.get(col), value);
        
        // save on every model's data change. Maybe is not needed if there is a Save button somewhere ...
        dt.save();
        
        //notify model has changed
        fireTableCellUpdated(row, col);
    }
    
    public String getColumnName(int columnIndex) {
        // if column Titles are setup, use it. If not, use column names from database.
        // columns titles are supposed to be more "human friendly"
        return columnTitles == null ? columnNames.get(columnIndex) : columnTitles[columnIndex];
    }
 
    public String[] getColumnTitles() {
        return columnTitles;
    }
 
    public void setColumnTitles(String[] columnTitles) {
        this.columnTitles = columnTitles;
    }
    
    public Class getColumnClass(int columnIndex) {
        return getValueAt(0, columnIndex).getClass();
    }
    
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return !dt.getColumn( columnNames.get(columnIndex) ).isReadOnly();
    }
    
    public void populate() {
        if (dt == null) return;
        
        // clear DataTable and load again ...
        dt.refresh();
 
        //notify model has changed
        fireTableDataChanged();
    }
}


Regards,
Diego.

Patrick Wright
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 5:29 AM   in response to: dags
  Click to reply to this thread Reply

Nice work.

Some possible changes:
1) make auto-save optional (in setValueAt())

2) don't allow constructor without DataTable--nothing will work
without it (make empty constructor private)

3) add listeners to the datatable in case the datatable structure
(columns, column names, number of rows, etc.) or datatable data
changes programmatically

Your code is very easy to read and very good to have as an example.

Cheers!
Patrick

Note to self: There are probably other neat examples we could do, like
highlighters that are sensitive to a row's status (new, updated,
deleted, etc).

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 5:45 AM   in response to: Patrick Wright
  Click to reply to this thread Reply

Patrick,

1) good point. I'll do it.
2) I use to have a empty constructor to ease the use in a IDE like Netbeans. I think is the only way to have it in the Palette. I add a TableModel from Palette and then change some of its properties, before adding to a JXTable (wich in turn was added from Palette).
3) good point too, even when I guess that DataTable's structure will rarely change in common DataTable usage. I will study a little more.

Thanks for for comments.

Diego.

dags

Posts: 182
Re: DataBuffer's TableCommand fails with PostgreSQL schemas ?
Posted: Aug 10, 2006 8:04 AM   in response to: dags
  Click to reply to this thread Reply

Patrick,

I tried CurrencyTableModel with another table, 23 columns and 2639 rows, showing serious performance troubles.

After a little search, I found that the trouble was in the getColumnClass method of CurrencyTableModel, throwing NullPointerException. I changed to :
 public Class getColumnClass(int columnIndex) {
        System.out.println("getColumnClass " + columnIndex);
        return dt.getColumn(columnNames.get(columnIndex)).getType();
        // former wrong code 
        //return getValueAt(0, columnIndex).getClass();
    }

and now works OK.

This is the code for the generic TableModel I am using now to learn about DataBuffer (someone has a better class name ?):
package com.adminsa.accounting.model;
 
import java.util.ArrayList;
import java.util.List;
import org.jdesktop.databuffer.DataColumn;
import org.jdesktop.databuffer.DataRow;
import org.jdesktop.databuffer.DataTable;
import org.jdesktop.databuffer.event.DataTableListener;
import org.jdesktop.databuffer.event.RowChangeEvent;
import org.jdesktop.databuffer.event.TableChangeEvent;
 
/**
 *
 * @author  dags
 */
public class DataTableTableModel extends javax.swing.table.AbstractTableModel implements DataTableListener {
    
    private DataTable dt = null;
    private boolean autoSave = true;
    
    /** to hold header's titles, if needed */
    private String[] columnTitles = null;
    
    /** to hold column names, from DataTable */
    private ArrayList<String> columnNames = null;
    
    /** Creates a new empty instance of DataTableTableModel */
    public DataTableTableModel() {
    }
    
    /** Creates a new instance of DataTableTableModel linked to a DataTable  */
    public DataTableTableModel(DataTable dt) {
        this();
        setDataTable(dt);
    }
    
    public void setDataTable(DataTable dt) {
        // remove this as a listener of the former datatable
        if (this.dt != null)
            this.dt.removeDataTableListener(this);
        
        this.dt = dt;
        this.dt.addDataTableListener(this);
        
        List<DataColumn> columns = dt.getColumns();
        
        columnNames = new ArrayList<String>();
        
        for (DataColumn column : columns)
            columnNames.add(column.getName());
        
        /** notify model has changed */
        fireTableDataChanged();
    }
    
    public void setAutoSave(boolean autoSave) {
        this.autoSave = autoSave;
    }
    
    public boolean isAutoSave() {
        return this.autoSave;
    }
    
    public int getColumnCount() {
        return (dt == null ? 0 : dt.getColumns().size());
    }
    
    public int getRowCount() {
        return (dt == null ? 0 : dt.getRowCount());
    }
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        return (dt == null ? null : dt.getValue(rowIndex, columnNames.get(columnIndex) ));
    }
    
    public void setValueAt(Object value, int row, int col) {
        
        if (dt == null) return;
        
        dt.setValue(row, columnNames.get(col), value);
        
        // save changes only if autoSave is true (it is by default)
        if (autoSave) {
            /**
             * It may be some troubles is autoSave is on, while trying to save
             * a non primary key column value before primary key is set, like in
             * a appended row.
             *
             * It can fails too with NOT NULL, Foreign Keys.
             **/
            dt.save();
        }
        
        //notify model has changed
        fireTableCellUpdated(row, col);
    }
    
    public String getColumnName(int columnIndex) {
        // if column Titles are setup, use it. If not, use column names from database.
        // columns titles are supposed to be more "human friendly"
        return columnTitles == null ? columnNames.get(columnIndex) : columnTitles[columnIndex];
    }
    
    public String[] getColumnTitles() {
        return columnTitles;
    }
    
    public void setColumnTitles(String[] columnTitles) {
        this.columnTitles = columnTitles;
    }
    
    public Class getColumnClass(int columnIndex) {
        return dt.getColumn(columnNames.get(columnIndex)).getType();
    }
    
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return !dt.getColumn( columnNames.get(columnIndex) ).isReadOnly();
    }
    
    public void populate() {
        if (dt == null) return;
        
        // clear DataTable and load again ...
        dt.refresh();
        
        // notify model has changed
        fireTableDataChanged();
    }
    
    public void save() {
        if (dt == null) return;
        
        dt.save();
    }
    
    public DataRow appendRow() {
        DataRow row = null;
        
        if (dt == null) return row;
        
        row = dt.appendRow();
 
        // notify model has changed
        fireTableRowsInserted(dt.getRowCount()-1, dt.getRowCount()-1);
        return row;
    }
    
    public void deleteRow(int rowIndex) {
        if (dt == null) return;
        
        dt.deleteRow(rowIndex);
        
        // notify model has changed
        fireTableRowsDeleted(rowIndex, rowIndex);
        return;
    }
 
    public void rowChanged(RowChangeEvent evt) {
        // must see what to do when DataRow changes
        System.out.println("rowChanged : " + evt.getEventType().toString());
    }
 
    public void tableChanged(TableChangeEvent evt) {
        // must see what to do when DataTable changes
        System.out.println("tableChanged : " + evt.getEventType().toString());
    }
}


Regards,
Diego.




 XML java.net RSS