使用JFace数据绑定绑定单选按钮组的正确方法

时间:2009-03-16 15:40:52

标签: swt eclipse-rcp jface data-binding

我想知道是否有人可以向我解释如何使用JFace数据绑定将一组单选按钮正确绑定到模型中的布尔变量。

让我先解释一下情况:我创建了一个代表一组SWT按钮的类(样式设置为'SWT.RADIO'),它由三个元素组成:带有问题的标签和两个按钮,一个用于“是”答案,一个用于“否”。我想在模型中创建一个布尔变量的绑定,这样当用户选择“是”单选按钮时,布尔值设置为true,当他/她选择“否”按钮时,布尔值为设置为false。

这是我班级的代码:

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;
}    


}

现在,正如您所看到的,我将“yes”按钮绑定到布尔值。具体来说,该值将绑定在SWT.selection事件上。这似乎是绑定单选按钮的唯一有效事件。但是,因此,一旦选择了“no”按钮,布尔值保持不变(因为“yes”按钮上没有触发SWT.selection事件)。
我该怎么做才能使它按照预期的方式工作,即能够根据用户选择的按钮更改模型中布尔值的值? 我错过了一些明显的东西吗? 谢谢!

6 个答案:

答案 0 :(得分:7)

它似乎与binding a POJO to a property类似。

这意味着你应该有一个对象,你的两个按钮实现IObservable,然后将它绑定到你的财产。
正如您在评论中提到的那样,您应该扩展AbstractObservable

您有一个关于可观察列表的扩展here with this class Test的示例(不需要您需要的内容,但它可以为您提供有关在通知时检测更改时使用Observable的想法)

答案 1 :(得分:6)

我认为我找到了最合适的实施方案。 您需要使用 org.eclipse.core.databinding.observable.value.SelectObservableValue 。 这是代码

class YesNoModel{
   public static enum RESPONSE {YES,NO};
   private RESPONSE value;
   public RESPONSE getValue(){return value;}
   public void setValue(RESPONSE value){this.value = value;}
}
class YouGraphicalClass {
   YesNoModel yesNomodel  = new YesNoModel();
   void iniDataBinding(){
        IObservableValue yesBtnSelection  = SWTObservables.observeSelection(this.getYesButton());
        IObservableValue noBtnSelection  = SWTObservables.observeSelection(this.getNoButton());
        SelectObservableValue featureRepoPolicyObservable = new SelectObservableValue(YesNoModel.RESPONSE.class);
        featureRepoPolicyObservable.addOption(RESPONSE.YES, yesBtnSelection);
        featureRepoPolicyObservable.addOption(RESPONSE.NO, noBtnSelection);
        p_dbContext.bindValue(featureRepoPolicyObservable,
                PojoObservables.observeValue(yesNomodel, "value"));
    }

这当然适用于各种枚举或其他类型的可选值。你当然可以使用String YES和NO,但我更喜欢枚举

答案 2 :(得分:2)

同一合成中的单选按钮将充当一个组,因此,只有一个按钮具有真值,而所有其他按钮都应具有假值。除此之外,Yes按钮上的observeSelection应足以在模型属性端反映所选的yes或no值。

或者换句话说,修改后的构造函数看起来像这样。

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);   
}

我试过这个并且发现效果很好。退房。

答案 3 :(得分:2)

如果使用Nebula RadioGroup控件,您可以使用RadioGroupViewer并像任何其他查看器一样绑定查看器选择,例如ComboViewer

答案 4 :(得分:0)

这是我在将单选按钮映射到枚举时最终得到的结果(我将继续并使其在我们的项目中可重用) - 使用ISWTObservableValue可以节省添加侦听器的工作量:

    final ISWTObservableValue upload = SWTObservables.observeSelection(btnUpload);
    final ISWTObservableValue download = SWTObservables.observeSelection(btnDownload);
    final ISWTObservableValue noTransfer = SWTObservables.observeSelection(btnNoTransfer);
    final IObservableValue btns = new ComputedValue(ExecutableTransferModes.class) {

        @Override
        protected void doSetValue(final Object value) {
            boolean u = false, d = false, n = false;
            switch ((ExecutableTransferModes) value) {
            case Upload:
                u = true;
                break;
            case Download:
                d = true;
                break;
            case Notransfer:
                n = true;
                break;
            }
            upload.setValue(u);
            download.setValue(d);
            noTransfer.setValue(n);
        }

        @Override
        protected Object calculate() {
            if (Boolean.TRUE.equals(upload.getValue())) {
                return ExecutableTransferModes.Upload;
            } else if (Boolean.TRUE.equals(download.getValue())) {
                return ExecutableTransferModes.Download;
            } else if (Boolean.TRUE.equals(noTransfer.getValue())) {
                return ExecutableTransferModes.Notransfer;
            } else {
                return null;
            }
        }
    };
    bindingContext.bindValue(btns, uploadProperty);

答案 5 :(得分:0)

这应该很少或没有努力,我们都知道这是最好的答案吗?

public static final void createAndBind(
    final DataBindingContext dbc, 
    final Composite parent,
    final Object bean, 
    final List<Object> options, 
    final String fieldName, 
    final Class<?> fieldType) {
    //
    List<Button> radios = new ArrayList<>();
    Button b;
    for (Object option : options) {
        b = new Button(parent, SWT.RADIO);
        b.setText(option.toString());
        b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        radios.add(b);
    }
    //
    List<IObservableValue> iovs = new ArrayList<>();
    IObservableValue iov;
    for (Button radio : radios) {
        iov = SWTObservables.observeSelection(radio);
        iovs.add(iov);
    }
    SelectObservableValue observable = new SelectObservableValue(fieldType);
    //
    for (int i = 0; i < options.size(); i++) {
        observable.addOption(options.get(i), iovs.get(i));
    }
    //
    dbc.bindValue(observable, PojoObservables.observeValue(bean, fieldName));
}