11

JFace データバインディングを使用して、ラジオボタンのグループをモデルのブール変数に適切にバインドする方法を誰かが説明してくれるかどうか疑問に思っていました。

最初に状況を説明しましょう: SWT ボタンのグループ (スタイルを「SWT.RADIO」に設定) を表すクラスを作成しました。このクラスは、次の 3 つの要素で構成されています。 「はい」の答えと「いいえ」の答え。ユーザーが「はい」ラジオボタンを選択するとブール値が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;
}    


}

ご覧のとおり、「はい」ボタンをブール値にバインドしています。具体的には、値は SWT.selection イベントにバインドされます。これは、ラジオ ボタンのバインドに有効な唯一のイベントのようです。ただし、このため、「いいえ」ボタンが選択されると、ブール値は変更されません (「はい」ボタンで SWT.selection イベントが発生しないため)。
これを想定どおりに機能させるには、つまり、ユーザーが選択したボタンに基づいてモデルのブール値を変更できるようにするにはどうすればよいですか? ここで明らかな何かが欠けていますか?ありがとう!

4

6 に答える 6

7

これは、POJOをプロパティにバインドするのと似ているようです。

つまり、2つのボタンでIObservableを実装する1つのオブジェクトを作成し、それをプロパティにバインドする必要があります。
コメントで述べているように、AbstractObservableを拡張する必要があります。

このクラスでは、このような拡張の例があります。監視可能なリストについてテストします(必要なものは必要ありませんが、通知時に変更を検出する場合にObservableの使用についてのアイデアを得ることができます)

于 2009-03-17T09:43:11.830 に答える
7

これに最も適した実装を見つけたと思います。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 を使用することもできますが、私は列挙型を好みます

于 2013-02-28T14:30:58.413 に答える
2

同じコンポジット内のラジオボタンはグループとして機能するため、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);   
}

これを試してみたところ、うまく機能していることがわかりました。チェックアウトしてください。

于 2009-07-29T16:12:53.493 に答える
2

Nebula RadioGroupコントロールを使用する場合は、 RadioGroupViewer を使用して、 ComboViewer などの他のビューアーと同様にビューアーの選択をバインドできます。

于 2010-12-09T23:12:34.383 に答える
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);
于 2012-09-17T23:00:29.833 に答える
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));
}
于 2015-06-28T05:40:27.050 に答える