删除排序为JTable的行中的行时出错

时间:2014-03-18 16:13:03

标签: java swing jtable keystroke

当我在a JTable中删除排序行时,我收到错误。

只有在对表进行排序时才会出现错误,并且我知道错误源位于何处: updateRowHeights()中的方法tableChanged会导致异常java.lang.ArrayIndexOutOfBoundsException

我想行int rowHeight = table.getRowHeight();会导致问题, 但我不知道为什么。

这是我的代码:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

public class TableExample {

String [] title = new String []      {"Title A", "Title B"};
Object [][] data = new String [][]  {{"aaaaaaaaaaaa aaaaaa aaaaaaa", "bbbbbbbb bbbb bbbbbb bbbbbb"},
                                     {"cccccccccc cccccccc ccccccc", "ddddddd ddd dddddddd dddddd"},
                                     {"eeeeeeeeee eeeeeeee eeeeeee", "fffffff ffff ffffff fffffff"}};


private JTable table;
private JFrame frame;
private DefaultTableModel model;
private JScrollPane pane1;

TableExample() {} //constructor

public JPanel createTable() {

    JPanel panel = new JPanel();

    //creating tables and table models
    model = new DefaultTableModel(data, title);       
    table = new JTable(model);

    table.getModel().addTableModelListener(new TableModelListener() {
        @Override
        public void tableChanged(TableModelEvent e) {
            updateRowHeights();             
        }           
    });

    //enable table sorting
    table.setAutoCreateRowSorter(true);

    pane1 = new JScrollPane(table);
    pane1.setPreferredSize(new Dimension(300,300));        

    updateRowHeights();     

    panel.add(pane1);

    //delete a row after del keystroke
    keyBindings();

    return panel;
}

void showTable() {
    //create and show frame     
    JPanel testPanel = createTable();
    frame = new JFrame();       
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(testPanel);              
    frame.pack();
    frame.setVisible(true);
}//showTable

void updateRowHeights() {
    for (int row = 0; row < table.getRowCount(); row++) {
        int rowHeight = table.getRowHeight();            
            Component comp = table.prepareRenderer(table.getCellRenderer(row, 1), row, 1);                
            rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);                
        table.setRowHeight(row, rowHeight);
    }
}

void keyBindings() {
    int condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT; 
    InputMap inputMap = table.getInputMap(condition);
    ActionMap actionMap = table.getActionMap(); 
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete");
    actionMap.put("delete", new AbstractAction() {  
        public void actionPerformed(ActionEvent e) {  
            int row = table.getSelectedRow();
            model.removeRow(row);
        }
    });
}

public static void main(String[] args) {
    TableExample example = new TableExample();  
    example.showTable();
}//main 

}//TableExample

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

如上所述here,“使用分拣机时,请务必记住转换单元格坐标。”例如,在删除操作中,

row = table.convertRowIndexToModel(row);

类似的问题折磨updateRowHeights(),虽然我没有追求这个。

另请考虑覆盖getPreferredScrollableViewportSize(),而不是调用setPreferredSize();更多详情here

经测试:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

public class TableExample {

    String[] title = new String[]{"Title A", "Title B"};
    Object[][] data = new String[][]{
        {"aaaaaaaaaaaa aaaaaa aaaaaaa", "bbbbbbbb bbbb bbbbbb bbbbbb"},
        {"cccccccccc cccccccc ccccccc", "ddddddd ddd dddddddd dddddd"},
        {"eeeeeeeeee eeeeeeee eeeeeee", "fffffff ffff ffffff fffffff"}};

    private JTable table;
    private JFrame frame;
    private DefaultTableModel model;
    private JScrollPane pane1;

    public JPanel createTable() {
        JPanel panel = new JPanel();
        //creating tables and table models
        model = new DefaultTableModel(data, title);
        table = new JTable(model);
        //enable table sorting
        table.setAutoCreateRowSorter(true);
        pane1 = new JScrollPane(table);
        panel.add(pane1);
        //delete a row after del keystroke
        keyBindings();
        return panel;
    }

    void showTable() {
        //create and show frame     
        JPanel testPanel = createTable();
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(testPanel);
        frame.pack();
        frame.setVisible(true);
    }//showTable

    void keyBindings() {
        int condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
        InputMap inputMap = table.getInputMap(condition);
        ActionMap actionMap = table.getActionMap();
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete");
        actionMap.put("delete", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int row = table.getSelectedRow();
                row = table.convertRowIndexToModel(row);
                model.removeRow(row);
            }
        });
    }

    public static void main(String[] args) {
        TableExample example = new TableExample();
        example.showTable();
    }//main 

}//TableExample