javaswingjtabletablemodelaction-interface

access table model swing


I wanted to make my application nicely, without 100 inner classes and stuff. I have class that holds some lists with data. I have menu, with items that use AbstractActions, eg. I wanted to have and action in there to delete selected item from table. For that I need references for both table and table model. I want to add this action to menu item, I would need to pass there references on table and table model that are created later as I do like this:

    MainMenuBar menuBar = new MainMenuBar(db);
    MainTabbedPane tabbedPane = new MainTabbedPane(db);

    this.setLayout(new BorderLayout());
    add(menuBar, BorderLayout.PAGE_START);
    add(tabbedPane, BorderLayout.CENTER);

where tabbedPane has 2 tabs with 2 tables. So any help how to do this in a nice way?


Solution

  • It would be nice if JTable supported generics, it would make life much easier, but it doesn't so we don't have much choice.

    One solution would be to take advantage of the Actions API, which would allow you to define a series of self contained "actions" which can be applied to menus, buttons and key bindings equally.

    For example...

    public abstract class AbstractTableAction<M extends TableModel> extends AbstractAction {
        private JTable table;
        private M model;
    
        public AbstractTableAction(JTable table, M model) {
            this.table = table;
            this.model = model;
        }
    
        public JTable getTable() {
            return table;
        }
    
        public M getModel() {
            return model;
        }
    }
    

    Then you can define more focused actions...

    public class DeleteRowAction extends AbstractTableAction<MutableTableModel> {
        public DeleteRowAction (JTable table, MutableTableModel model) {
            super(table, model);
            putValue(NAME, "Delete selected row(s)");
        }
    
        public void actionPerformed(ActionEvent evt) {
            JTable table = getTable();
            int rows[] = table.getSelectedRows();
            for (int index = 0; index < rows.length; index++) {
                rows[index] = table.convertRowIndexToModel(rows[index]);
            }
            getModel().removeRows(rows);
        }
    }
    

    Now, obviously, MutableTableModel is just example, but is a particular implementation of TableModel that provides the functionality that you need.

    This approach would allow you to apply these actions to JMenuItem, JButton and key bindings, meaning you could, for example, assign the Action to the Delete, so that when pressed when a table has focus, the Action would be triggered

    You could further abstract the concept by defining some kind of controller which provided access to the current table/model, so you would only need to create a single series of Actions, which took the "controller" as a reference. The controller then would provide context to the current state of the view/program (that is, which table/model was currently active) for example...