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

Bug 347750

Summary: [DataBinding] Databinding between java.io.File#path and Text control doesn't work
Product: [Eclipse Project] Platform Reporter: Sascha Becher <becher-sascha>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: RESOLVED WORKSFORME QA Contact: Matthew Hall <qualidafial>
Severity: enhancement    
Priority: P3 CC: mechko, prakash
Version: 3.7   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Sascha Becher CLA 2011-05-31 05:46:41 EDT
Build Identifier: 

File selectedFile = new File("123");
Binding binding = new DataBindingContext().bindValue(SWTObservables.observeText(textControl), PojoObservables.observeValue(selectedFile, "path")
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));

The binding works only for the first time. The text field shows 123 in the beginning. If selectedFile gets changed and binding.updateModelToTarget(); is being called, the text field doesn't change. 

I guess, it's because class File doesn't has a setter for the property path. 
But I have set the UpdateValueStrategy of targetToModel to POLICY_NEVER, so the setter of File#path isn't required at all and no Exception is thrown (if set to POLICY_UPDATE, an exception occurs).

I find this misleading, as the UpdateValueStrategy's in both directions suggesting control over this aspect.

Reproducible: Always

Steps to Reproduce:
1. run example code
2. see details above
Comment 1 Matthew Hall CLA 2011-09-14 02:26:09 EDT
Hello Sascha!

My apologies for taking so long to respond to this. I hope my response will still be useful to you.

What you are missing is that you can't simply reassign a new value to the selectedFile variable and have data binding pick it up. You must store that value in another observable, and then observe the path as a detail of that observable:

WritableValue fileObservable = WritableValue.withValueType(File.class);
fileObservable.setValue(selectedFile);

When a new file is selected, you indicate this by replacing the value held by the WritableValue:

fileObservable.setValue(newSelectedFile);

Now, to observe the file path, you must observe it as a *detail* of the parent observable, fileObservable:

IObservableFile filePathObservable =
    PojoProperties.value("path").observeDetail(fileObservable);

A "detail" observable is an observable that observes a particular detail of the value of the parent observable--in this case, the file observable. The detail we have chosen to observe is the file's path. So every time we stick a new File object in fileObservable, filePathObservable is updated with the path of that file.

Hope this helps.
Comment 2 Sascha Becher CLA 2011-09-14 06:29:15 EDT
Thanks for the explanation! 

>WritableValue fileObservable = WritableValue.withValueType(File.class);
>fileObservable.setValue(selectedFile);
upon changing the file:
>fileObservable.setValue(newSelectedFile);

Since I still have to catch the event that changes the file, I could simply update the UI element that displays the path with java.io.File. I don't see how this makes my code shorter. Maybe my misunderstanding is to still have a private property java.io.File on the value object instead of just having an IObservableValue that wraps the File object. But this would make the code less readable, I'm afraid.

> IObservableFile filePathObservable =
>     PojoProperties.value("path").observeDetail(fileObservable);

This line doesn't work for me, no IBeanValueProperty#observeDetail found and no IObserveFile, yet I understand what you are suggesting.