使用 JFace 数据绑定绑定单选按钮组的正确方法
Posted
技术标签:
【中文标题】使用 JFace 数据绑定绑定单选按钮组的正确方法【英文标题】:Proper way to bind a radio button group using JFace data binding 【发布时间】: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 事件)。 我该怎么做才能使这项工作以应有的方式工作,即能够根据用户选择的按钮来更改模型中布尔值的值? 我在这里遗漏了一些明显的东西吗? 谢谢!
【问题讨论】:
【参考方案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));
【讨论】:
以上是关于使用 JFace 数据绑定绑定单选按钮组的正确方法的主要内容,如果未能解决你的问题,请参考以下文章