HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Table model code style

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
codestylemodeltable

Problem

This is my table model code style:

public class MyModel extends DefaultTableModel {

static Vector data = new Vector();
static Vector column = new Vector();
Connection conn;
Statement statement;
ResultSet result;

public MyModel() {
super(data, column);
try {
    conn = DriverManager.getConnection(...);
    statement = conn.createStatement();
    result = statement.executeQuery("Select * from table");

    int col = result.getMetaData().getColumnCount();
    for (int i = 1; i <= col; i++) {
        column.add(result.getMetaData().getColumnName(i));
    }

    while (result.next()) {
        Vector newRow = new Vector(col);
        for (int i = 1; i <= col; i++) {
            newRow.add(result.getString(i));
        }
        data.add(newRow);
    }

} catch (SQLException e) {
    e.printStackTrace();
} 
}
// create methods for remove and add and edit a JTable selected row

}

//My GUI class that show jtable on own


Is this best way?

What is this way problems?

Any idea to be better?

Solution

This way your software is highly coupled. I can see three big responsibilities in it:

  • Get data from db



  • Format data in "TableModel way"



  • Create TableModel



Let's create a class to get data. I don't like the idea of let other classes deal with objects from jdbc api, so this class will format data too:

public class TableData {

    public TableContent getData() {
        Vector headers = new Vector();
        Vector> content = new Vector>();

        try {
            Connection conn = DriverManager.getConnection("");
            Statement statement = conn.createStatement();
            ResultSet rs = statement.executeQuery("Select * from table");

            headers = buildHeaders(rs);
            content = buildContent(rs);

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return new TableContent(headers, content);
    }

    private Vector buildHeaders(final ResultSet rs) throws SQLException {
        Vector headers = new Vector();

        int col = rs.getMetaData().getColumnCount();
        for (int i = 1; i > buildContent(final ResultSet rs) throws SQLException {
        Vector> content = new Vector>();

        while (rs.next()) {
            int col = rs.getMetaData().getColumnCount();
            Vector newRow = new Vector(col);

            for (int i = 1; i <= col; i++) {
                newRow.add(rs.getString(i));
            }
            content.add(newRow);
        }
        return content;
    }
}


I've created TableContent just to wrap the result:

public class TableContent {

    private final Vector headers;
    private final Vector> content;

    public TableContent(final Vector headers, final Vector> content) {
        this.headers = headers;
        this.content = content;
    }

    public Vector headers() {
        return headers;
    }

    public Vector> content() {
        return content;
    }
}


Now, the TableModel. That way you don't need to extend the class DefaultTableModel, you can simply instantiate one:

TableContent data = new TableData().getData();
new DefaultTableModel(data.headers(), data.content());


The class TableData still has a problem, the ideal would be to receive the Connection by the constructor, because without it, it's not possible to test the class with unit tests. I didn't wanna make the solution more difficult.

Code Snippets

public class TableData {

    public TableContent getData() {
        Vector<String> headers = new Vector<String>();
        Vector<Vector<String>> content = new Vector<Vector<String>>();

        try {
            Connection conn = DriverManager.getConnection("");
            Statement statement = conn.createStatement();
            ResultSet rs = statement.executeQuery("Select * from table");

            headers = buildHeaders(rs);
            content = buildContent(rs);

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return new TableContent(headers, content);
    }

    private Vector<String> buildHeaders(final ResultSet rs) throws SQLException {
        Vector<String> headers = new Vector<String>();

        int col = rs.getMetaData().getColumnCount();
        for (int i = 1; i <= col; i++) {
            headers.add(rs.getMetaData().getColumnName(i));
        }
        return headers;
    }

    private Vector<Vector<String>> buildContent(final ResultSet rs) throws SQLException {
        Vector<Vector<String>> content = new Vector<Vector<String>>();

        while (rs.next()) {
            int col = rs.getMetaData().getColumnCount();
            Vector<String> newRow = new Vector<String>(col);

            for (int i = 1; i <= col; i++) {
                newRow.add(rs.getString(i));
            }
            content.add(newRow);
        }
        return content;
    }
}
public class TableContent {

    private final Vector<String> headers;
    private final Vector<Vector<String>> content;

    public TableContent(final Vector<String> headers, final Vector<Vector<String>> content) {
        this.headers = headers;
        this.content = content;
    }

    public Vector<String> headers() {
        return headers;
    }

    public Vector<Vector<String>> content() {
        return content;
    }
}
TableContent data = new TableData().getData();
new DefaultTableModel(data.headers(), data.content());

Context

StackExchange Code Review Q#30330, answer score: 5

Revisions (0)

No revisions yet.