2009-03-16 5 views
11

JFace 데이터 바인딩을 사용하여 모델의 부울 변수에 라디오 버튼 그룹을 올바르게 바인딩하는 방법을 누군가에게 설명 할 수 있는지 궁금합니다.JFace 데이터 바인딩을 사용하여 라디오 버튼 그룹을 바인딩하는 올바른 방법

상황을 먼저 설명해 드리겠습니다 : 세 가지 요소로 구성된 SWT 버튼 그룹 (SWT.RADIO로 설정된 스타일 포함)을 나타내는 클래스를 만들었습니다. 질문이있는 레이블과 두 개의 버튼 하나는 "예"대답을위한 것이고 다른 하나는 "아니오"를위한 것입니다. 사용자가 "예"라디오 버튼을 선택하면 부울 값이 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 이벤트가 발생하지 않으므로 부울 값이 변경되지 않습니다.
사용자가 선택한 버튼을 기반으로 모델에서 부울 값을 변경할 수 있도록이 작업을 수행하려면 어떻게해야합니까? 나는 여기에서 명백한 무엇인가 놓치고 있냐? 감사합니다.

답변

7

binding a POJO to a property과 비슷합니다.

즉, IObservable을 구현하는 두 개의 버튼이있는 하나의 객체를 가져와 속성에 바인딩해야합니다.
의견에 언급 된대로 AbstractObservable을 확장해야합니다.

당신은 관찰 목록에 대한 이러한 확장 here with this class Test의 예를 가지고 (필요하지 않습니다이 필요하지만이 통지에 따라 변경 감지 할 때 그것은 당신에게 관찰 가능한 사용에 대한 아이디어를 줄 수있는)

+0

음 ... 그렇습니다.이 문제를 해결하는 가장 우아한 방법 인 것 같습니다. 대답은 Tnx, 아무도 더 좋은 것으로 올라 오지 않으면 받아 들일 것입니다. Btw, 아마도 IObservable을 직접 구현하는 대신 AbstractObservable을 확장해야 할 것 같습니다. – Sandman

+0

SeB.Fr은 SelectObservableValue를 사용하여 더욱 우아하고 단순한 솔루션을 제공한다고 생각합니다. – janhink

+1

@ eQui 나는 그 의견에 동의하고 upvoted했다. – VonC

2

라디오를 동일한 복합체 내의 버튼은 그룹으로 작동하므로 하나의 버튼 만 참 값을 가지며 다른 모든 버튼은 거짓 값을 가져야합니다. 이 사실과 함께 Yes 버튼의 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); 
} 

나는 이것을 시도하고 잘 작동하는 것으로 나타났습니다. 그냥 체크 아웃하십시오.

2

Nebula RadioGroup 컨트롤을 사용하는 경우 RadioGroupViewer를 사용하여 다른 뷰어와 마찬가지로 뷰어 선택을 바인딩 할 수 있습니다.

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

사용 ISWTObservableValue은 추가 청취자의 노력을 절약 나는 이것을 위해 가장 적절한 구현을 발견했다. 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")); 
    } 

입니다. 당신은 물론 당신을 사용할 수 있습니다 문자열 예와 아니오,하지만 열거 형을 선호

6

나는 생각한다 - 이것은 내가 (내가 진행하고 프로젝트에 재사용 할 것) 열거 형 라디오 버튼을 매핑 할 때와 끝난 것입니다 ComboViewer

+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)); 
} 
관련 문제