Im trying to get a number of rows from a database to populate a JTable in a JFrame but its only getting the first row/entry (row 1 always). Its a list of houses + details stored in a table
public static DefaultTableModel buildTableModel(ResultSet rs)
throws SQLException {
ResultSetMetaData metaData = (ResultSetMetaData) rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount-1; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
How do I print out at all the rows in the table rather than just the first?
public void displaySaleProperties() throws SQLException{
Connection conn = null;
try {
conn = DriverManager.getConnection(CONN_STRING, USERNAME, PASSWORD);
System.out.println("Connected to database.");
// The Connection is obtained
Statement Stmt = (Statement) conn.createStatement();
// Stmt.execute(createPropertyTable);
ResultSet rs = Stmt.executeQuery("select * from PropertySale");
// It creates and displays the table
JTable table = new JTable(buildTableModel(rs));
table.setPreferredSize(new Dimension(1150,17));
// JOptionPane.showMessageDialog(null, new JScrollPane(table));
final JPanel panelOne = new JPanel();
panelOne.setVisible(true);
panelOne.setBackground(Color.LIGHT_GRAY);
// JFRAME
final JFrame topFrame = new JFrame();
topFrame.setSize(1200, 300);
topFrame.setLocationRelativeTo ( null );
topFrame.setVisible(true);
topFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// PUT TOGETHER
topFrame.add(panelOne);
panelOne.add(table);
panelOne.revalidate();
panelOne.repaint();
// Closes the Connection
} catch (SQLException e) {
System.err.println("Cannot connect to database." + e);
} finally {
if(conn != null){
conn.close();
}
}
}
Remove the line with:
table.setPreferredSize(new Dimension(1150,17));
In another way, may you want to use a scroll pane:
JTable table = new JTable(buildTableModel(rs));
JScrollPane scrollPane = new JScrollPane(table);
topFrame.add(scrollPane);
Related
I am reading data from SQL database and displaying it in a Jtable; then I am adding other columns and doing some calculations... The display time of data in Jtable is long even if the number of rows is low. Any hint pleaaaase?
public JTable display () throws ClassNotFoundException, SQLException, ParseException{
java.sql.Connection sqlConnection = null;
sqlConnection = getSQLConnection();
Statement stmt = null;
stmt = sqlConnection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT OFINTERNE,CMDCLIENT,CHAINE,REF,QTE,QTEBAC,DELAI,EFFECTIF,RENDEMENT,TPSn,"
+ "dateCreation,QTEPROD,datedebutpce,datedebutbac,datefinpce,termine from TEST_LAMIAA where OFINTERNE<3000 "
+ "order by chaine");
ResultSetMetaData rsmetaData = rs.getMetaData();
//stores the number of columns
int colmns = rsmetaData.getColumnCount();
// the object that will pass data to the jTable
DefaultTableModel dtm = new DefaultTableModel();
Vector cl_names = new Vector();
Vector data_rows = new Vector();
for(int i = 1; i<(colmns+1); i++){
cl_names.addElement(rsmetaData.getColumnName(i));
}
dtm.setColumnIdentifiers(cl_names);
while(rs.next()){
data_rows = new Vector();
for(int j = 1; j <(colmns+1) ; j++){
data_rows.addElement(rs.getString(j));
// System.out.println(rs.getString(j));
}
dtm.addRow(data_rows);
}
//pass default model object into my table
jTable1.setModel(dtm);
//adding columns
TableColumn col = new TableColumn(dtm.getColumnCount() - 1);
col.setHeaderValue("Sequence");
jTable1.addColumn(col);
dtm.addColumn(col);
TableColumn date = new TableColumn(dtm.getColumnCount() - 1);
date.setHeaderValue("Date");
jTable1.addColumn(date);
dtm.addColumn(date);
TableColumn duree = new TableColumn(dtm.getColumnCount() - 1);
duree.setHeaderValue("Duree");
jTable1.addColumn(duree);
dtm.addColumn(duree);
TableColumn datFin = new TableColumn(dtm.getColumnCount() - 1);
datFin.setHeaderValue("Date Fin");
jTable1.addColumn(datFin);
dtm.addColumn(datFin);
jTable1.setModel(dtm);
return jTable1;
}
currently I have data in MySQL server and I am calling the datas onto the JTable through JDBC. However there are 1369 rows and it seems that it has too much data for it to load. It usually takes 5 minutes to load. Are there anyways to optimize the process? This is my code(I apologize in advance for a messy code):
public class DataTable {
private String databaseName = "*****";
private String tableName = "******";
public void showDatabase(){
Connection conn = null;
DatabaseMetaData meta = null;
Statement stmt = null;
ResultSet rs = null;
int k = 0;
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String connectionUrl = "jdbc:mysql://localhost:3306/" + databaseName;
String connectionUser = "*****";
String connectionPassword = "*****";
conn = DriverManager.getConnection(connectionUrl, connectionUser, connectionPassword);
stmt = conn.createStatement();
meta = conn.getMetaData();
dataSets(stmt, meta);
}catch(Exception e){
e.printStackTrace();
} finally{
try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
//return the column size of the table
public int getColumnNumber(DatabaseMetaData meta, Statement stmt) throws SQLException
{
//ResultSet rs = meta.getColumns(null, null, "practiceexample", null);
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
return columnsNumber;
}
//return the rowNumber of the tables
public int getRowNumber(Statement stmt) throws SQLException
{
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
int rowCount = 0;
while(rs.next()){
rowCount = rs.getInt(1);
}
return rowCount;
}
public void dataSets(Statement stmt, DatabaseMetaData meta) throws SQLException
{
String[] columnNames = new String[getColumnNumber(meta, stmt)];
String[][] dataSets = new String[getRowNumber(stmt)][columnNames.length];
ResultSet column = meta.getColumns(null, null, tableName, null);
int i = 0;
while(column.next())
{
columnNames[i] = column.getString("COLUMN_NAME");
//columnNames.add(i, column.getString("COLUMN_NAME"));
i++;
}
for(int j = 0; j < dataSets.length; j++)
{
String[] singleRowData = new String[columnNames.length];
ResultSet data = null;
for(int k = 0; k < columnNames.length; k++)
{
String columnName = columnNames[k];
data = stmt.executeQuery("SELECT " + columnName +
" FROM " + tableName + " LIMIT " + j + ", " + 1);
while(data.next())
{
singleRowData[k] = data.getString(columnName);
}
}
dataSets[j] = singleRowData;
}
SimpleTable table = new SimpleTable(columnNames, dataSets);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
table.createAndShowGUI();
}
});
}
class SimpleTable{
String[] columns;
String[][] dataSets;
public SimpleTable(String[] columns, String[][] dataSets){
this.columns = columns;
this.dataSets = dataSets;
}
public void createAndShowGUI(){
JPanel gui = new JPanel(new BorderLayout(3, 3));
final JTable table = new JTable(new DefaultTableModel(dataSets, columns));
final JScrollPane scrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
Dimension dimension = table.getPreferredSize();
scrollPane.setPreferredSize(new Dimension(dimension.width, table.getRowHeight() * 30));
JPanel navigation = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton next = new JButton(">");
next.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
int height = table.getRowHeight() * (20-1);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getValue() + height);
}
});
JButton previous = new JButton("<");
previous.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int height = table.getRowHeight()*(20-1);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue( bar.getValue()-height );
}
} );
navigation.add(previous);
navigation.add(next);
gui.add(scrollPane, BorderLayout.CENTER);
gui.add(navigation, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
}
}
IMHO the root of the bad permormance is you unnecessarily query the database mutliple times to get the data (columns, rows, rows number, columns number, etc) you need:
To get columns number:
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
To get rows number:
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
To get rows (this is the worst beacuse it's inside a loop):
data = stmt.executeQuery("SELECT " + columnName + " FROM " + tableName + " LIMIT " + j + ", " + 1);
How to solve it
Just query the database once. A single ResultSet and its associated ResultSetMetaData should be enough to accomplish your goal. Additionaly, and as already suggested, use a SwingWorker to do database calls in a separate thread. For example:
final JTable table = new JTable();
SwingWorker<Void, TableModel> worker = new SwingWorker<Void, TableModel> () {
#Override
protected Void doInBackground() throws Exception {
ResultSet resultSet = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount(); // columns number
String[] columnNames = new String[columnCount];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = metaData.getColumnName(i); // fill columns names
}
resultSet.last();
int rowCount = resultSet.getRow(); // get rows number
resultSet.beforeFirst();
Object[][] data = new Object[rowCount][columnCount];
int currentRow = 0;
while (resultSet.next()) {
for (int currentColumn = 1; currentColumn <= columnCount; currentColumn++) {
data[currentRow][currentColumn - 1] = resultSet.getObject(currentColumn); // fill data set
}
currentRow++;
}
TableModel model = new DefaultTableModel(data, columnNames);
publish(model);
return null;
}
#Override
protected void process(List<TableModel> chunks) {
TableModel model = chunks.get(0);
table.setModel(model);
}
}
worker.execute();
i'm trying to display the data of a table in the form of a JTable.
My table is in Oracle 10g Express Edition.
T.name: Doctor
I want that the entire table should be displayed in my form with the help of a JTable.
class PatientTableFromDatabase extends JFrame
{
static Connection con=null;
Statement st=null;
ResultSet rs=null;
PatientTableFromDatabase()
{
Vector columnNames = new Vector();
Vector data = new Vector();
try
{
// Connect to the Database
try{
//Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//cn=DriverManager.getConnection("Jdbc:Odbc:pat");
Class.forName("oracle.jdbc.OracleDriver");
Connection con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1522:xe", "hr", "hr");
}
catch(Exception e)
{
//System.out.println(e);
e.printStackTrace();
}
// Read data from a table
String sql = "Select * from Doctor";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery( sql );
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
// Get column names
for (int i = 1; i <= columns; i++)
{
columnNames.addElement(md.getColumnName(i));
}
// Get row data
while (rs.next())
{
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement(rs.getObject(i));
}
data.addElement( row );
}
}
catch(Exception e)
{
System.out.println( e );
//e.printStackTrace();
}
// Create table with database data
JTable table = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add( scrollPane );
/* JPanel buttonPanel = new JPanel();
getContentPane().add( buttonPanel, BorderLayout.SOUTH );*/
}
public static void main(String[] args)
{
PatientTableFromDatabase frame = new PatientTableFromDatabase();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
when i run the frame appears but with no data,no table.
Please Help!!
Thanks
you sql query is empty
ResultSet rs = stmt.executeQuery( );
try with
ResultSet rs = stmt.executeQuery( sql);
You have two variables called con
The first one is the static one defined at the top of your class, and then you define it again in your try-catch block on line 21.
On line 34 you are using the uninitialized version of con and therefore you get the NullPointerException.
To fix this issue change the code to the following:
...
try{
//Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//cn=DriverManager.getConnection("Jdbc:Odbc:pat");
Class.forName("oracle.jdbc.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1522:xe", "hr", "hr");
}
catch(Exception e) {
e.printStackTrace();
}
...
connection = DriverManager.getConnection(URL, USER, PASSWORD);
Statement st = connection.createStatement();
ResultSet result = st.executeQuery("select * from department");
table_1.setModel(buildTableModel(result));
method:
public static DefaultTableModel buildTableModel(ResultSet rs)
throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
result:
You need to wrap your JTable inside a JScrollPane, and add the resulting JScrollPane to your layout.
The sample code you provided does not show how you're adding the JTable to the JPanel or JFrame of your application.
Found a solution:
I put a JScrollPane in jframe then use following code:
connection = DriverManager.getConnection(URL, USER, PASSWORD);
Statement st = connection.createStatement();
ResultSet result = st.executeQuery("select * from department");
JTable t=new JTable();
t.setModel(buildTableModel(result));
s1.setViewportView(t);
s1 is JScrollPane.
Output:
These are my codes for my jTable in java swing.
private JTable getJTable() {
if (jTable == null) {
Vector columnNames = new Vector(); //Vector class allows dynamic array of objects
Vector data = new Vector();
JPanel panel = new JPanel();
panel.setSize(new Dimension(198, 106));
try {
DBController db = new DBController();
db.setUp("IT Innovation Project");
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String dsn = "IT Innovation Project";
String s = "jdbc:odbc:" + dsn;
Connection con = DriverManager.getConnection(s, "", "");
String sql = "Select * from forumTopics";
java.sql.Statement statement = con.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
ResultSetMetaData metaData = resultSet.getMetaData();
int columns = metaData.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(metaData.getColumnName(i));
}
while (resultSet.next()) {
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(resultSet.getObject(i));
}
data.addElement(row);
}
resultSet.close();
((Connection) statement).close();
} catch (Exception e) {
System.out.println(e);
}
jTable = new JTable(data, columnNames);
TableColumn column;
for (int i = 0; i < jTable.getColumnCount(); i++) {
column = jTable.getColumnModel().getColumn(i);
column.setMaxWidth(250);
}
String header[] = {"description", "title", "category", "posted by"};
for(int i=0;i<jTable.getColumnCount();i++) {
TableColumn column1 = jTable.getTableHeader().getColumnModel().getColumn(i);
column1.setHeaderValue(header[i]);
}
jTable.setBounds(new Rectangle(82, 218, 736, 292));
jTable.setEnabled(false);
jTable.setRowHeight(50);
jTable.getRowHeight();
}
return jTable;
}
I set an array for the header of my table. However, the program only shows the data inside my database without any header. Can somebody please enlighten me? Thanks in advance.
Put your JTable in JScrollPane like
add(new JScrollPane( getJTable() ) );