Question

When i want to get a cell value from my table (after search with filtering) and select that row and execute the returnAction() , Exception occur.

My code:

public class BookPage_User extends JFrame implements ActionListener {

private JButton returnBookBtn;
private JTextField filterTF;
private TableRowSorter sorter;
private JTable table;
private BookJDBC bookJDBC;
private BookModel model;

public BookPage_User(String[] enterUserInfo, String userId) {
    bookJDBC = new BookJDBC();
    model = new BookModel(bookJDBC.getData(), bookJDBC.getColumn());

    sorter = new TableRowSorter<TableModel>(model);
    table = new JTable(model);
    table.setRowSorter(sorter);

    add(createForm(), BorderLayout.NORTH);
    add(new JScrollPane(table), BorderLayout.CENTER);

    RowFilter<BookModel, Object> rf = null;
    rf = RowFilter.regexFilter(filterTF.getText(), 0);
    sorter.setRowFilter(rf);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(850, 600);
    setVisible(true);
}
public JPanel createForm() {
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    returnBookBtn = new JButton("Return Book");
    filterTF = new JTextField(10);
    filterTF.getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            String key = filterTF.getText().trim();
            if (key.length() == 0) sorter.setRowFilter(null);
            else sorter.setRowFilter(RowFilter.regexFilter(key, 1));
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            String key = filterTF.getText().trim();
            if (key.length() == 0) sorter.setRowFilter(null);
            else sorter.setRowFilter(RowFilter.regexFilter(key, 1));
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
        }
    });

    returnBookBtn.addActionListener(this);
    panel.add(returnBookBtn);
    panel.add(filterTF);
    return panel;
}
@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == returnBookBtn) returnAction();
}

public void returnAction() {
    if (table.getSelectedRow() > -1) {
        int rowInTable = table.getSelectedRow();
        int rowInModel = table.convertRowIndexToModel(rowInTable);
        String oldStatus = String.valueOf(table.getValueAt(rowInModel, 3));  // Exception occur here!
        String returnBookId = String.valueOf(table.getValueAt(rowInModel, 0));
        if (oldStatus.equalsIgnoreCase("Yes")) {
                model.updateBooksTableReturnAction(rowInModel);
                model.deleteFromBorrowTable(returnBookId);
        } else {
            JOptionPane.showMessageDialog(null, "This Book Not Borrowed");
            return;
        }
    } else JOptionPane.showMessageDialog(null, "Select a book");
}

The exception that I've got is as follows -

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 8
at javax.swing.DefaultRowSorter.convertRowIndexToModel(DefaultRowSorter.java:518)
at javax.swing.JTable.convertRowIndexToModel(JTable.java:2645)
at javax.swing.JTable.getValueAt(JTable.java:2720)
at Project.BookPage_User.returnAction(BookPage_User.java:125)
at Project.BookPage_User.actionPerformed(BookPage_User.java:95)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:696)
at java.awt.EventQueue$4.run(EventQueue.java:694)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:693)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Was it helpful?

Solution 2

I am assuming(or this is actually the reason), You are actually having the issue with the following line:

String oldStatus = String.valueOf(table.getValueAt(rowInModel, 3));

JTable.getValueAt(row, col) method will return the value of the cell (row, col) by converting them to model-index where (row, col) is view-index. Let use look into the source of JTable class:

public Object getValueAt(int row, int column) {
        return getModel().getValueAt(convertRowIndexToModel(row),
                                     convertColumnIndexToModel(column));
    }

So your passed (row, col) to this function should belongs to the view, instead of model. In your context which is rowInTable. The rowInModel is already a model index as you got it from table.convertRowIndexToModel(rowInTable). By calling JTable.getValueAt(rowInModel, 3) you are essentially trying to convert a model index to another model index resulting in computational error.

OTHER TIPS

The ArrayIndexOutOfBounds is just saying you are trying to access a row or column which is outside the bounds of the internal arrays representing the rows and columns of the table.

Make sure you use the right indexes for the model and for the table. Remember that the way the table is rendering the model might be a bit different, since the user might order rows, swap columns etc.

If the value is in a table cell and you know the row and column to it and you want to get it from there use the rowInTable not rowInModel. rowInModel might be different so asking the table to give you the value of the row using this index might give you the wrong value, and if rows are being filtered out you might end up with these ArrayIndexOutOfBounds exceptions.

Full details here.

When the table is filtered, the column/row numbers of the displayed values are different from the underlying column/row numbers of the original table model. Therefore, you need to convert the row or column numbers accordingly to avoid arrrayOutOfBounds exception.

Assuming your table is called jTableItems, the following simple if...else.. conditions will ensure the row and col values returned correctly points to the selected data whether the table is sorted or not:

 if (jTableItems.getSelectedColumn() == jTableItems.convertColumnIndexToView(jTableItems.getSelectedColumn())) {
            col = jTableItems.getSelectedColumn();
            row = jTableItems.getSelectedRow();
        } else {
            col = jTableItems.convertColumnIndexToView(jTableItems.getSelectedColumn());
            row = jTableItems.convertRowIndexToView(jTableItems.getSelectedRow());

        }

Best of luck in your coding!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top