patternjavaMinor
Table model code style
Viewed 0 times
codestylemodeltable
Problem
This is my table model code style:
Is this best way?
What is this way problems?
Any idea to be better?
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 ownIs 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:
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:
I've created TableContent just to wrap the result:
Now, the TableModel. That way you don't need to extend the class DefaultTableModel, you can simply instantiate one:
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.
- 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.