I have a JTable
which is being fed from a database. I have a custom model for the table - ResultSetTableModel
. The model is as follows:
public class ResultSetTableModel extends AbstractTableModel {
private String[] columnNames;
private Class[] columnClasses;
private List<List<Object>> cells = new ArrayList<List<Object>>();
public ResultSetTableModel() {
columnNames = new String[1];
columnNames[0] = "Result Set";
List<Object> row = new ArrayList<Object>();
row.add("No data");
cells.add(row);
}
public ResultSetTableModel(ResultSet rs) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
// SOMETHING TO KEEP AN EYE ON! It looks like the ResultSetMetaData
// object screws up once the ResultSet itself has been read (ie by
// rs.next() ). Putting any rsmd.XXXX commands after the "while" loop at
// the bottom throws a nasty exception. A bug on the SQLite side I
// think.
columnNames = new String[rsmd.getColumnCount()];
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
columnNames[i - 1] = rsmd.getColumnName(i);
}
columnClasses = new Class[rsmd.getColumnCount()];
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
int columnType = rsmd.getColumnType(i);
switch (columnType) {
case java.sql.Types.INTEGER:
case java.sql.Types.NUMERIC:
columnClasses[i - 1] = Integer.class;
break;
case java.sql.Types.VARCHAR:
case java.sql.Types.CHAR:
case java.sql.Types.DATE:
columnClasses[i - 1] = String.class;
break;
case java.sql.Types.DECIMAL:
case java.sql.Types.FLOAT:
columnClasses[i - 1] = Float.class;
default:
columnClasses[i - 1] = Object.class;
break;
}
}
while (rs.next()) {
List<Object> row = new ArrayList<Object>();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
row.add(rs.getString(i));
}
cells.add(row);
}
}
public int getRowCount() {
return cells.size();
}
public int getColumnCount() {
return columnNames.length;
}
@Override
public Class getColumnClass(int columnIndex) {
if (columnClasses != null) {
return columnClasses[columnIndex];
} else {
return Object.class;
}
}
public boolean isEmpty() {
return cells.isEmpty();
}
public Object getValueAt(int rowIndex, int columnIndex) {
return cells.get(rowIndex).get(columnIndex);
}
@Override
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
public void deleteRowDisplay(int index){
this.cells.remove(index);
}
public void deleteRow(String username, String query,int indexOndisplay) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/duno",
"root", "3498");
Statement statement = connection.createStatement();
statement.executeUpdate(query);
} catch (ClassNotFoundException | SQLException e) {
System.out.println(e.getMessage());
}
this.deleteRowDisplay(indexOndisplay);
this.fireTableRowsDeleted(indexOndisplay, indexOndisplay);
}
}
Now my data is displayed correctly.
Problem: The only problem is that when the table is being displayed none of the rows has focus. Below is the image showing this (showing test data).
I have tried to use table.setRowSelectionInterval(0, 0);
to set focus/selection to the first row and it worked.However, I have a delete
button which when I click will delete the row both from the database and the display. Once the row is removed from display the focus is lost again.
Question How do I set the focus/selection to the first row in the display even after deleting a row?
Below is the code to delete a row.
this.delete
.addActionListener((ActionEvent) -> {
if(!this.rm.isEmpty()){
String username = this.table.getValueAt(
this.table.getSelectedRow(), 2).toString();
String query="DELETE FROM users WHERE username='"
+ username + "'";
int index=this.table.convertRowIndexToModel(this.table.getSelectedRow());
int selection = JOptionPane.showConfirmDialog(null,
"Do you want to remove :\t " + username
+ "\t in the System?", "Warning",
JOptionPane.OK_CANCEL_OPTION);
if (selection == JOptionPane.OK_OPTION) {
rm.deleteRow(username,query,index);
JOptionPane.showMessageDialog(parent, "Record Deleted!");
this.table.requestDefaultFocus();//I have tried this but nothing happens
this.table.changeSelection(0, 0, false, false);
} else {
// do nothing
}}else{
JOptionPane.showMessageDialog(parent, "No Record To Deleted!");
}
});