0

整篇文章已编辑

我的问题是:这段代码会导致IndexOutOfBoundsException什么?以及如何避免这种情况?ErrorStackTrace如下图所示,当您单击Fetch按钮 15-20 次时,您可以得到相同的结果。我的问题真的与convertRowIndexToModel()吗?如果可以的话,请给我解释一下。谢谢你。

已编辑,希望这次我做对了

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.table.TableStringConverter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

public class Main {

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            GoodsView goodsView = new GoodsView();
            goodsView.setLocationRelativeTo(null);
            goodsView.setVisible(true);
        }
    });
  }
}

class GoodsView extends JFrame {

private JTable table;
private List<GoodsPosition> positions;
private List<List<Object>> tempList;
private GoodsViewTableModel model;
private JButton button;
private TableUtils tableUtils;
private JTextField textField = new JTextField(15);

public GoodsView() {
    positions = new ArrayList<>(25);
    tempList = new ArrayList<>(25);
    tableUtils = new TableUtils();
    initGUI();
    setSize(600, 400);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

private void initGUI() {
    Container container = getContentPane();
    container.setLayout(new BorderLayout());
    container.add(createTableView(), BorderLayout.CENTER);
    container.add(createButtonPanel(), BorderLayout.NORTH);
}

private JScrollPane createTableView() {
    model = new GoodsViewTableModel(positions);
    table = new JTable(model);
    table.setRowSorter(tableUtils.createSorter(model, textField));
    return new JScrollPane(table);

}

private JPanel createButtonPanel() {
    button = new JButton(new AbstractAction("Fetch") {
        @Override
        public void actionPerformed(ActionEvent e) {
            button.setEnabled(false);
            runGoodsFetcher();
        }
    });

    JPanel panel = new JPanel(new BorderLayout(5, 5));
    panel.add(button, BorderLayout.EAST);
    panel.add(textField, BorderLayout.WEST);

    return panel;
}

private void runGoodsFetcher() {

    new SwingWorker<Void, GoodsPosition>() {

        String id, art;

        @Override
        protected Void doInBackground() throws Exception {

            if (!tempList.isEmpty()) {
                tempList.clear();
            }

            if (!positions.isEmpty()) {
                positions.clear();
            }

            tempList = executeQuery();

            for (List<Object> tempListItem : tempList) {

                id = tempListItem.get(0) == null ? "" : tempListItem.get(0).toString();
                art = tempListItem.get(1) == null ? "" : tempListItem.get(1).toString();
                //Thread.sleep(5);
                GoodsPosition position = new GoodsPosition(id, art);
                publish(position);
            }

            return null;
        }

        @Override
        protected void process(List<GoodsPosition> pos) {
            model.addPositions(pos);
        }

        @Override
        public void done() {
            button.setEnabled(true);
        }

    }.execute();
}

public List<List<Object>> executeQuery() {

    List<List<Object>> rows = new ArrayList<>();

    for (int column = 0; column < 100000; column++) {

        List<Object> newRow = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            newRow.add(0, column);
            newRow.add(1, column + 1);
        }
        rows.add(newRow);
    }
    return rows;
}

private class GoodsViewTableModel extends AbstractTableModel {

    private String[] columnNames =
            {"id", "art"};

    private List<GoodsPosition> goodsPositions;

    GoodsViewTableModel(List<GoodsPosition> goodsPositions) {
        this.goodsPositions = goodsPositions;
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }

    @Override
    public int getRowCount() {
        return goodsPositions.size();
    }

    @Override
    public Class<?> getColumnClass(int column) {
        return String.class;
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    @Override
    public Object getValueAt(int row, int column) {
        GoodsPosition position = getPosition(row);

        switch (column) {
            case 0:
                return position.getId();
            case 1:
                return position.getArt();
            default:
                return null;
        }
    }

    @Override
    public void setValueAt(Object value, int row, int column) {
        GoodsPosition position = getPosition(row);
        switch (column) {
            case 0:
                position.setId((String) value);
                break;
            case 1:
                position.setArt((String) value);
                break;
        }
        fireTableCellUpdated(row, column);
    }

    public GoodsPosition getPosition(int row) {
        return goodsPositions.get(row);
    }

    public void addPosition(GoodsPosition position) {
        insertPosition(getRowCount(), position);
    }

    public void addPositions(List<GoodsPosition> positionsList) {
        int rowCount = getRowCount();
        goodsPositions.addAll(positionsList);
        fireTableRowsInserted(rowCount, getRowCount() - 1);
    }

    public void insertPosition(int row, GoodsPosition position) {
        goodsPositions.add(row, position);
        fireTableRowsInserted(row, row);
    }

    public void removePosition(int row) {
        goodsPositions.remove(row);
        fireTableRowsDeleted(row, row);
    }

    public void removeAllPositions() {
        if (!goodsPositions.isEmpty()) {
            goodsPositions.clear();
        }
    }
}

public class GoodsPosition {

    private String oraId;
    private String art;

    public GoodsPosition(String oraId, String art) {
        this.oraId = oraId;
        this.art = art;
    }

    public String getId() {
        return oraId;
    }

    public void setId(String oraId) {
        this.oraId = oraId;
    }

    public String getArt() {
        return art;
    }

    public void setArt(String art) {
        this.art = art;
    }
}

private class TableUtils {

    private TableRowSorter<TableModel> createSorter(TableModel model, JTextField field) {
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);

        sorter.setStringConverter(new TableStringConverter() {
            @Override
            public String toString(TableModel model, int row, int column) {
                return model.getValueAt(row, column).toString().toLowerCase();
            }
        });
        field.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                String searchText = field.getText().toLowerCase();

                if (searchText.trim().length() == 0) {
                    sorter.setRowFilter(null);
                } else {
                    sorter.setRowFilter(RowFilter.regexFilter(searchText));
                }
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                String searchText = field.getText().toLowerCase();

                if (searchText.trim().length() == 0) {
                    sorter.setRowFilter(null);
                } else {
                    sorter.setRowFilter(RowFilter.regexFilter(searchText));
                }
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                String searchText = field.getText().toLowerCase();

                if (searchText.trim().length() == 0) {
                    sorter.setRowFilter(null);
                } else {
                    sorter.setRowFilter(RowFilter.regexFilter(searchText));
                }
            }
        });
        return sorter;
    }
  }

}

和我的ErrorStackTrace

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 62523, Size: 7524
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at GoodsView$GoodsViewTableModel.getPosition(Main.java:205)
at GoodsView$GoodsViewTableModel.getValueAt(Main.java:178)
at javax.swing.table.TableRowSorter$TableRowSorterModelWrapper.getValueAt(TableRowSorter.java:269)
at javax.swing.DefaultRowSorter.compare(DefaultRowSorter.java:955)
at javax.swing.DefaultRowSorter.access$100(DefaultRowSorter.java:112)
at javax.swing.DefaultRowSorter$Row.compareTo(DefaultRowSorter.java:1376)
at javax.swing.DefaultRowSorter$Row.compareTo(DefaultRowSorter.java:1366)
at java.util.Arrays.binarySearch0(Arrays.java:2439)
at java.util.Arrays.binarySearch(Arrays.java:2379)
at javax.swing.DefaultRowSorter.insertInOrder(DefaultRowSorter.java:1000)
at javax.swing.DefaultRowSorter.rowsInserted0(DefaultRowSorter.java:1058)
at javax.swing.DefaultRowSorter.rowsInserted(DefaultRowSorter.java:868)
at javax.swing.JTable.notifySorter(JTable.java:4270)
at javax.swing.JTable.sortedTableChanged(JTable.java:4118)
at javax.swing.JTable.tableChanged(JTable.java:4395)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:231)
at GoodsView$GoodsViewTableModel.addPositions(Main.java:215)
at GoodsView$2.process(Main.java:113)
at javax.swing.SwingWorker$3.run(SwingWorker.java:414)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
at javax.swing.Timer.fireActionPerformed(Timer.java:313)
at javax.swing.Timer$DoPostEvent.run(Timer.java:245)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.DefaultRowSorter.getViewToModelAsInts(DefaultRowSorter.java:742)
at javax.swing.DefaultRowSorter.sort(DefaultRowSorter.java:572)
at javax.swing.DefaultRowSorter.shouldOptimizeChange(DefaultRowSorter.java:1025)
at javax.swing.DefaultRowSorter.rowsInserted(DefaultRowSorter.java:867)
at javax.swing.JTable.notifySorter(JTable.java:4270)
at javax.swing.JTable.sortedTableChanged(JTable.java:4118)
at javax.swing.JTable.tableChanged(JTable.java:4395)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:231)
at GoodsView$GoodsViewTableModel.addPositions(Main.java:215)
at GoodsView$2.process(Main.java:113)
at javax.swing.SwingWorker$3.run(SwingWorker.java:414)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
at javax.swing.Timer.fireActionPerformed(Timer.java:313)
at javax.swing.Timer$DoPostEvent.run(Timer.java:245)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

再次提前感谢大家。如果我违反了任何发布规则或任何内容,我很抱歉。

4

0 回答 0