0

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).

enter image description here

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!");
                }
            });
CN1002
  • 1,115
  • 3
  • 20
  • 40
  • 1
    You need to write an implementation of the `ListSelectionListener`, which makes the first row selected, when selection is empty. Use `table.getSelectionModel().addListSelectionListener()` to attach your listener to your table. – Sergiy Medvynskyy Apr 10 '15 at 11:35
  • @SergiyMedvynskyy Well I have tried this ` public void valueChanged(ListSelectionEvent e) { ListSelectionModel lsm = (ListSelectionModel)e.getSource(); if(lsm.isSelectionEmpty()){ lsm.setSelectionInterval(0,0); } }` but only the first row is selected at first when displaying the table. Once the delete a row focus is lost again. You may provide a sample code to assist me. – CN1002 Apr 10 '15 at 12:18
  • 1
    For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). And don't put code snippets in comments where they are unreadable.. – Andrew Thompson Apr 10 '15 at 12:22
  • @Giovanrich Just type in Google "`ListSelectionListener` tutorial". – Guillaume Polet Apr 10 '15 at 12:34
  • Well I got it through following Luna's answer [here](http://stackoverflow.com/questions/11365294/how-to-set-focus-to-the-first-row-in-a-jtable-which-is-inside-a-jscrollpane). At first I made a mistake of using it on another table instead of the one that I wanted - hence the comment above. – CN1002 Apr 10 '15 at 12:53
  • @GuillaumePolet It is what I usually do when I encounter a problem. In this case I got [this](http://stackoverflow.com/questions/11365294/how-to-set-focus-to-the-first-row-in-a-jtable-which-is-inside-a-jscrollpane) but had used it on a wrong table - I have two tables. Anyway it is a good reminder :)- – CN1002 Apr 10 '15 at 13:00

0 Answers0