简体   繁体   中英

JTable - Adding row to sorted table gives NullPointerException

I have a JTable created and 8 different buttons above this JTable in the GUI. Depending on which button you press, the table will be filled with different data (always same columns) and before doing that it deletes all the old data (from before-pressed buttons)

Everything is working fine - until i am sorting a column.

I am using this code to set a sorter to my table:

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

And this code to calculate/add the new rows:

button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            model.setRowCount(0);

            new Thread(new Runnable(){
                public void run(){

                    // Here is a call to another class which is calculating 
                    // the values and adding the row, but basically it is just.. 
                    // adding a row , so i exchanged it with this:

                    model.addRow(Object[]);

                }
            }).start();
        }
    });

As i said, the exception only appears when i am sorting a column, with default sorting no exception is thrown.

I have read already about EDT and with this kind of code i am editing the table outside of it and maybe to use InvokeLater. Tried to use it and also read some documentation about it but i can't get it working.

Got the information from here: Sorting JTable causes NullPointerException

This is a new area for me so telling me to "just add xyz or do xyz" won't help me since i do not know how i should do it, which means it would be really nice if someone can give me examples of it or even add it to my code

This is the exception i get (It repeats several times):

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source) at javax.swing.JTable.convertRowIndexToModel(Unknown Source) at javax.swing.JTable.getValueAt(Unknown Source) at javax.swing.JTable.prepareRenderer(Unknown Source) at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source) at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source) at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source) at javax.swing.plaf.ComponentUI.update(Unknown Source) at javax.swing.JComponent.paintComponent(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintChildren(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JViewport.paint(Unknown Source) at javax.swing.JComponent.paintChildren(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintToOffscreen(Unknown Source) at javax.swing.RepaintManager $PaintManager.paintDoubleBuffered(Unknown Source) at javax.swing.RepaintManager$PaintManager.paint(Unknown Source) at javax.swing.RepaintManager.paint(Unknown Source) at javax.swing.JComponent._paintImmediately(Unknown Source) at javax.swing.JComponent.paintImmediately(Unknown Source) at javax.swing.RepaintManager$4.run(Unknown Source) at javax.swing.RepaintManager$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.access$1300(Unknown Source) at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$500( Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)

model.addRow(Object[]); looks suspect. You are adding a row with no data.

Also you should really be doing this in the UI thread. Use SwingUtilities.invokeLater .

Instead of

new Thread(new Runnable(){
    public void run(){

do

SwingUtilities.invokeLater(new Runnable(){
    public void run(){

Don't do this...

        new Thread(new Runnable(){
            public void run(){

                // Here is a call to another class which is calculating 
                // the values and adding the row, but basically it is just.. 
                // adding a row , so i exchanged it with this:

                model.addRow(Object[]);

            }
        }).start();

This is modifying the state of the UI outside of the context of the Event Dispatching Thread, which is leading to a race condition between the UI, the model and the sorter.

Swing is not thread safe and any modifications of the UI (or anything that might affect the UI) should be done from within the context of the EDT.

Either use SwingUtilities.invokeLater or a SwingWorker

See Concurrency in Swing for more details

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM