JFaceデータバインディングを使用してラジオボタングループをバインドする適切な方法
-
19-08-2019 - |
質問
JFaceデータバインディングを使用して、ラジオボタンのグループをモデル内のブール変数に適切にバインドする方法を説明できる人がいるかどうか疑問に思っていました。
最初に状況を説明します。3つの要素で構成されるSWTボタンのグループを表すクラスを作成しました(スタイルは 'SWT.RADIO'に設定されています)。質問と2つのボタンのラベル、 <!> quot; yes <!> quot;回答と<!> quot; no <!> quot;に対する回答。ユーザーが<!> quot; yes <!> quot;を選択するように、モデル内のブール変数へのバインディングを作成したいと思います。ラジオボタンブール値はtrueに設定され、彼/彼女が<!> quot; no <!> quot;を選択すると、 buttonブール値は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;
}
}
今、ご覧のとおり、<!> quot; yes <!> quot;をバインドしています。ブールへのボタン。具体的には、値はSWT.selectionイベントにバインドされます。これは、ラジオボタンをバインドするための唯一の有効なイベントのようです。ただし、このため、一度<!> quot; no <!> quot;ボタンが選択されている場合、ブール値は変更されません(<!> quot; yes <!> quot;ボタンでSWT.selectionイベントが発生しなかったため)。
この機能を想定どおりに動作させるには、つまり、ユーザーが選択したボタンに基づいてモデルのブール値を変更できるようにするにはどうすればよいですか?
ここで明らかな何かを見逃していますか?
ありがとう!
解決
つまり、 IObservable を使用して、プロパティにバインドします。
コメントで言及したように、 AbstractObservable 。
このような拡張機能の例がありますこのクラスのテストについて監視可能なリスト(必要なものは必要ありませんが、通知時に変更を検出する際にObservableの使用に関するアイデアを提供できます)
他のヒント
このための最も適切な実装を見つけたと思います。 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を使用できますが、列挙型の方が好きです
Nebula RadioGroup コントロールを使用する場合、RadioGroupViewerを使用して、他のビューアなどのビューア選択ComboViewer
同じコンポジット内のラジオボタンはグループとして機能するため、1つのボタンのみが真の値を持ち、他のボタンはすべて偽の値を持つ必要があります。この事実に加えて、[はい]ボタンの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));
}