使用 JFace 数据绑定绑定单选按钮组的正确方法
-
19-08-2019 - |
题
我想知道是否有人可以向我解释如何使用 JFace 数据绑定将一组单选按钮正确绑定到模型中的布尔变量。
我先说明一下情况:我创建了一个类来表示一组 SWT 按钮(样式设置为“SWT.RADIO”),该按钮由三个元素组成:带有问题和两个按钮的标签,一个用于回答“是”,一个用于回答“否”。我想创建一个到模型中布尔变量的绑定,当用户选择“是”单选按钮时,布尔值设置为 true,当他/她选择“否”按钮时,布尔值设置为设置为假。
这是我的班级的代码:
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 事件。这似乎是绑定单选按钮的唯一有效事件。然而,正因为如此,一旦选择了“no”按钮,布尔值就保持不变(因为“yes”按钮上没有触发 SWT.selection 事件)。
我该怎么做才能使这项工作按预期方式进行,即能够根据用户选择的按钮来更改模型中布尔值的值?我在这里遗漏了一些明显的东西吗?谢谢!
解决方案
看起来类似于 将 POJO 绑定到属性.
这意味着您应该有一个对象,其中两个按钮实现 IObservable, ,然后将其绑定到您的财产。
正如您在评论中提到的,您应该扩展 抽象可观察.
您有一个此类扩展的示例 这里有这个类测试 关于可观察列表(不一定是您需要的,但它可以为您提供有关在通知后检测更改时使用可观察列表的想法)
其他提示
我想我找到了这个最appropiate实施。 你需要使用 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"));
}
此工作当然对人类的枚举或其它种类的可选择的值组成。当然,你可以使用你的字符串YES和NO,但我更喜欢枚举
如果使用您的星云RadioGroup中控制可以使用RadioGroupViewer和绑定观众选择像任何其他浏览器如ComboViewer
相同的复合材料内的单选按钮将作为一组,因此,只有一个按钮将具有真值和所有其他应该有一个假值。随着这一事实,对是按钮的observeSelection应足以反映的是所选择的价值或没有,在模型属性的一面。
或者换言之,经修改的构造是这样的。
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);
}
我尝试这样做,发现工作良好。只是检查出。
这是我结束了绘制单选按钮时,枚举(我将继续,并且让它在我们的项目中重复使用)与 - 使用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);
这应该很少努力没有努力,我们都知道这是最好的一种回答吧?
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));
}