Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 235368 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/swt/widgets/Table.java (-8 / +12 lines)
Lines 127-133 Link Here
127
    }
127
    }
128
128
129
    public void checkData( final int index ) {
129
    public void checkData( final int index ) {
130
      Table.this.checkData( Table.this._getItem( index ), index );
130
      if( index >= 0 && index < Table.this.itemCount ) {
131
        Table.this.checkData( Table.this._getItem( index ), index );
132
      }
131
    }
133
    }
132
134
133
    public int getDefaultColumnWidth() {
135
    public int getDefaultColumnWidth() {
Lines 1920-1926 Link Here
1920
    checkWidget();
1922
    checkWidget();
1921
    SelectionEvent.removeListener( this, listener );
1923
    SelectionEvent.removeListener( this, listener );
1922
  }
1924
  }
1923
1925
  
1924
  /////////////////////////////
1926
  /////////////////////////////
1925
  // Create and destroy columns
1927
  // Create and destroy columns
1926
1928
Lines 2134-2145 Link Here
2134
    if( ( style & SWT.VIRTUAL ) != 0 && !item.cached ) {
2136
    if( ( style & SWT.VIRTUAL ) != 0 && !item.cached ) {
2135
      ProcessActionRunner.add( new Runnable() {
2137
      ProcessActionRunner.add( new Runnable() {
2136
        public void run() {
2138
        public void run() {
2137
          item.cached = true;
2139
          if( index >= 0 && index < itemCount ) {
2138
          SetDataEvent event = new SetDataEvent( Table.this, item, index );
2140
            item.cached = true;
2139
          event.processEvent();
2141
            SetDataEvent event = new SetDataEvent( Table.this, item, index );
2140
          // widget could be disposed at this point
2142
            event.processEvent();
2141
          if( isDisposed() || item.isDisposed() ) {
2143
            // widget could be disposed at this point
2142
            SWT.error( SWT.ERROR_WIDGET_DISPOSED );
2144
            if( isDisposed() || item.isDisposed() ) {
2145
              SWT.error( SWT.ERROR_WIDGET_DISPOSED );
2146
            }
2143
          }
2147
          }
2144
        }
2148
        }
2145
      } );
2149
      } );
(-)src/org/eclipse/swt/internal/widgets/tablekit/TableLCA.java (-14 / +20 lines)
Lines 83-89 Link Here
83
    Table table = ( Table )widget;
83
    Table table = ( Table )widget;
84
    readTopIndex( table ); // topIndex MUST be read *before* processSetData
84
    readTopIndex( table ); // topIndex MUST be read *before* processSetData
85
    readSelection( table );
85
    readSelection( table );
86
    processSetData( table );
86
    readSetData( table );
87
    readWidgetSelected( table );
87
    readWidgetSelected( table );
88
    readWidgetDefaultSelected( table );
88
    readWidgetDefaultSelected( table );
89
    ControlLCAUtil.processMouseEvents( table );
89
    ControlLCAUtil.processMouseEvents( table );
Lines 169-175 Link Here
169
    }
169
    }
170
  }
170
  }
171
  
171
  
172
  private static void processSetData( final Table table ) {
172
  private static void readSetData( final Table table ) {
173
    if( WidgetLCAUtil.wasEventSent( table, JSConst.EVENT_SET_DATA ) ) {
173
    if( WidgetLCAUtil.wasEventSent( table, JSConst.EVENT_SET_DATA ) ) {
174
      HttpServletRequest request = ContextProvider.getRequest();
174
      HttpServletRequest request = ContextProvider.getRequest();
175
      String value = request.getParameter( JSConst.EVENT_SET_DATA_INDEX );
175
      String value = request.getParameter( JSConst.EVENT_SET_DATA_INDEX );
Lines 178-184 Link Here
178
      ITableAdapter tableAdapter = ( ITableAdapter )adapter;
178
      ITableAdapter tableAdapter = ( ITableAdapter )adapter;
179
      for( int i = 0; i < indices.length; i++ ) {
179
      for( int i = 0; i < indices.length; i++ ) {
180
        int index = Integer.parseInt( indices[ i ] );
180
        int index = Integer.parseInt( indices[ i ] );
181
        tableAdapter.checkData( index );
181
        if (index >-1 && index < table.getItemCount()) {
182
            tableAdapter.checkData( index );
183
        }
182
      }
184
      }
183
    }
185
    }
184
  }
186
  }
Lines 186-202 Link Here
186
  private void readWidgetSelected( final Table table ) {
188
  private void readWidgetSelected( final Table table ) {
187
    if( WidgetLCAUtil.wasEventSent( table, JSConst.EVENT_WIDGET_SELECTED ) ) {
189
    if( WidgetLCAUtil.wasEventSent( table, JSConst.EVENT_WIDGET_SELECTED ) ) {
188
      // TODO [rh] do something about when index points to unresolved item! 
190
      // TODO [rh] do something about when index points to unresolved item! 
189
      TableItem item = table.getItem( getWidgetSelectedIndex() );
191
      final int widgetSelectedIndex = getWidgetSelectedIndex();
190
      int detail = getWidgetSelectedDetail();
192
      // Bugfix: check if index is valid before firing event to avoid problems with fast scrolling
191
      int id = SelectionEvent.WIDGET_SELECTED;
193
      if (widgetSelectedIndex > -1 && widgetSelectedIndex < table.getItemCount()) {
192
      SelectionEvent event = new SelectionEvent( table,
194
          TableItem item = table.getItem( widgetSelectedIndex );
193
                                                 item,
195
          int detail = getWidgetSelectedDetail();
194
                                                 id,
196
          int id = SelectionEvent.WIDGET_SELECTED;
195
                                                 new Rectangle( 0, 0, 0, 0 ),
197
          SelectionEvent event = new SelectionEvent( table,
196
                                                 "",
198
                  item,
197
                                                 true,
199
                  id,
198
                                                 detail );
200
                  new Rectangle( 0, 0, 0, 0 ),
199
      event.processEvent();
201
                  "",
202
                  true,
203
                  detail );
204
          event.processEvent();
205
      }
200
    }
206
    }
201
  }
207
  }
202
208
(-)src/org/eclipse/swt/widgets/Table_Test.java (-6 / +22 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
2
 * Copyright (c) 2002-2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
10
 ******************************************************************************/
11
12
package org.eclipse.swt.widgets;
11
package org.eclipse.swt.widgets;
13
12
14
import junit.framework.TestCase;
13
import junit.framework.TestCase;
Lines 424-433 Link Here
424
    Object adapter = table.getAdapter( ITableAdapter.class );
423
    Object adapter = table.getAdapter( ITableAdapter.class );
425
    ITableAdapter tableAdapter = ( ITableAdapter )adapter;
424
    ITableAdapter tableAdapter = ( ITableAdapter )adapter;
426
425
427
//    table.setItemCount( 100 );
428
//    table.setSelection( 90 );
429
//    table.setSize( 501, 501 );
430
//    table.setItemCount( 10 );
431
    table.setItemCount( 100 );
426
    table.setItemCount( 100 );
432
    table.setSelection( 99 );
427
    table.setSelection( 99 );
433
    table.setSize( 501, 501 );
428
    table.setSize( 501, 501 );
Lines 1447-1452 Link Here
1447
    assertNotNull( item );
1442
    assertNotNull( item );
1448
    assertEquals( 0, table.indexOf( item ) );
1443
    assertEquals( 0, table.indexOf( item ) );
1449
  }
1444
  }
1445
1446
  /*
1447
   * Ensures that checkData calls with an invalid index are silently ignored.
1448
   * This may happen, when the itemCount is reduced during a SetData event.
1449
   * Queued SetData events may then have stale (out-of-bounds) indices.
1450
   * See 235368: [table] [table] ArrayIndexOutOfBoundsException in virtual 
1451
   *     TableViewer 
1452
   *     https://bugs.eclipse.org/bugs/show_bug.cgi?id=235368
1453
   */
1454
  public void testCheckDataWithInvalidIndex() {
1455
    RWTFixture.fakePhase( PhaseId.PROCESS_ACTION );
1456
    Display display = new Display();
1457
    Shell shell = new Shell( display );
1458
    Table table = new Table( shell, SWT.VIRTUAL );
1459
    table.setItemCount( 10 );
1460
    ITableAdapter adapter
1461
      = ( ITableAdapter )table.getAdapter( ITableAdapter.class );
1462
    adapter.checkData( 99 );
1463
    // No assert - the purpose of this test is to ensure that no 
1464
    // ArrayIndexOutOfBoundsException is thrown 
1465
  }
1450
  
1466
  
1451
  private static void clearColumns( final Table table ) {
1467
  private static void clearColumns( final Table table ) {
1452
    while( table.getColumnCount() > 0 ) {
1468
    while( table.getColumnCount() > 0 ) {
(-)src/org/eclipse/swt/internal/widgets/tablekit/TableLCA_Test.java (+38 lines)
Lines 516-521 Link Here
516
    assertTrue( Fixture.getAllMarkup().indexOf( "Item 500" ) != -1 );
516
    assertTrue( Fixture.getAllMarkup().indexOf( "Item 500" ) != -1 );
517
  }
517
  }
518
  
518
  
519
  /*
520
   * Ensures that checkData calls with an invalid index are silently ignored.
521
   * This may happen, when the itemCount is reduced during a SetData event.
522
   * Queued SetData events may then have stale (out-of-bounds) indices.
523
   * See 235368: [table] [table] ArrayIndexOutOfBoundsException in virtual 
524
   *     TableViewer 
525
   *     https://bugs.eclipse.org/bugs/show_bug.cgi?id=235368
526
   */
527
  public void testReduceItemCountInSetData() {
528
    RWTFixture.fakePhase( PhaseId.PROCESS_ACTION );
529
    Display display = new Display();
530
    Shell shell = new Shell( display );
531
    shell.setSize( 100, 100 );
532
    Table table = new Table( shell, SWT.VIRTUAL );
533
    table.addListener( SWT.SetData, new Listener() {
534
      public void handleEvent( Event event ) {
535
        fail( "Must not trigger SetData event" ); 
536
      }
537
    } );
538
539
    RWTFixture.fakePhase( PhaseId.READ_DATA );
540
    table.setItemCount( 1 );
541
    ITableAdapter adapter
542
      = ( ITableAdapter )table.getAdapter( ITableAdapter.class );
543
    adapter.checkData( 0 );
544
    
545
    RWTFixture.fakePhase( PhaseId.PROCESS_ACTION );
546
    table.setItemCount( 0 );
547
    int eventCount = 0;
548
    while( ProcessActionRunner.executeNext() ) {
549
      eventCount++;
550
    }
551
    while( SetDataEvent.executeNext() ) {
552
      eventCount++;
553
    }
554
    assertEquals( 1, eventCount );
555
  }
556
  
519
  private static int countResolvedItems( final Table table ) {
557
  private static int countResolvedItems( final Table table ) {
520
    Object adapter = table.getAdapter( ITableAdapter.class );
558
    Object adapter = table.getAdapter( ITableAdapter.class );
521
    ITableAdapter tableAdapter = ( ITableAdapter )adapter;
559
    ITableAdapter tableAdapter = ( ITableAdapter )adapter;

Return to bug 235368