JTable сортировать как добавление и удаление - PullRequest
0 голосов
/ 25 октября 2018

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

Это мой метод, который вызывает добавление к model.

   @Override
   public void notify( final String topic, final AvxPacket packet)
   {
      if ( this.active.get() && avionixPacket.getPacketType() == RawPacketType.AVR_PACKET )
      {
         final AVRPacket avrPacket = ( AVRPacket ) packet;

         if ( this.validateAgainstFilter( avrPacket ) )
         {
            try
            {
               this.model.addRow( AirpacketDecoder.decode( avrPacket ) );
            }
            catch ( final BadFormatException | UnspecifiedFormatError | CRCError e )
            {
               AirInspectorTable.LOG.warn( "Something went wrong", e );
            }
         }

      }
   }

Ниже вы увидите метод, который добавляет к строкам vector.vector - это место, где хранятся все записи.

   /** List of table entries. */
   private final transient Vector<AirTableEntry> rows = new Vector<>();

     /** Adds an entry to table. Takes care of table size - does not let it 
     grow above defined size.
       @param airPacket data source */
   public void addRow( final AirPacket airPacket )
   {
      if ( airPacket != null )
      {
         this.rows.add( new AirTableEntry( airPacket ) );
         final int rowNumber = this.rows.size() - 1;
         this.fireTableRowsInserted( rowNumber, rowNumber );
         if ( this.rows.size() > AirTableModel.MAX_ROWS )
         {
            this.rows.remove( 0 );
            this.fireTableRowsDeleted( 0, 0 );
         }
      }
   }

Также у меня есть один класс с именем FilterPanelEventListener, где я передаю Table, чтобы добавить RowSorter.

/**
    * Constructor which takes source table and filterTxt as an argument.
    * @param sourceTable is the table to be modified.
    * @param sourceFilterTxt is the filter txt.
    */
   public FilterPanelEventListener( final AirInspectorTable sourceTable,
         final JTextField sourceFilterTxt )
   {
      this.table = sourceTable;
      this.filterTxt = sourceFilterTxt;
      RowSorter<? extends TableModel> rs = this.table.getRowSorter();
      this.rowSorter = new TableRowSorter<>( this.table.getModel() );

      for ( int rowIndex = 0; rowIndex < this.table.getColumnCount(); rowIndex++ )
      {
         this.rowSorter.setSortable( rowIndex, false );
      }
      if ( rs == null )
      {
         this.table.setRowSorter( this.rowSorter );
         rs = this.table.getRowSorter();
      }
      this.rowSorter =
            rs instanceof TableRowSorter ? ( TableRowSorter<? extends TableModel> ) rs : null;
      if ( this.rowSorter == null )
      {
         throw new RuntimeException( "Cannot find appropriate rowSorter: " + rs );
      }
   }

Всякий раз, когда есть запись в JTextField RowSorter, сортировка с использованием этого метода ниже.

    /**
    * Updates the filter.
    * @param filter is the filter
    */
   private void update( final String filter )
   {
      try
      {
         if ( filter.trim().length() == 0 )
         {
            this.rowSorter.setRowFilter( null );
         }
         else
         {
            this.rowSorter
                  .setRowFilter( RowFilter.regexFilter( "(?i)" + filter, ID_COLUMN_INDEX ) );
         }
      }
      catch ( final ArrayIndexOutOfBoundsException ex )
      {
         LOG.warn( "Something went wrong", ex );
      }
   }

Все работает нормально, пока Vector не достигнет максимального значения, сортировщик работает отлично.Однако после максимального значения, если я склонен к сортировке (например, при записи чего-либо в JTextField, я получаю десятки исключений, таблица начинает мигать. Я не заметил этого, потому что мой лимит обычно составлял 100000, где я фактически не ждалтак много, что нужно заполнить. Теперь я вижу, когда он добавляется и удаляется одновременно, возникает проблема. Исключения таковы:

java.lang.ArrayIndexOutOfBoundsException: 7
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)

java.lang.NullPointerException: null
    at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JTable.convertRowIndexToModel(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JTable.getValueAt(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JTable.prepareRenderer(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.plaf.ComponentUI.update(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JComponent.paintComponent(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JComponent.paint(Unknown Source) ~[?:1.8.0_181]
    at javax.swing.JComponent.paintChildren(Unknown Source) ~[?:1.8.0_181]

Что я делаю не так? Спасибовперед.

1 Ответ

0 голосов
/ 26 октября 2018

Swing разработан как однопоточный, и все обновления модели или компонента должны выполняться на Event Dispatch Thread (EDT).

Похоже, вы пытаетесь обновить модель из отдельного потока, и некоторая логика выполняется не по порядку.

Убедитесь, что все обновления модели выполнены на EDTоборачивая код добавления / удаления в SwingUtilities.invokeLater().

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