Wednesday, October 08, 2008

Disable parts SWT-Table/Tree with SWT.CHECK

This is a hack, a hack, a hack posting.

I have read many many entries on the newsgroups asking a question like this:

How can I disable certain check boxes in an SWT-Tree/Table. Is this possible?

The standard answer to this was: "Sorry no this is not possible". Today I faced the same problem (mine had to do with ViewerObservables#observeCheckElements()) where the user is not allowed to check the Top-Level-Nodes.

The tree looks like this:

+ Application 1
+ Privilege A
+ Privileg A1
+ Privilege B
+ Privileg B2
+ Application 1
+ Privileg C


The values bound are the ones in Privileg* so I have to lock the Application-checkboxes

The setup is something like this:

Databinding ctx = ....
IObservableSet mObs = ....

Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);
IObservableSet uiOs = ViewerObservables.observeCheckedElements(v,IPrivileges.class);
ctx.bindSet(uiObs,mObs,null,null);


I nearly gave up but then I had the following idea.


final Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
// Attach a listener directly after the creation
tree.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
if( event.detail == SWT.CHECK ) {
if( !(event.item.getData() instanceof IPrivileg) ) {
event.detail = SWT.NONE;
event.type = SWT.None;
event.doIt = false;
try {
tree.setRedraw(false);
TreeItem item = (TreeItem)tree.item;
item.setChecked(! item.getChecked() );
} finally {
tree.setRedraw(true);
}
}
}
}
});

CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);
// ....


This is a hack, I only tested it on Win32 (XP) and don't know how cross platform it is so don't kill me for posting this hack of hacks.

10 comments:

Konstantin Komissarchik said...

I've struggled with this problem as well. My solution was a little higher-level than yours (used check listener on the viewer). As far as I know, it works fine on only platforms. Unfortunately, not allowing check/uncheck is only half of the problem. You have to still give the user some sense that they are looking at an unmodifiable item or they get frustrated trying to check/uncheck. After a few iterations, the solution that I came up with is to use a lock overlay on the icon associated with the tree item and to display a tooltip explaining the situation if the user actually tries to check/uncheck. Before the tooltip, I tried a dialog box, but the dialog box was quite jarring. The tooltip conveys the message and is less in your face.

If you want to see my solution in action, just take a look at WTP. Open Dynamic Web Project wizard and select "Modify" next to configurations combo.

Tom said...

That's too late for me because then databinding already stepped in tried to update the model-observable and I'll have an exception logged.

With this solution the CheckTreeViewer doesn't even get a check-changed event so so do all other who are attaching themselves on the control.

Unknown said...

Great idea !

but, Why can't you use en image whith the labelprovider?
(i know the image can change... depends of the platform & you can't use databinding but... you don't use hack ^^)

Tom said...

Well the image is not the problem see http://tom-eclipse-dev.blogspot.com/2007/01/tableviewers-and-nativelooking.html

Steve said...

What is the setRedraw() doing? Get rid of it.

Steve

Anonymous said...

In order to add the visual indication to this issue I changed the foreground of those "disabled" items...

Laptop Parts said...

Interesting stuff I must admit. But what I really want to know is how did you really compose all this coding?? Okay, once I get this down hopefully it will work for me because I tried a couple different ways and none of them seemed to work. No worries though, that's why Google is here! haha I can literally find anything to everything on the web nowadays but enough of that.. But then thing is, that whenever I try inserting something like this it say, "The project type is not supported by this installation" How can I solve this problem?

Unknown said...

I was able to disable chekboxes, but it is done via listener. Seems Eclipse 3.5 has ICheckStateProvider that suppose to make this task easier.

buy generic viagra online said...

Hey your blog is so interesting.... I enjoyed to be reading your blog. Thanks very much! Keep posting.....

James Woods,
Health Consultant

vineel yalamarthy said...

Hi Every One,Can any one suggest me how to remove a check box placed in front of every row in SWT Table.

This is the constructor to create a TABLE .For this table whenever a row gets populated, a check box is visible.Now , I need to remove the check box.

The constructor for the table creation looks like this.

final Table table = toolkit.createTable(composite, SWT.FULL_SELECTION
| SWT.BORDER |SWT.Activate| SWT.SetData);
table.setHeaderVisible(false);
// table.getColumn(0).setToolTipText(null);
final TableViewer tableViewer = new TableViewer(table);
ColumnViewerToolTipSupport.enableFor(tableViewer);

TableLayout layout = new TableLayout();
table.setLayout(layout);
table.setHeaderVisible(true);
table.setLinesVisible(true);