Сортировка JTable вызывает исключение NullPointerException - PullRequest
2 голосов
/ 26 сентября 2011

У меня есть JTable, который при нажатии на соответствующую кнопку начинает заполняться результатами обхода файлового дерева, который происходит в фоновом режиме. Это отлично работает.

Затем я решил, что хочу отсортировать таблицу. После некоторого чтения я создал TableRowSorter и настроил таблицу для его использования. Казалось, что это работает, но при ближайшем рассмотрении я заметил, что некоторые результаты файла отсутствовали. Я отключил сортировщик и снова запустил программу, и все файлы снова присутствовали, после повторного включения сортировщика некоторые были пропущены, но каждый раз при отбрасывании это были разные файлы.

Чтобы проверить это, я создал автономный блок кода в качестве теста (см. Ниже), который должен был представлять код JTable (на самом деле большие куски были извлечены непосредственно из существующего программного кода). Обход дерева файлов представлен циклом for. Опять же, он работал отлично без сортировщика. Однако когда я включил сортировщик (раскомментировав строку 29), вся программа зависла, и мне сказали, что существует исключение NullPointerException.

Я понятия не имею, что является причиной этих проблем, и действительно ли они вообще связаны между собой. Любые идеи о том, что не так, приветствуются.

import javax.swing.table.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Sort extends JFrame{

    private JTable table;
    private DefaultTableModel model;
    private TableRowSorter<DefaultTableModel> sorter;

    private JButton go;

    public Sort(){
        super("Sort");

        // Create table and model
        model = new DefaultTableModel(0, 4);
        table = new JTable(model);

        // Setup sorting
        sorter = new TableRowSorter<DefaultTableModel>(model);
        ArrayList<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
        sortKeys.add(new RowSorter.SortKey(2, SortOrder.ASCENDING));
        sortKeys.add(new RowSorter.SortKey(3, SortOrder.ASCENDING));
        sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
        sorter.setSortKeys(sortKeys); 
        //table.setRowSorter(sorter);

        // Create Scroll Pane
        JScrollPane tableScroller = new JScrollPane(table);
        table.setFillsViewportHeight(true);
        tableScroller.setPreferredSize(new Dimension(500, 200));

        // Setup button
        go = new JButton("Go");
        go.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>(){
                    public Void doInBackground(){
                        for(int i = 0; i < 200; i++){
                            model.addRow( new Object[] { (new Integer(i)), String.valueOf(i), String.valueOf(i%50), String.valueOf(i%10) } );
                        }
                        return null;
                    }
                };
                worker.execute();
            }
        });

        // Assemble GUI
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(tableScroller, BorderLayout.CENTER);
        panel.add(go, BorderLayout.SOUTH);

        setContentPane(panel);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);

    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                new Sort();
            }
        });
    }

}

StackTrace

Это часть трассировки стека, она повторяется ..

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    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 javax.swing.JTable.prepareRenderer(JTable.java:5718)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
    at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
    at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
    at javax.swing.JComponent.paintComponent(JComponent.java:778)
    at javax.swing.JComponent.paint(JComponent.java:1054)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
    at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1206)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
    at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    ...

1 Ответ

9 голосов
/ 26 сентября 2011

В вашем коде есть большая проблема, что может объяснить, что вы наблюдаете: вы изменяете модель таблицы вне EDT, что является злом.

Поскольку вывы используете SwingWorker, вы должны попытаться использовать его полностью правильно, например, используйте его publish API для вызова model.addRow().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...