2009-03-16 17 views
11

Tôi tự hỏi liệu có ai có thể giải thích cho tôi cách tôi có thể ràng buộc một nhóm nút radio thành biến boolean trong mô hình bằng cách sử dụng liên kết dữ liệu JFace hay không.Cách thích hợp để ràng buộc nhóm nút radio bằng cách sử dụng liên kết dữ liệu JFace

Để tôi giải thích tình huống trước: Tôi đã tạo một lớp đại diện cho một nhóm nút SWT (với kiểu được đặt thành 'SWT.RADIO') bao gồm ba phần tử: Nhãn có câu hỏi và hai nút , một cho câu trả lời "có" và một cho "không". Tôi muốn tạo một ràng buộc với biến boolean trong mô hình theo cách mà khi người dùng chọn nút radio "có", boolean được đặt thành true và khi người đó chọn nút "no" thì boolean là đặt thành false.

Dưới đây là đoạn code của lớp học của tôi:

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


} 

Bây giờ, như bạn có thể thấy, tôi đang ràng buộc nút "yes" của tôi vào boolean. Cụ thể, giá trị sẽ được ràng buộc trong sự kiện SWT.selection. Đây là, có vẻ như, sự kiện hợp lệ duy nhất cho sự ràng buộc của một nút radio. Tuy nhiên, vì điều này, một khi nút "no" được chọn, giá trị của boolean vẫn không thay đổi (vì không có sự kiện SWT.selection nào trên nút "yes" được kích hoạt).
Tôi có thể làm gì để thực hiện công việc này theo cách của nó, tức là để có thể thay đổi giá trị của boolean trong mô hình dựa trên các nút mà người dùng chọn? Tôi có thiếu điều gì đó hiển nhiên ở đây không? Cảm ơn!

Trả lời

7

Có vẻ như là binding a POJO to a property.

Điều đó có nghĩa là bạn nên có một đối tượng với hai nút đang triển khai IObservable và sau đó liên kết nó với thuộc tính của bạn.
Khi bạn đề cập trong các nhận xét, bạn nên mở rộng AbstractObservable.

Bạn có một ví dụ về một phần mở rộng here with this class Test ví dụ về một danh sách quan sát được (không cần thiết những gì bạn cần nhưng nó có thể cung cấp cho bạn những ý tưởng về việc sử dụng Quan sát khi nói đến phát hiện sự thay đổi theo thông báo)

+0

Hmmm ... có, đây có vẻ là cách thanh lịch nhất để giải quyết vấn đề này. Tnx cho câu trả lời, tôi sẽ chấp nhận nó nếu không ai đến với bất cứ điều gì tốt hơn. Btw, có vẻ như tôi có lẽ nên mở rộng AbstractObservable thay vì thực hiện IObservable trực tiếp. – Sandman

+0

Tôi nghĩ rằng SeB.Fr cung cấp giải pháp thậm chí thanh lịch hơn và đơn giản hơn bằng cách sử dụng SelectObservableValue. – janhink

+1

@eQui Tôi đồng ý và đã bỏ phiếu cho bài đăng đó. – VonC

2

Các đài phát thanh các nút trong cùng một kết hợp sẽ hoạt động như một nhóm, do đó, chỉ một nút sẽ có giá trị thực và tất cả các nút khác sẽ có giá trị sai. Cùng với thực tế này, observSelection trên Yes Button phải đủ đủ để phản ánh giá trị đã chọn có hoặc không, ở phía thuộc tính mô hình.

Hoặc nói cách khác, hàm tạo được sửa đổi sẽ trông như thế này.

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

Tôi đã thử tính năng này và hoạt động tốt. Chỉ cần kiểm tra.

2

Nếu sử dụng điều khiển Nebula RadioGroup, bạn có thể sử dụng RadioGroupViewer và liên kết lựa chọn trình xem như bất kỳ trình xem nào khác, ví dụ: ComboViewer

0

Đây là những gì tôi đã kết thúc với khi lập bản đồ nút radio để enum (tôi sẽ tiến hành và làm cho nó tái sử dụng trong dự án của chúng tôi) - sử dụng ISWTObservableValue tiết kiệm các nỗ lực của việc thêm các thính giả:

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

Tôi nghĩ Tôi đã tìm thấy triển khai thích hợp nhất cho việc này. Bạn cần sử dụng org.eclipse.core.databinding.observable.value.SelectObservableValue. ở đây là mã số

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

Công trình này tất nhiên là dành cho một loại enums hoặc các loại giá trị có thể chọn khác. Tất nhiên, bạn có thể sử dụng bạn String YES và NO, nhưng tôi thích enums

+0

Tôi nghĩ đây là giải pháp thanh lịch nhất, cảm ơn! – janhink

0

Điều này sẽ làm việc với ít hoặc không có nỗ lực, và chúng ta đều biết đó là loại câu trả lời đúng nhất?

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