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

Bug 148327

Summary: [DataBinding] Java 5 Enum Support
Product: [Eclipse Project] Platform Reporter: Peter Centgraf <peter>
Component: UIAssignee: Jens Lideström <jens>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: c.hauser, djo, jens, Lars.Vogel, matt
Version: 3.2   
Target Milestone: 4.23 M2   
Hardware: All   
OS: All   
See Also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=558842
https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/155307
https://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=c807f128d0b6a181cbaaa2e94dc641960a5f8e74
Whiteboard:

Description Peter Centgraf CLA 2006-06-22 21:00:56 EDT
It should be possible to bind a Java 5 Enum type to a (C)Combo, List, Table, etc. and have the framework do nifty automatic things.  The widget.content should be filled with converter(? extends Enum, String) for each enum value, and the widget.selection should be bound to the specified observable.

For extra credit, the framework could also bind a multi-selection to Collection<? extends Enum> or EnumSet.
Comment 1 Matt Carter CLA 2006-07-20 15:18:08 EDT
+1
Comment 2 Matt Carter CLA 2006-08-14 14:25:07 EDT
I'm implementing support for binding Java 5 Enum type to SWT Radio Buttons, which I need.

I seek some guidance on how this should best be implemented.

Obviously it has be in a separate factory to isolate the Java 5 specific code.. 

Because a set of controls need to be bound, one for each enum option, I envisage binding one radio button to one element of an enum set, like so:

dbc.bind(radioBtnControl, new Property(anObject, "anEnumTypeProperty"),
  new BindSpec(EnumToBooleanConverter(AnEnumType.ENUM_OPTION_1)
)

It feels like I should create a pair of converters.. but the option to bind is model metadata which I cannot pass in to a default converter, so the user would have to create them. I have also considered wrapping the target observable with a description object like so:

dbc.bind(new EnumSelection(radioBtnControl, AnEnumType.ENUM_OPTION_1),
new Property(anObject, "anEnumTypeProperty"));

I could also wrap the model. The model is already a description object so it would be:

dbc.bind(new EnumOption(new Property(anObject, "anEnumTypeProperty"), AnEnumType.ENUM_OPTION_1), new Property(anObject, "anEnumTypeProperty"));

So do I have the user create Converters, wrap the target, or wrap the model?

Also, do I utilise to the existing ButtonObservableValue or create a separate RadioButtonObservableValue for this purpose. (This decision depends on the overall strategy chosen from above).

Also to consider is support for extracting the radio button label from a method on the enumeration, e.g. AnEnumType.ENUM_OPTION_1.label(), the label method name will also have to be provided as metadata.

I have a need to implement this now so any input is appreciated.

Regards
Matt
Comment 3 Matt Carter CLA 2006-08-14 14:27:05 EDT
In my haste I didn't complete the first code block. It should read:

dbc.bind(radioBtnControl, new Property(anObject, "anEnumTypeProperty"),
  new BindSpec(new EnumToBooleanConverter(AnEnumType.ENUM_OPTION_1), new BooleanToEnumConverter(AnEnumType.ENUM_OPTION_1));

Comment 4 Matt Carter CLA 2006-08-14 14:31:06 EDT
ugh, and the third.
Let me repost:

I'm implementing support for binding Java 5 Enum type to SWT Radio Buttons,
which I need.

I seek some guidance on how this should best be implemented.

Obviously it has be in a separate factory to isolate the Java 5 specific code.. 

Because a set of controls need to be bound, one for each enum option, I
envisage binding one radio button to one element of an enum set, like so:

dbc.bind(
  radioBtnControl,
  new Property(anObject, "anEnumTypeProperty"),
  new BindSpec(
    new EnumToBooleanConverter(AnEnumType.ENUM_OPTION_1),
    new BooleanToEnumConverter(AnEnumType.ENUM_OPTION_1),
    null, 
    null
  )
);

It feels like I should create a pair of converters.. but the option to bind is
model metadata which I cannot pass in to a default converter, so the user would
have to create them. I have also considered wrapping the target observable with
a description object like so:

dbc.bind(new EnumSelection(radioBtnControl, AnEnumType.ENUM_OPTION_1),
new Property(anObject, "anEnumTypeProperty"));

I could also wrap the model. The model is already a description object so it
would be:

dbc.bind(radioBtnControl, new EnumOption(new Property(anObject, "anEnumTypeProperty"), AnEnumType.ENUM_OPTION_1));

So do I have the user create Converters, wrap the target, or wrap the model?

Also, do I utilise to the existing ButtonObservableValue or create a separate
RadioButtonObservableValue for this purpose. (This decision depends on the
overall strategy chosen from above).

Also to consider is support for extracting the radio button label from a method
on the enumeration, e.g. AnEnumType.ENUM_OPTION_1.label(), the label method
name will also have to be provided as metadata.

I have a need to implement this now so any input is appreciated.

Regards
Matt

Comment 5 Boris Bokowski CLA 2006-08-17 14:24:09 EDT
(In reply to comment #4)
> Obviously it has be in a separate factory to isolate the Java 5 specific code.. 

Yes.  JFace is targeting CDC-1.0/Foundation-1.0, which is a subset of J2SE 1.3.

> Because a set of controls need to be bound, one for each enum option, I
> envisage binding one radio button to one element of an enum set, like so:

Why not binding a set of buttons to an attribute of an object?

Note that we are likely moving away from Description objects and generic factories (see bug 147563 comment 32, Proposal 1).  I would write a concrete factory that creates a IObservableValue from a set of radio buttons.  Does this make sense?
Comment 6 Peter Centgraf CLA 2006-08-21 13:13:37 EDT
You might create an IObservable that wraps the Composite for the entire radio button group, rather than binding to each individual radio button.  This would provide a better abstraction for the framework, I think.  Your proposal would be more flexible in supporting layouts that put RadioButtons across multiple Composites, but it might suffer from strange side-effects depending on event ordering.

As an aside, I'm interested in a variant that uses this approach to bind a Composite to an IObservableList, rather than an Enum.  In that way, you could bind both the set of RadioButtons and the selection state.  SWT's layout algorithms might make this difficult to do in a general way, though.  (It's difficult to create and destroy controls safely, since setLayoutData() and setData() can attach arbitrary Objects, and some layouts are sensitive to creation order.)
Comment 7 Lars Vogel CLA 2019-09-05 02:53:07 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. If the request is still relevant please remove the stalebug whiteboard tag.
Comment 8 Jens Lideström CLA 2019-12-30 13:31:36 EST
I plan to do something simple to solve this.

Probably a property factory for enum/string conversion.

It could look something like this:

IObservableValue<String> enumLabel = WidgetProperties.comboSelection()
  .value(Properties.enumValue(SomeEnum.class))
  .observe(combo);
Comment 9 Jens Lideström CLA 2020-01-07 14:54:04 EST
I think binding of enum values is already reasonable well-supported by the framework.

To make things a little easier I added a couple of enum converters [1] and updated a snippet to demonstrate enum usage better [2].

The following seems to be the best way to bind to enums:

### Combo and List

This is really easy and pretty: Use a Viewer, bind using ViewerProperties#singleSelection.

It you can't use a Viewer, instead bind manually using the EnumConverters.

### Radio buttons

Use a SelectionObservaleValue, see [2].

--------------

There was apparently higher ambitions for the work that are discussed in this ticket. 

But given that the enum support already is pretty good I think we can close this ticket. 

If there are new concrete proposals about how we could improve enum support we'll handle that in new tickets.

----------------

Snippets with enum binding:

https://git.eclipse.org/c/platform/eclipse.platform.ui.git/tree/examples/org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet024SelectObservableValue.java
https://git.eclipse.org/c/platform/eclipse.platform.ui.git/tree/examples/org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet034ComboViewerAndEnum.java

---------

[1]: https://git.eclipse.org/r/c/155307/
[2]: https://git.eclipse.org/r/c/155308/
Comment 10 Jens Lideström CLA 2021-12-30 10:42:25 EST
Reopening to add better support for enum converters, in the form of the EnumConverters class.