I have done enough searches to solve my problem which i have done partly but there's this one bug that keeps disturbing me.I am trying to fetch data from a database based on a condition.I have a table 'user_branch' with a foreign key column branchID which is supposed to fetch the coresponding branchNames in another table 'branches' and I am supposed to display the results into a JTable.When i do System.out.println i get all my results but it returns only the last row when i display in a JTable(branchJTable).This is the code i am using
int row = user2BAssignedJTable.getSelectedRow();
assignUserID.setText(user2BAssignedJTable.getModel().getValueAt(row, 0).toString());
user2BAssignedField.setText(user2BAssignedJTable.getModel().getValueAt(row, 1).toString());
try {
String userBrQry = "SELECT branchID FROM user_branch WHERE userID IN(?) ";
String brQ = "SELECT branchName FROM branches WHERE branchID IN(%s) ";
pstmt = con.prepareStatement(userBrQry);
pstmt.setString(1, assignUserID.getText());
results = pstmt.executeQuery();
results.last();
int nRows = results.getRow();
results.beforeFirst();
while (results.next()) {
String branchIDS = results.getString("branchID");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < nRows; i++) {
builder.append("?");
if (i + 1 < nRows) {
builder.append(",");
}
}
brQ = String.format(brQ, builder.toString());
PreparedStatement ps = con.prepareStatement(brQ);
for (int i = 0; i < nRows; i++) {
ps.setString(i + 1, branchIDS);
}
ResultSet rs = ps.executeQuery();
//branchJTable.setModel(DbUtils.resultSetToTableModel(rs));
javax.swing.table.DefaultTableModel model = new javax.swing.table.DefaultTableModel();
model.setColumnIdentifiers(new String[]{"Branch Name"});
branchJTable.setModel(model);
while (rs.next()) {
String branchname = rs.getString("branchName");
model.addRow(new Object[]{branchname});
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
Forget about the first 3 rows as it is a another JTable event i use to get the userID to use as a condition for getting a particular user's branches assigned to him.
The branches assigned to a user is dynamic hence using StringBuilder.
I am supposed to display the results into another JTable called branchJTable which only displays the last row.Any HELP would be appreciated!
From your question, I think you should declare the JTable
javax.swing.table.DefaultTableModel model = new javax.swing.table.DefaultTableModel();
model.setColumnIdentifiers(new String[]{"Branch Name"});
branchJTable.setModel(model);
before your first loop -
i.e. before while (results.next()) { in your code.
Otherwise in loop, for each loop execution,
the JTable Model is initialising and you are getting the last inserted row in Jtable.
Related
I've looked through this forum and searched the web for a solution to my above problem but could not find something that points me in the right direction. Please forgive me if this is a duplication.
I'm working on a java project where my application interacts with an MS Access 2016 database. One of the functions of my program is to query the db for a specific record and display the data of that record in a gui. Here is my code to retrieve the data:
int i = 0;
String q = "select * from QueryData where id=123456";
try {
pstmnt=conn.prepareStatement(q);
Object obj ;
rs = pstmnt.executeQuery();
while (rs.next()) {
obj=rs.getObject(i+1);
data.add(obj); //where data is a List object i++;
}
} catch ....
Problem is I only get the first value in this record (1st column of record) and there are more data available in the record/row.
Could it be the rs.next() method that is doing this and if so, what should I use to get the next value in this specific record?
ResultSet#next() iterates over the rows in the result set (which, in this case, is just a single row). If you don't know the result set's structure upfront, you can dynamically deduce it from a ResultSetMetaData object:
int i=0;
String q="select * from QueryData where id=123456";
try (PreparedStatement pstmnt = conn.prepareStatement(q);
ResultSet rs = pstmnt.executeQuery()) {
ResultSetMetaData rsmd = rs.getMetaData();
// Assume it's just one row.
// If there's more than one, you need a while loop
if (rs.next()) {
for (int i = 0; i < rsmd.getColumnCount(); ++i) {
data.add(rs.getObject(i + 1));
}
}
}
I have developed below code,
try{
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/online_store","username","password");
if(con != null){
String query = "SELECT * FROM expense";
rs = stmt.executeQuery(query);
ResultSetMetaData rsmt = rs.getMetaData();
int c = rsmt.getColumnCount();
Vector column = new Vector(c);
for(int i = 1; i <= c; i++) { column.add(rsmt.getColumnName(i)); }
Vector data = new Vector(); Vector row = new Vector();
while(rs.next())
{
row = new Vector(c);
for(int i = 1; i <= c; i++)
{
row.add(rs.getString(i));
}
data.add(row);
}
expense_table.add(data);
// expense_table.getColumnName(null);
JOptionPane.showMessageDialog(null, "get details from database");
}
}catch(SQLException ex){
System.out.println(ex);
}
My existing table's name is expense_table. I need to display all the records from database in this table without change its structure/without creating new table.Everything is ok except showing data(rows) vector in table which is " expense_table.add(data);" line. Please tell me is there any method to to this.
I need to display all the records from database in this table without change its structure/without creating new table.
So then you don't need to access the column names from the ResultSet. You just need to add new rows of data to the JTable. So get rid of the logic that creates the "column" Vector.
//expense_table.add(data);
You can't add a Vector to a JTable. There is no method that allows you to do this so get rid of that statement.
Instead you need to add the data to the DefaultTableModel one row at a time:
//data.add(row);
DefaultTableModel model = (DefaultTableModel)expense_table.getModel();
model.addRow( row );
Excuse me. I want to show all records in JTable. But I get confused because my coding just show 1 record. When I click it again, that just show same records.
Can you help me how to get all records?
try {
Statement stmt;
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM menu");
if (rs.next()) {
String menu_id = rs.getString("menu_id");
String menu_type = rs.getString("menu_type");
String menu_cat = rs.getString("menu_cat");
String menu_name = rs.getString("menu_name");
String menu_price = rs.getString("menu_price");
DefaultTableModel model = (DefaultTableModel) tblMenu.getModel();
model.addRow(new Object[]{menu_id, menu_type, menu_cat, menu_name, menu_price});
}
} catch (Exception e) {
System.out.println("Failed " + e);
}
I have no Idea how to code it. Thank you
Change
if (rs.next())
to
while (rs.next())
to run to the code block not just once, but till the end of the ResultSet.
It should actually look like this
DefaultTableModel model = (DefaultTableModel) tblMenu.getModel();
while (rs.next()) {
String menu_id = rs.getString("menu_id");
String menu_type = rs.getString("menu_type");
String menu_cat = rs.getString("menu_cat");
String menu_name = rs.getString("menu_name");
String menu_price = rs.getString("menu_price");
model.addRow(new Object[]{menu_id, menu_type, menu_cat, menu_name, menu_price});
}
Try this
String[] cols={"id","type","cat","name","price"};
ArrayList<String[]> list = new ArrayList<String[]>();
while (rs.next()) {
String menu_id = rs.getString("menu_id");
String menu_type = rs.getString("menu_type");
String menu_cat = rs.getString("menu_cat");
String menu_name = rs.getString("menu_name");
String menu_price = rs.getString("menu_price");
list.add(new String[]{menu_id, menu_type, menu_cat, menu_name, menu_price});
}
String[][] elts= new String[list.size()][];
elts = list.toArray(elts);
JTable table = new JTable(elts,cols);
JScrollPane pane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
frame.getContentPane().add(pane);
You have used if(rs.next()) you know that if condition checked if it is true or false.
rs.next()
shifts the cursor to the next row of the result set from the database and returns true if there is any row, otherwise false. In combination with the if statement (instead of the while) this means that you expecting in only one row. simply,
rs.next()
check for next row if it is exist if condition passed and do the code block and get out from the block run the rest of the code.
As to the concrete question about iterate through the database table and add all to the jTable. You only have to change one keyword,
if to while
What happens when you use while keyword instead if keyword is that rs.next() check for next row and if it is true then condition true for while loop and go through the code block and when block is finish again check for next row. Likewise go through the all rows in your table and condition will fail after last row.
Im trying to write a code in which when a user will click an a "Sort by Name" button, my program will sort the records of my Database and put them in a JTable,combining 2 DB Tables with INNER JOIN. I have managed to do this by using a resultSet and selecting for example Ascending Order. But because I dont want to have 2 buttons, one for the ASC and one for the DESC, I thought of using preparedStatement and an showInputDialog in which the user will select if he wants to have an ASC or a DESC ordering and execute the order. Also, I remembered that some programs I've seen used a feature in which the first time you clicked the button it sorted DESC and if you pressed it again would order by ASC(havent managed to find in on the WEB).About my first thought, I tried to do it but I could get past this one
ResultSetMetaData mdsort = rssort.getMetaData();
I should have an ResultSet variable(rssort) to use getMetaData() but if I selected to make the program with my PreparedStatement i would get an error there. Any suggestions??
try{
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
Statement stmtsort = conn.createStatement();
ResultSet rssort = stmtsort.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ASC");
// ERROR HERE!!! needs resultset,not preparedStatement
ResultSetMetaData mdsort = rssort.getMetaData();
columnCount = mdsort.getColumnCount();
String[] colssort = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssort[i-1] = mdsort.getColumnName(i);
}
DefaultTableModel model = new DefaultTableModel(colssort,0);
while (rssort.next())
{
Object[] rowsort = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsort[i-1] = rssort.getObject(i);
}
model.addRow(rowsort);
}
JTable table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true);
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(218,59,529,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsort.close();
rssort.close();
} catch (SQLException case1)
{case1.printStackTrace();
} catch (Exception case2)
{case2.printStackTrace();}
}
});
UPDATE
OK I managed to fix this issue with the getMetaData() but now the thing is that I dont use any ResultSet variables/instances and cant use next() method to create my DB.
String name = "SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ?";
PreparedStatement psname = conn.prepareStatement(name);
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
psname.setString(1,strin);
psname.executeUpdate();
ResultSetMetaData mdsort = psname.getMetaData();
int columnCount = mdsort.getColumnCount();
.
.
.
// error coming up here,because i deleted the ResultSet
while (psname.next())
.
.
.
Better make a bit more complex TableModel.
That is more optimal.
Keep the data from the ResultSet in an original TableModel.
Use a wrapping TableModel to sort, and maybe filter.
Use the ResultSetMetaData for the column type, if it is Number (Integer, BigDecimal, ...) then use that type instead of Object for the column type: gives a right aligned column.
Maybe first do an internet search for ResultSetTableModel; other peoply must have done it already.
try{
conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
stmtsortname = conn.createStatement();
rssortname = stmtsortname.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name "+strin);
mdsortname = rssortname.getMetaData();
columnCount = mdsortname.getColumnCount();
String[] colssortname = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssortname[i-1] = mdsortname.getColumnName(i);
}
model = new DefaultTableModel(colssortname,0);
while (rssortname.next())
{
Object[] rowsortname = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsortname[i-1] = rssortname.getObject(i);
}
model.addRow(rowsortname);
}
table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true)
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(146,59,763,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsortname.close();
rssortname.close();
} catch (SQLException case1)
{
case1.printStackTrace();
}
catch (Exception case2)
{
case2.printStackTrace();
}
}
});
tb_records = jtable name
records = table name inside my database
Date = my first column
hey = substitute for my real password
mydatabase = name of my database
My problem is that, when I highlight a row in my JTable and delete it, it deletes all the rows. I want to delete the selected row only. Here's my code:
int row = tb_records.getSelectedRow();
DefaultTableModel model= (DefaultTableModel)tb_records.getModel();
String selected = model.getValueAt(row, 0).toString();
if (row >= 0) {
model.removeRow(row);
try {
Connection conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "hey");
PreparedStatement ps = conn.prepareStatement("delete from records where Date='"+selected+"' ");
ps.executeUpdate();
}
catch (Exception w) {
JOptionPane.showMessageDialog(this, "Connection Error!");
}
}
What could be the problem here? How can I delete a selected row in my database and not all the rows?
DefaultTableModel model = (DefaultTableModel) jTable.getModel();
int row = jTable.getSelectedRow();
String eve = jTable.getModel().getValueAt(row, 0).
String delRow = "delete from user where id="+eve;
try {
ps = myCon.getConnection().prepareStatement(delRow);
ps.execute();
JOptionPane.showMessageDialog(null, "Congratulation !!");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
1) Don't display your own message. Display the error message from the Exception as it will give a better explanation what the problem is.
2) Use a proper PreparedStatement for the SQL. You are less likely to make syntax errors. Something like:
String sql = "delete from records where Date= ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString( 1, selected );
stmt.executeUpdate();
I don't know much about SQL but maybe you need to pass a Date object not a String object since your where clause is using a Date?
The OP wrote:
SOLUTION: Pick a column with unique values. My Date column has the same values that's why it's deleting all my rows even though I set my row as getSelectedRow. Time_in = my 4th column with unique values.
change
String selected = model.getValueAt(row, 0).toString();
to
String selected = model.getValueAt(row, 3).toString();
and
PreparedStatement ps = conn.prepareStatement("delete from records where Date='"+selected+"' ");
to
PreparedStatement ps = conn.prepareStatement("delete from records where Time_in='"+selected+"' ");