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

StackOverflow https://stackoverflow.com/questions/650959

Вопрос

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

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

Это было полезно?

Решение

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

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

У вас есть пример такого расширения здесь с этим классом Test о список наблюдаемых (необязательно, что вам нужно, но он может дать вам представление об использовании 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

Переключатели внутри одного и того же составного элемента будут действовать как группа, поэтому только одна кнопка будет иметь истинное значение, а все остальные должны иметь ложное значение. Наряду с этим фактом, поле 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);   
}

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

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

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

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));
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top