Pregunta

Me preguntaba si alguien podría explicarme cómo podría vincular correctamente un grupo de botones de radio a una variable booleana en el modelo utilizando el enlace de datos JFace.

Permítanme explicar primero la situación: he creado una clase que representa un grupo de botones SWT (con el estilo establecido en 'SWT.RADIO') que consta de tres elementos: una etiqueta con la pregunta y dos botones, uno para el "sí" respuesta y uno para un "no". Me gustaría crear un enlace a una variable booleana en el modelo de tal manera que cuando un usuario seleccione el "sí" botón de opción el booleano se establece en verdadero, y cuando él / ella selecciona el "no" botón el booleano se establece en falso.

Aquí está el código de mi clase:

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


}

Ahora, como pueden ver, estoy vinculando mi "sí" botón al booleano. Específicamente, el valor estará vinculado al evento SWT.selection. Este es, al parecer, el único evento válido para la unión de un botón de opción. Sin embargo, debido a esto, una vez que el "no" se selecciona el botón, el valor del booleano permanece sin cambios (ya que no se activó ningún evento SWT.selection en el botón "sí").
¿Qué puedo hacer para que esto funcione de la manera en que se supone que debe hacerlo, es decir, para poder cambiar el valor del booleano en el modelo en función de qué botones selecciona el usuario? ¿Me estoy perdiendo algo obvio aquí? Gracias!

¿Fue útil?

Solución

Parece similar a vincular un POJO a una propiedad .

Eso significa que debe tener un objeto con sus dos botones implementando un IObservable , y luego vincúlelo a su propiedad.
Como mencionas en los comentarios, debes extender AbstractObservable .

Tiene un ejemplo de dicha extensión aquí con esta clase Prueba sobre una lista observable (no es necesario lo que necesita, pero puede darle ideas sobre el uso de Observable cuando se trata de detectar el cambio tras la notificación)

Otros consejos

Creo que encontré la implementación más adecuada para esto. Debe usar el org.eclipse.core.databinding.observable.value.SelectObservableValue . aquí está el código

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

Esto funciona, por supuesto, para todo tipo de enumeraciones u otro tipo de valores seleccionables. Por supuesto, podría usar su Cadena SÍ y NO, pero prefiero enumeraciones

Si usa el control Nebula RadioGroup puede usar RadioGroupViewer y vincular el selección de espectador como cualquier otro espectador, por ejemplo ComboViewer

Los botones de radio dentro del mismo compuesto actuarían como un grupo, por lo tanto, solo un botón tendrá un valor verdadero y todos los demás deberían tener un valor falso. Junto con este hecho, el botón observeSelección en Sí debería ser suficiente para reflejar el valor seleccionado de sí o no, en el lado de la propiedad del modelo.

O en otras palabras, el constructor modificado se vería así.

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

Probé esto y encontré que funcionaba bien. Solo echa un vistazo.

Esto es con lo que terminé al asignar botones de radio a enumeración (procederé y lo volveré a usar en nuestro proyecto): el uso de ISWTObservableValue ahorra el esfuerzo de agregar los oyentes:

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

Esto debería funcionar con poco o ningún esfuerzo, y todos sabemos que esa es la mejor respuesta, ¿no?

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));
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top