2009-03-16 6 views
11

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

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

ответ

7

Похоже на binding a POJO to a property.

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

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

+0

Хммм ... да, это, кажется, самый элегантный способ решить эту проблему. Tnx для ответа, я соглашусь, если никто не придумает ничего лучшего. Кстати, кажется, что я должен, вероятно, расширить AbstractObservable, а не напрямую выполнять IObservable. – Sandman

+0

Я думаю, что SeB.Fr предоставил еще более элегантное и более простое решение, используя SelectObservableValue. – janhink

+1

@eQui Я согласен и поддержал этот пост. – VonC

2

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

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

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

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

2

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

0

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

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

Это работает, конечно, для аль рода перечислений или другого вида выбираемых значений. Вы могли бы, конечно, использовать вас String YES и NO, но я предпочитаю перечисления

+0

Я думаю, что это самое элегантное решение, спасибо! – janhink

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