Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(8/19)

时间:2022-11-11 17:26:48
 

更改 Presentation Model

现在已将代码分离为 UI、Presentation Model 和域模型层,您可以轻松地修改代码以满足更改要求。假定客户机需要更直观并且拥有如图 6 所示的带 Married 复选框的 UI,选中/取消选中此框将同时启用/禁用 Spouse 字段和 Years Married 字段。



图 6. 添加直观的复选框后的示例 UI
Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(8/19)

由于要更改 Presentation Model 的功能,因此需要修改测试以验证实现内容。清单 9 显示了经过调整的测试方法。复选框将处理启用状态的更改,因此只需更改侦听程序中另一个逻辑来根据需要清空与两个婚姻状况相关的字段。



清单 9. 重构后的启用测试
                    
public void testYearsMarriedEnablement() {
    Contact contact = new Contact();
    ContactPresentationModel presentationModel = new ContactPresentationModel(
            contact);

    assertFalse(presentationModel.getEnableYearsMarried());

    presentationModel.setEnableYearsMarried(true);
    presentationModel.getContact().setSpouse("spouse");
    presentationModel.getContact().setYearsMarried("5");
    presentationModel.setEnableYearsMarried(false);

    assertNull(presentationModel.getContact().getSpouse());
    assertNull(presentationModel.getContact().getYearsMarried());
}

要使测试能够通过,则需重构 ContactPresentationModel 构造函数和 EnablementPropertyChangeListener,如清单 10 所示。



清单 10. 修改 Presentation Model 使其能够显式启用
                    
public ContactPresentationModel(Contact contact) {
    this.contact = contact;

    EnablementPropertyChangeListener enablementPropertyChangeListener = 
    	new  EnablementPropertyChangeListener();
    addPropertyChangeListener("enableYearsMarried",
            enablementPropertyChangeListener);
}


private class EnablementPropertyChangeListener implements
        PropertyChangeListener {

    public void propertyChange(PropertyChangeEvent evt) {
        if (!getEnableYearsMarried()) {
            getContact().setYearsMarried(null);
 	    getContact().setSpouse(null);
        }
    }
}

最后还需要做的是修改 UI。需要将标签和复选框添加到 createControls() 方法中。然后必须将这个新复选框绑定到 Presentation Model。最后,为了像 Years Married 字段一样可以启用/禁用 Spouse 字段,请将 Spouse 字段的已启用属性绑定到 Presentation Model 中的同一位置。这些更改如清单 11 所示。



清单 11. 将复选框添加到 UI 中
                    
private void bindGUI(ContactPresentationModel 
presentationModel) {
. . .
   ctx.bind(chkIsMarried,  
        new Property(presentationModel, "enableYearsMarried"),      new BindSpec());
   ctx.bind(new Property(spouseTxt, "enabled"),  
        new Property(presentationModel, "enableYearsMarried"), 
            new BindSpec());

}

private void createControls(Composite c) {

    . . .

    Label labelMarried = new Label(c, SWT.SHELL_TRIM);
    labelMarried.setText("Married");

    gridData = new GridData(GridData.FILL_HORIZONTAL);
    this.chkIsMarried = new Button(c, SWT.CHECK);
    this.chkIsMarried.setLayoutData(gridData);

    . . .
}

如您所见,可以对示例的每个构建块做出关系紧密的更改。可以很轻松地修改启用逻辑以清空模型中的第二个字段。而这只需要多加一行绑定代码就可以实现对 UI 中的附加 Spouse 字段的启用并使其保持同步。