Bug 161699

Summary: [Viewers] TableViewer not refreshing without a scrollbar
Product: [Eclipse Project] Platform Reporter: Arvind Vanthavasi <arvind.vanthavasi>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P3    
Version: 3.2   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Arvind Vanthavasi CLA 2006-10-20 04:28:50 EDT
I'm developing a plugin in which I have a view with a TableViewer and a Table. The table is dynamically populated based on the user's selection in an editor. I've come across a strange problem where the TableViewer would not refresh its contents on certain occasions, where the number of rows in the table did not require a vertical scroll bar in the TableViewer. 

For example, if the number of rows in the table being generated was 100, and the view currently was capable of displaying 10 rows, the TableViewer would refresh and the contents would be shown. However, if the table generated anything less than 10 (ie. so that no vertical scroll bar is required for the viewer), the contents would not be shown, and the view would remain empty.

At first I thought it was a problem with my model. However, I was able to replicate the problem using a simple example. The following code contains a TableViewer, Table, Text field and a button. Enter in the number of rows you want in the table in the text field and click the button to refresh the table and viewer. If you enter 1 as the number of rows, the viewer will not update automatically. However, if you resize the application so that the TableViewer is also forced to resize, the contents display correctly. Also, if you enter a figure large enough (eg. 50 rows) so that the viewer is forced to produce a vertical scroll bar, the viewer refreshes and the contents display without resizing the application. 

public class Test {
	
	protected static Table table;
	
	protected static TableViewer viewer;
	
	protected static String randomItems;
	
	protected static Text randomText;
	
	protected static ArrayList columnNames;
	
	public static void main (String [] args) {
	    Display display = new Display ();
	    Shell shell = new Shell (display);
	    shell.setSize(200, 200);
	    GridLayout layout = new GridLayout();
	    shell.setLayout(layout);
	    layout.numColumns = 2;
		layout.verticalSpacing = 9;
	
		createTable(shell);
		createTableViewer(shell);
		viewer.setContentProvider(new ContentPv());
		viewer.setLabelProvider(new LabelPv());
	
		randomText = new Text(shell, SWT.SINGLE | SWT.BORDER);
		GridData gd = new GridData(SWT.FILL, SWT.NULL, true, false);
		gd.widthHint = 180;
		gd.horizontalSpan = 2;
		randomText.setLayoutData(gd);
		randomText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) 
			{
				setRandomItems();
			}
		});	
		
	    Button b = new Button(shell,SWT.PUSH);
	    b.setText("Change Number of Entries");
	    b.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
				
			}


			public void widgetSelected(SelectionEvent e) {
				try {
					int n = Integer.parseInt(randomItems);
					refreshTableColumns();
					refreshTable(n);
				} catch (NumberFormatException exception) {
					exception.printStackTrace();
				}
			}
	    	
	    });
	
	    shell.open ();
	    while (!shell.isDisposed ()) {
	        if (!display.readAndDispatch ()) display.sleep ();
	    }
	    display.dispose ();
	}

	private static void setRandomItems() {
		randomItems = randomText.getText();
	}
	
	private static void createTable(Composite parent) {
		int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | 
			SWT.FULL_SELECTION | SWT.HIDE_SELECTION;
		
		int WIDTH_HINT = 100;
		int HEIGHT_HINT = 100;
		
		table = new Table(parent, style);
		
		GridData gd = new GridData(SWT.FILL, SWT.NULL, true, false);
		gd.grabExcessVerticalSpace = true;
		gd.widthHint = WIDTH_HINT;
		gd.heightHint = HEIGHT_HINT;
		gd.horizontalSpan = 2;
		table.setLayoutData(gd);
		
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		
		TableLayout layout = new TableLayout();
		table.setLayout(layout);
	}
	
	protected static void createTableViewer(Composite parent) {
		viewer = new TableViewer(table);
		viewer.setUseHashlookup(true);
	}
	
	protected static void refreshTableColumns() {
		// remove current table data
		table.removeAll();
		// remove current table columns
        int columnCount = table.getColumnCount();
        for(int tableColumnIndex = columnCount - 1;
        	tableColumnIndex >=0; tableColumnIndex--) {
        	table.getColumn(tableColumnIndex).dispose();
        }
        
        // add new table Columns
        TableLayout layout = new TableLayout();
        int colWidth = 100 / 1;
        for (int i = 0; i < 1; i++) {
        	layout.addColumnData(new ColumnWeightData(colWidth, 75, true));
        }

        if (columnNames == null) {
        	columnNames = new ArrayList();
        }
        else {
        	columnNames.clear();
        }
        for (int i = 0; i < 1; i++) {
        	TableColumn column = new TableColumn(table, SWT.LEFT);
        	String name = new String(new Integer(i).toString());
        	column.setText(name);
        	columnNames.add(name);
        }
        table.setLayout(layout);
        table.redraw();
		
	}
	
	protected static void refreshTable(int n) {
		// Generate n ModelItems
		ArrayList items = new ArrayList();
		for (int i = 0; i < n; i++) {
			items.add(new ModelItem(new Integer(i).toString()));
		}
		viewer.setInput(items);
		viewer.refresh();
	}
	
	private static class LabelPv extends LabelProvider implements
		ITableLabelProvider {


		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}


		public String getColumnText(Object element, int columnIndex) {
			return ((ModelItem)element).label;
		}
		
	}
	
	private static class ContentPv implements IStructuredContentProvider {
		
		protected ArrayList modelItems;
		
		public Object[] getElements(Object inputElement) {
			ArrayList items = (ArrayList) inputElement;
			Object[] vals = items.toArray();
			
			return vals;
		}


		public void dispose() {
			// TODO Auto-generated method stub
			
		}


		public void inputChanged(Viewer viewer, Object oldInput, Object
				newInput) {
			if (newInput != null) {
				modelItems = (ArrayList) newInput;
			}
			
		}
		
	}
	
	private static class ModelItem {
		public String label;
		public ModelItem( String label ) {
			this.label = label;
		}
	}
}
Comment 1 Boris Bokowski CLA 2009-11-26 09:53:54 EST
Hitesh is now responsible for watching bugs in the [Viewers] component area.
Comment 2 Eclipse Webmaster CLA 2019-09-06 16:13:37 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.