Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 335096

Summary: [Viewers] Table.getClientArea() does not remove check column width with SWT.CHECK
Product: [Eclipse Project] Platform Reporter: Brian de Alwis <bsd>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: grant_gayed, peter.kullmann, prakash, skovatch
Version: 3.7   
Target Milestone: ---   
Hardware: Macintosh   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard: stalebug
Attachments:
Description Flags
demo project none

Description Brian de Alwis CLA 2011-01-22 20:12:57 EST
Created attachment 187369 [details]
demo project

Noticed with SWT 3.7M4, but likely in earlier versions too.

Neither Table nor Tree's getClientArea() take into account the checkbox column.

As a result, instances of JFace's CheckboxTableViewer with a TableColumnLayout configured with ColumnWeightData columns always have a horizontal scroll bar.  This combination should dynamically resize the columns to fit within the table bounds.  But as the available space is derived from the client area, the resized columns are too big.  (And similarly for CheckboxTreeViewer with a TreeColumnLayout.)

I've attached an example project.  Import and run the main().  Not matter how you resize the shell/window, there is always a horizontal scroll bar.

I think the solution is to change Table#getClientArea() and Tree#getClientArea() to look as following:

public Rectangle getClientArea () {
	checkWidget ();
	Rectangle rect = super.getClientArea ();
	NSTableHeaderView headerView = ((NSTableView) view).headerView ();
	if (headerView != null) {
		// The origin of the table is the top-left of the rows of the table,
		// not the header.  Adjust the y value accordingly.
		int height =  (int) headerView.bounds ().height;
		rect.y -= height;
		rect.height += height;
	}

	// Check column must be removed from the area
	if ((style & SWT.CHECK) != 0) {
		int checkWidth = getCheckColumnWidth();
		rect.x += checkWidth;
		rect.width -= checkWidth;
	}
	return rect;
}
Comment 1 Scott Kovatch CLA 2011-02-02 15:04:40 EST
Subtracting out the checkbox column width in Table#getClientArea() fixes the problem, but it doesn't make sense to me why that should be the case. 

Adding Grant, since he did Table and Tree -- are checkboxes considered to be part of the 'client area' on Win32 and elsewhere?

The TableLayout code has a lot of platform-specific funkiness that may be part of the problem here, but I thought I'd ask before I check this in.
Comment 2 Grant Gayed CLA 2011-02-04 12:12:52 EST
Yes, checkboxes are part of the client area on all platforms, snippet:

public static void main(String[] args) {
    final Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());
    shell.setBounds(10,10,600,600);
    final Table table = new Table(shell, SWT.CHECK);
    new TableColumn(table, SWT.NONE).setWidth(100);
    new TableColumn(table, SWT.NONE).setWidth(100);
    new TableColumn(table, SWT.NONE).setWidth(100);
    table.setLinesVisible(true);
    for (int i = 0; i < 9; i++) {
        new TableItem(table, SWT.NONE).setText("item " + i);
    }
    table.addListener(SWT.Paint, new Listener() {
        public void handleEvent(Event event) {
            Rectangle rect = table.getClientArea();
            rect.width -= 1; rect.height -= 1;
            event.gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
            event.gc.drawRectangle(rect);
        }
    });
    shell.open();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) display.sleep();
    }
    display.dispose();
}
Comment 3 Scott Kovatch CLA 2011-02-04 12:39:44 EST
(In reply to comment #2)
> Yes, checkboxes are part of the client area on all platforms, snippet:

Thanks, Grant. In fact, this snippet demonstrates that it's not an SWT problem at all. Moving to UI.
Comment 4 Brian de Alwis CLA 2011-03-29 10:55:11 EDT
Sorry for the delay in getting back to this.  I finally found a moment to look at fixing the JFace {Table,Tree}ColumnLayouts.  

We need information from SWT to determine the checkbox widths as the column widths on tables do not include the checkbox widths.

To see the problem, try adding the following listener to Grant's example.  It attempts to set the columns to a consistent width based on the available space.

	    table.addListener(SWT.Resize, new Listener() {
	        public void handleEvent(Event event) {
	        	int tableWidth = table.getClientArea().width;
	        	System.out.println("Table width: " + tableWidth);
	        	for(int i = 0; i < table.getColumnCount(); i++) {
	        		table.getColumn(i).setWidth(tableWidth / 3);
	        	}
	        }});

A table without SWT.CHECK never shows a horizontal scroll bar.
A table with SWT.CHECK always shows a horizontal scroll bar.

For the {Table,Tree}ColumnLayout to work properly for tables with checkboxes, we need to know the space taken by the checkboxes.  More accurately, we need to know the space that is actually available to the columns.  I suppose we could embed more platform-specific constants, but that's not very desirable.

Table and Tree on Cocoa do have a method getCheckColumnWidth(), but it is private.  I'm not sure about other platforms.  Would it be possible to expose these methods and make them API?
Comment 5 Eclipse Genie CLA 2019-09-25 15:36:47 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.

--
The automated Eclipse Genie.