views:

1870

answers:

2

Hello,

I was wondering if anyone could explain to me how I could properly bind a group of radio buttons to a boolean variable in the model using JFace data binding.

Let me explain the situation first: I've created a class that represents a group of SWT buttons (with the style set to 'SWT.RADIO') that consists of three elements: A label with the question and two buttons, one for the "yes" answer and one for a "no". I would like to create a binding to a boolean variable in the model in such a way that when a user selects the "yes" radio button the boolean is set to true, and when he/she selects the "no" button the boolean is set to false.

Here's the code of my class:

private class YesOrNoRadioButtonGroup {

private static final String YES = "yes";
private static final String NO = "no";
private Button m_yesButton;
private Button m_noButton;

public YesOrNoRadioButtonGroup(final Composite p_parent,
                               final String p_questionText,
                               final IObservableValue p_modelProperty
                               final DataBindingContext p_dbContext) 
{

  Composite radioButtonGroupContainer = new Composite(p_parent, SWT.NONE);
  radioButtonGroupContainer.setLayout(new GridLayout());
  Label question = new Label(radioButtonGroupContainer, SWT.NONE);
  question.setText(p_questionText);


  m_yesButton = new Button(radioButtonGroupContainer, SWT.RADIO);
  m_yesButton.setText(YES);

  m_noButton = new Button(radioButtonGroupContainer, SWT.RADIO);
  m_noButton.setText(NO);
  m_noButton.setSelection(true);

  Listener yesOrNoRadioGroupListener = new Listener() {

    public void handleEvent(Event p_event) {

      Button button = (Button) p_event.widget;

      if (m_yesButton.equals(button)) {
        m_yesButton.setSelection(true);
        m_noButton.setSelection(false);
      }
      else {
        m_yesButton.setSelection(false);
        m_noButton.setSelection(true);
      }
    }
  };

  m_yesButton.addListener(SWT.Selection, yesOrNoRadioGroupListener);
  m_noButton.addListener(SWT.Selection, yesOrNoRadioGroupListener);

  p_dbContext.bindValue(SWTObservables.observeSelection(this.getYesButton()),
      p_modelProperty, null, null);      
}

public Button getYesButton() {
  return m_yesButton;
}

public Button getNoButton() {
  return m_noButton;
}    


}

Now, as you can see, I'm binding my "yes" button to the boolean. Specifically, the value will be bound on the SWT.selection event. This is, it seems, the only valid event for the binding of a radio button. However, because of this, once the "no" button is selected, the value of the boolean remains unchanged (since no SWT.selection event on the "yes" button was fired).
What can I do to make this work the way it's supposed to, i.e. to be able to change the value of the boolean in the model based on which of the buttons the user selects? Am I missing something obvious here? Thanks!

+3  A: 

It seems similar to binding a POJO to a property.

That means you should have one object with your two buttons implementing an IObservable, and then bind it to your property.
As you mention in the comments, you should extend AbstractObservable.

You have an example of such an extension here with this class Test about an observable list (not necessary what you need but it can give you ideas about the use of Observable when it comes to detect the change upon notification)

VonC
Hmmm... yes, this seems to be the most elegant way to solve this problem. Tnx for the answer, i'll accept it if nobody comes up with anything better. Btw, it seems that I should probably extend AbstractObservable instead of implementing IObservable directly.
Sandman
+1  A: 

The radio buttons within the same composite would act as a group, therefore, only one button will have a true value and all others should have a false value. Along with this fact, the observeSelection on Yes Button should be sufficient enough to reflect the selected value of yes or no, at the model property side.

Or in other words, the modified constructor would look like this.

public YesOrNoRadioButtonGroup(final Composite p_parent, final String p_questionText, final IObservableValue p_modelProperty, final DataBindingContext p_dbContext) {

 Composite radioButtonGroupContainer = new Composite(p_parent, SWT.NONE);
 radioButtonGroupContainer.setLayout(new GridLayout());
 Label question = new Label(radioButtonGroupContainer, SWT.NONE);
 question.setText(p_questionText);

 m_yesButton = new Button(radioButtonGroupContainer, SWT.RADIO);
 m_yesButton.setText(YES);
 m_noButton = new Button(radioButtonGroupContainer, SWT.RADIO);
 m_noButton.setText(NO);
 m_noButton.setSelection(true);

 p_dbContext.bindValue(SWTObservables.observeSelection(this.getYesButton()),
   p_modelProperty, null, null);   

}

I tried this and found working well. Just check out.