So I'm currently working on a GUI for a school project, where we are making a Hotel Management System. Currently my task is to populate a jTable with some objects from our SQL database.
I have read up on it and the easiest way seems to be to use the defaulttablemodel, but I'm not sure how to incorporate that into my already existing GUI.
That is what my jForm currently looks like, not sure if that helps anyone at all, but at least it's a visual of what I'm trying to do.
And this is my "RoomMapper"
public class RoomMapper {
public ArrayList<Room> getRooms(Connection con) {
ArrayList<Room> rooms = new ArrayList();
String sqlString1
= "select * from room "
+ "order by room_id";
String sqlString2 = "SELECT TABLE_NAME FROM USER_TABLES";
PreparedStatement statement;
try {
statement = con.prepareStatement(sqlString1);
ResultSet rs = statement.executeQuery();
int i = 0;
while (rs.next()) {
i++;
System.out.println(rs.getString(1));
System.out.println("just added room nb " + i);
rooms.add(new Room(rs.getInt(1), rs.getInt(2), 0, "stringy string"));
}
statement.close();
} catch (Exception e) {
System.out.println("Fail in RoomMapper - getRooms");
System.out.println(e.getMessage());
}
System.out.println("rooms arraylist size: " + rooms.size());
return rooms;
}
}
Create a tablemodel
DefaultTableModel model = new DefaultTableModel();
Create headers
String[] headers = {"1", "2"};
Set headers
model.setColumnIdentifiers(headers);
Populate the model
model.addRow(new Object[]{room.get1(), room.get2()});
Set tablemodel to the table
Related
I have a JTable with 6 columns, the rows for the first 3 columns comes from table1(subject_records_bsit_first_year) and the last 3 will come from table2(evaluation_permission). The two database table have two joined columns(subject_code and subject_title). I'm trying to fill the last 3 columns of my JTable with data from table2—using the db table connection to display the right data.
My code:
public static void loadFirstYearSubjectList() {
ConnectionManager connectionManager = new ConnectionManager();
//String sqlChooseStudent = "SELECT * FROM student_bsit_"+studentID.toLowerCase() +" WHERE year_level = '"+yearLevel+"'";
try {
Connection con = connectionManager.createConnection();
Statement stmt = con.createStatement();
String sql = "SELECT * FROM `subject_records_bsit_first_year` ORDER BY `subject_records_bsit_first_year`.`trimester_period` ASC";
ResultSet rs = stmt.executeQuery(sql);
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.addColumn("Subject Code");
tableModel.addColumn("Subject Title");
tableModel.addColumn("Trimester");
tableModel.addColumn("Section");
tableModel.addColumn("Professor");
tableModel.addColumn("Evaluation");
table.setModel(tableModel);
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(0).setPreferredWidth(95);
columnModel.getColumn(1).setPreferredWidth(266);
columnModel.getColumn(2).setPreferredWidth(90);
columnModel.getColumn(3).setPreferredWidth(77);
columnModel.getColumn(4).setPreferredWidth(179);
columnModel.getColumn(5).setPreferredWidth(78);
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setBackground(new Color(120, 120, 120, 10));
renderer.setOpaque(true);
columnModel.getColumn(0).setCellRenderer(renderer);
columnModel.getColumn(1).setCellRenderer(renderer);
columnModel.getColumn(2).setCellRenderer(renderer);
columnModel.getColumn(3).setCellRenderer(renderer);
columnModel.getColumn(4).setCellRenderer(renderer);
columnModel.getColumn(5).setCellRenderer(renderer);
while (rs.next()) {
String subjectCode = rs.getString("subject_code");
String subjectTitle = rs.getString("subject_title");
String trimesterPeriod = rs.getString("trimester_period");
tableModel.addRow(new Object[] {subjectCode, subjectTitle, trimesterPeriod});
}
} catch (Exception e) {
} finally {
try {
connectionManager.closeConnection();
} catch (Exception e2) {
}
}
}
table 2 data
I'm trying to display the section, subject_teacher and evaluation_permission from this table, this table is joined from another table that already displays the first 3 columns on my jtable. The two db table is joined with the same column names; subject_code and subject_title.
Create your own implementation of TableModel that is able to retrieve the data as you described above. Then use JTable's setModel() to make the JTable actually use your TableModel implementation.
An example how to use it is in the Java tutorials.
SELECT subject_records_bsit_first_year.subject_code,
subject_records_bsit_first_year.subject_title,
subject_records_bsit_first_year.trimester_period,
evaluation_permission.section, evaluation_permission.subject_teacher,
evaluation_permission.permission_status
FROM subject_records_bsit_first_year
INNER JOIN evaluation_permission
ON subject_records_bsit_first_year.subject_code = evaluation_permission.subject_code;
Got what I'm trying to do, thanks for the help! Sometimes people learn from example.
I am trying to update a database from a dynamic JTable. Here is my code
try {
//open connection...
conn = javaConnect.ConnectDb();
//select the qualifications table row for the selected staffID
String sql2 = "select * from QualificationsTable where qualID =" + theRowID;
pStmt = conn.prepareStatement(sql2);
ResultSet rs2 = pStmt.executeQuery();
//check if QualificationsTable has content on that row...
if (rs2.next()) {
//it has content update...
//get the model for the qual table...
DefaultTableModel tModel = (DefaultTableModel) qualTable.getModel();
for (int i = 0; i < tModel.getRowCount(); i++) {
//get inputs from the tables
String qualification = tModel.getValueAt(i, 0).toString();
String yearAttained = tModel.getValueAt(i, 1).toString();
//sql query for updating qualifications table...
String sql3 = "update QualificationsTable set qualifications = ?, yearAttained = ? where qualID = ?";
pStmt = conn.prepareStatement(sql3);
//set the pareameters...
pStmt.setString(1, qualification);
pStmt.setString(2, yearAttained);
pStmt.setInt(3, theRowID);
//execute the prepared statement...
pStmt.execute();
// dbStatement.executeUpdate("INSERT INTO tableName VALUES('"+item+"','"+quant+"','"+unit+"','"+tot+"')");
}
//close connection
conn.close();
JOptionPane.showMessageDialog(null, "Qualifications updated successfully!", "Success", INFORMATION_MESSAGE);
} else {
//it doesnt have content insert...
//get the model for the qual table...
DefaultTableModel tModel = (DefaultTableModel) qualTable.getModel();
for (int i = 0; i < tModel.getRowCount(); i++) {
//System.out.println(tModel.getSelectedColumn()+tModel.getSelectedRow());
//get inputs from the tables
String qualification = tModel.getValueAt(i, 0).toString();
String yearAttained = tModel.getValueAt(i, 1).toString();
//sql query for storing into QualificationsTable
String sql3 = "insert into QualificationsTable (qualifications,yearAttained,qualID) "
+ "values (?,?,?)";
pStmt = conn.prepareStatement(sql3);
//set the parameters...
pStmt.setString(1, qualification);
pStmt.setString(2, yearAttained);
pStmt.setInt(3, theRowID);
//execute the prepared statement...
pStmt.execute();
}
//close connection
conn.close();
JOptionPane.showMessageDialog(null, "Qualifications saved successfully!", "Success", INFORMATION_MESSAGE);
}
} catch (SQLException ex) {
Logger.getLogger(StoreInfo.class.getName()).log(Level.SEVERE, null, ex);
} catch(NullPointerException nfe){
JOptionPane.showMessageDialog(infoParentTab, "Please, always hit the Enter button to effect your changes on the table", "USER ERROR!", ERROR_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(infoParentTab, "You must select a Staff from the Browser...", "USER ERROR!", ERROR_MESSAGE);
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e);
e.printStackTrace();
}
what i am actually trying to do is to use a table linked to a database to store qualifications of staff in a company. now each entry in the qualifications database is referenced to the staffID in the staffs database through qualID.
so when i store the qualification on the table, it also records the staff that has the qualification. this should enable me retrieve a particular staff's qualifications from the database when need.
the segment for inserting into the database if empty works fine (i.e. the else... segment). but the update segment (i.e. the if... segment) is faulty in the sense that the code uses the last row on the JTable to populate all the rows in the database table instead of replicating all the new changes into the database table when update is need.
i have tried everything i could to no avail. please i need much help in this...time is not on my side. tnx guys in advance
The best way to do this is to use a CachedRowSet to back up the JTable's model. You'll be able to view, insert and update data easily.
Here's the tutorial: Using JDBC with GUI API
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();
}
}
});
I try to select certain row from jTable and perform a deletion then the jTable will be updated with the latest data in database. This is how I set up jTable :
private JTable getJTableManageReplies() {
jTableManageReplies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTableManageReplies.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(
viewRow, 0).toString());
eForumRepliesAdmin reply = new eForumRepliesAdmin(replyID);
replyID = JOptionPane.showConfirmDialog(null, "Are you sure that you want to delete the selected reply? " , "Delete replies", JOptionPane.YES_NO_OPTION);
if(replyID == JOptionPane.YES_OPTION){
reply.deleteReply();
SetUpJTableManageReplies();}
}
}
});
return jTableManageReplies;
}
public void SetUpJTableManageReplies() {
DefaultTableModel tableModel = (DefaultTableModel) jTableManageReplies
.getModel();
String[] data = new String[5];
db.setUp("IT Innovation Project");
String sql = "Select forumReplies.reply_ID,forumReplies.reply_topic,forumTopics.topic_title,forumReplies.reply_content,forumReplies.reply_by from forumReplies,forumTopics WHERE forumReplies.reply_topic = forumTopics.topic_id ";
ResultSet resultSet = null;
resultSet = db.readRequest(sql);
tableModel.getDataVector().removeAllElements();
try {
while (resultSet.next()) {
data[0] = resultSet.getString("reply_ID");
data[1] = resultSet.getString("reply_topic");
data[2] = resultSet.getString("topic_title");
data[3] = resultSet.getString("reply_content");
data[4] = resultSet.getString("reply_by");
// Add data to table model
tableModel.addRow(data);
}
resultSet.close();
} catch (Exception e) {
System.out.println(e);
}
}
And this is my codes to perform deletion from database :
public boolean deleteReply() {
boolean success = false;
DBController db = new DBController();
db.setUp("IT Innovation Project");
String sql = "DELETE FROM forumReplies where reply_ID = " + replyID
+ "";
if (db.updateRequest(sql) == 1)
success = true;
db.terminate();
return success;
}
However, there is an error message which is ArrayIndexOutOfBound right after I add the SetUpJTableManageReplies methos in the jDialog box. I try to do like when user select certain row, there will be a pop out to ask for confirmation of deletion. Then right after they click on yes, the jTable data will be refreshed. Can somebody give me some guides? Thanks in advance.
Your Problem is here:
tableModel.getDataVector().removeAllElements();
Better:
tableModel.setRowCount(0);
Much better: write your own table model and implement all methods which are defined in TableModel interface - so you can learn how to deal with the JTable component
Use TableModel to manage table data. DefaultTableModel will be useful, you should first create tableModel, then create JTable and set table's model to previously created table model.
You should perform insert/delete/update to table cells using model, which will update JTable automatically. Use DefaultTableModel to manage your data.
I'm populating data from my database into my JTable. After I add new data and press Refresh button, I want to remove the existing row displayed on table before retrieving the new data. How can I remove the existing row?
Here is the original table with data [a,1].
This is the table after I add new data [b,1] and press refresh button. The original data [a,1] is still shown in the table:
JButton refreshButton = new JButton("Refresh");
refreshButton.setBounds(188, 248, 101, 23);
panel.add(refreshButton);
refreshButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
DefaultTableModel model = new DefaultTableModel(data,columnNames);
int rowCount = model.getRowCount();
for (int x = 0; x <=rowCount; x++)
{
model.removeRow(x);
}
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/watchlist","root","root");
String sql = "SELECT * FROM watchlist";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
while (rs.next())
{
Vector row = new Vector(columns);
for (int i=1; i <= columns; i++)
{
row.addElement( rs.getObject(i) );
System.out.println( rs.getObject(i).toString());
}
data.addElement(row);
table.revalidate();
table.repaint();
panel.repaint();
} // end while
} // end try
catch (Exception e){
}
}
});
I think that I saw this question,
1) search for ResultsetTableModel / TableFromDatabase (better)
(if Database Connection (so hard and lazy action) isn't closed during Applications lifecycle)
a) replace JTable contents
b) works with embeded Db of database placed in intranet immediatelly
dis
all processes is durring EDT, then GUI waiting for SQL statement
for most code examples required to move Xxx.close to the finally block
2) most complex workaround you have to use SwingWorker, better and easiest way is to load data from Runnable#Thread
3) you can remove row(s) from TableModel,
You can either remove the row (see DefaultTableModel.removeRow)
or put the new data into a new table model, and replace the table's table model with JTable.setModel()
Upon refreshing button, call the following:
DefaultTableModel model = new DefaultTableModel(data,col);
model.removeRow(1); // first row in this case
In this case you need to manage to get the data , columns and the row count.Data is your actual data, col is the number of columns.
enter image description here
this method i used to populte data in any jTbale
it clear jtable (refresh ) jtable befor populte new data
this line cleare jatble befor populate data
mytable.setModel(new DefaultTableModel(null, colname));
public static void FilltableV(JTable mytable, String sql){
Connection con = null;
Statement Cmd = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/alserg", "root", "");
sql="SELECT * FROM products";
Cmd=con.createStatement();
rs=Cmd.executeQuery(sql);
ResultSetMetaData rsmt=rs.getMetaData();
int colno =rsmt.getColumnCount();
Vector colname =new Vector();
DefaultTableModel mytab =new DefaultTableModel();
Vector rows =new Vector();
for(int i=1 ;i< colno;++i){
colname.addElement(rsmt.getColumnName(i));
mytab.setColumnIdentifiers(colname);
}
while (rs.next()){
rows= new Vector();
for (int j=1;j<colno;++j){
rows.addElement(rs.getString(j));
}
mytab.addRow(rows);
mytable.setModel(new DefaultTableModel(null, colname));
mytable.setModel(mytab);
}
} catch (SQLException ex) {
Logger.getLogger(products.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
try {
rs.close();
Cmd.close();
con.close();
} catch (SQLException ex) {
Logger.getLogger(AlseragLang.class.getName()).log(Level.SEVERE, null, ex);
}
}
}