【问题标题】:Proper way to bind a radio button group using JFace data binding使用 JFace 数据绑定绑定单选按钮组的正确方法
【发布时间】:2010-10-13 15:38:19
【问题描述】:

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

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

这是我班级的代码:

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


}

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

【问题讨论】:

    标签: swt eclipse-rcp jface data-binding


    【解决方案1】:

    似乎类似于binding a POJO to a property

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

    您有一个这样的扩展示例here with this class Test 关于可观察列表(不是您所需要的,但它可以让您了解在通知时检测更改时使用可观察)

    【讨论】:

    • 嗯...是的,这似乎是解决这个问题的最优雅的方法。 Tnx 的答案,如果没有人提出更好的建议,我会接受它。顺便说一句,似乎我应该扩展 AbstractObservable 而不是直接实现 IObservable。
    • 我认为 SeB.Fr 使用 SelectObservableValue 提供了更优雅、更简单的解决方案。
    【解决方案2】:

    我想我找到了最合适的实现。 您需要使用 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,但我更喜欢枚举

    【讨论】:

    • 我认为这是最优雅的解决方案,谢谢!
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      同一组合中的单选按钮将作为一个组,因此,只有一个按钮具有真值,所有其他按钮都应具有假值。除了这个事实,Yes Button 上的 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);   
      }
      

      我试过了,发现效果很好。去看看吧。

      【讨论】:

        【解决方案5】:

        这是我在将单选按钮映射到枚举时得到的结果(我将继续并使其在我们的项目中可重用) - 使用 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);
        

        【讨论】:

          【解决方案6】:

          这应该不费吹灰之力,而且我们都知道这是最好的答案,对吧?

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-27
            相关资源
            最近更新 更多