Правильный способ привязки группы переключателей с использованием привязки данных JFace - PullRequest
11 голосов
/ 16 марта 2009

Мне было интересно, может ли кто-нибудь объяснить мне, как правильно связать группу переключателей с логической переменной в модели, используя привязку данных JFace.

Позвольте мне сначала объяснить ситуацию: я создал класс, который представляет группу кнопок SWT (с установленным стилем «SWT.RADIO»), который состоит из трех элементов: метка с вопросом и две кнопки, один для ответа «да» и один для «нет». Я хотел бы создать привязку к логической переменной в модели таким образом, чтобы при выборе пользователем переключателя «да» логическое значение устанавливалось в значение «истина», а при выборе кнопки «нет» логическое значение установлено в 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» для кнопки «да» не было запущено).
Что я могу сделать, чтобы заставить эту работу работать так, как она должна, т. Е. Чтобы иметь возможность изменять значение логического значения в модели в зависимости от того, какую из кнопок выбирает пользователь? Я что-то упускаю здесь очевидное? Спасибо!

Ответы [ 6 ]

7 голосов
/ 17 марта 2009

Это похоже на привязку POJO к свойству .

Это означает, что у вас должен быть один объект с двумя кнопками, реализующими IObservable , а затем привязать его к вашему свойству.
Как вы упоминаете в комментариях, вы должны расширить AbstractObservable .

У вас есть пример такого расширения здесь с этим классом Test о наблюдаемом списке (не обязательно, что вам нужно, но он может дать вам представление об использовании Observable, когда дело доходит до обнаружения изменения после уведомления)

6 голосов
/ 28 февраля 2013

Я думаю, что нашел наиболее подходящую реализацию для этого. Вам необходимо использовать 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, но я предпочитаю enums

2 голосов
/ 10 декабря 2010

Если вы используете элемент управления Nebula RadioGroup , вы можете использовать RadioGroupViewer и привязать выбор зрителя, как и любой другой зритель, например, ComboViewer

2 голосов
/ 29 июля 2009

Переключатели внутри одного и того же композита будут действовать как группа, поэтому только одна кнопка будет иметь истинное значение, а все остальные должны иметь ложное значение. Наряду с этим фактом, поле visibleSelection для кнопки «Да» должно быть достаточным для отражения выбранного значения «да» или «нет» на стороне свойства модели.

Или, другими словами, модифицированный конструктор будет выглядеть следующим образом.

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

Я попробовал это и нашел работу хорошо. Просто проверьте.

0 голосов
/ 28 июня 2015

Это должно работать без особых усилий, и мы все знаем, что это лучший ответ, верно?

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));
}
0 голосов
/ 18 сентября 2012

Это то, с чем я закончил, когда отображал переключатели в enum (я продолжу и сделаю его многоразовым в нашем проекте) - использование 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);
...