如何使用ovirt中的GWT框架为页面添加组件?修改、添加、删除菜单请参考文档在左侧导航定位页面ovirt中添加/修改页面规则。ovirt页面以集群为例。集群列表页面MainClusterView.java(V)类似页面是MainNetworkView.javaMainHostView.javatabSubTabClusterGeneralView.java类似页面是SubTabHostGeneralView.java创建、删除、修改等按钮监控页面ClusterPopupView.java类似页面是HostPopupView。java如果要查找这些页面,可以在PresenterModule.java页面中通过页面名查询,在PresenterModule中定义了各个tab和popubview的M、V、P的关系。修改页面定位到页面后,可以对页面进行操作,如添加、修改、隐藏某个组件等。注意,如果视图页面有对应的xml页面,修改时需要同步两个文件的内容。下面以新建和编辑虚拟网卡配置集页面的新建安全组下拉列表为例。按照上述方法定位到页面,找到需要修改的页面VnicProfilePopupView.java,发现对应的VnicProfilePopupView.ui.xml中存在VnicProfilePopupView.java各种参考在VnicProfilePopupView中添加安全组radio组件VnicProfilePopupView.ui.xml.ui.xml里面有各种引用xmlns:ui="urn:ui:com.google.gwt.uibinder"xmlns:g="urn:import:com.google.gwt.user.client.ui"xmlns:d="urn:import:org.ovirt.engine.ui.common.widget.dialog"xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor"xmlns:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic"xmlns:k="urn:import:org.ovirt.engine.ui.common.widget.form.key_value"xmlns:b="urn:import:org.gwtbootstrap3.client.ui">建议使用框架中原生的和已知的简单组件,可以上网查询文档参考:组件库ListModelListBoxEditor:Componentnameui:field="securityGroupsEditor":这个参数需要和视图中一样保存在xml中添加css样式.firstRow{padding-top:15px;}.hide_ext{显示:无;可以使用addStyleNames="{style.hide_ext}"将声明的css添加到组件中在VnicProfilePopupView.java中,添加一个名为ui的参数:xml中的字段值,类型对应组件使用@UiField(provided=true)@Path("securityGroups.selectedItem")publicListModelListBoxEditorsecurityGroupsEditor;在构造方法中对组件进行初始化securityGroupsEditor=newListModelListBoxEditor<>(newSecurityGroupForVnicRenderer(constants));VnicProfileModel.javaNewVnicProfileModel.javaEditVnicProfileModel.javaNewVnicProfileModel、EditVnicProfileModel继承了VnicProfileModel,ThesameoperationisimplementedinVnicProfileModel同样的操作声明对象用来保存后台查到的值,名称需要对应视图页面中@Path("securityGroups.selectedItem")中的securityGroups//过滤后台查到的值使之符合组件privateListModelsecurityGroups对应的数据格式;publicListModelgetSecurityGroups(){返回安全组;}publicvoidsetSecurityGroups(ListModelsecurityGroups){this.securityGroups=securityGroupsForVnic>列表值查询>securityys;公共列表getSecuritys(){returnsecurityys;}publicvoidsetSecuritys(Listsecurityys){this.securityys=securityys;}声明空选项,下拉列表设置空选项privatestaticfinalSecurityGroupForVnicEMPTY=SESecurityGroupForVnic();初始化构造方法中的数据//初始化下拉列表值setSecurityGroups(newListModel());//请求后台,查询安全局数据querySecurityGroupList();Frontend.getInstance().runQuery():请求后台接口方法QueryType.GetAllSecurityGroup:后台请求查询,后台实现为GetAllSecurityGroupQuerynewSecurityGroupQueryParameter(0,null):查询参数newAsyncQuery():接口请求回调,在该方法中给securitys赋值publicvoidquerySecurityGroupList(){Frontend.getInstance().runQuery(QueryType.GetAllSecurityGroup,newSecurityGroupQueryParameter(0),newAsyncQuery(returnValue->{if(returnValue!=null){setSecuritys(returnValue.getReturnValue());}}));}在安全组中更改事件添加initSecurityGroups()getDataCenters().getSelectedItemChangedEvent().addListener((ev,sender,args)->{if(getDataCenters().getSelectedItem()!=null){VersiondcCompatibilityVersion=getDataCenters().getSelectedItem().getCompatibilityVersion();GuidcurrentDcId=getDataCenters().getSelectedItem().getId();initCustomPropertySheet(dcCompatibilityVersion);initNetworkQoSList(currentDcId);initNetworkFilterList(dcCompatibilityVersion);initNetworkList(currentDcId);初始值安全组();}});该方法初始化安全组下拉列表privatevoidinitSecurityGroups(){if(!getSecurityGroups().getIsAvailable()){return;}querySecurityGroupList();if(getSecuritys()!=null){ListsecurityGroupForVnics=newArrayList<>();securityGroupForVnics.add(EMPTY_SECURITY);getSecuritys().stream().filter(sg->getDataCenters().getSelectedItem()!=null&&getDataCenters().getSelectedItem().getId().toString().equals(sg.getDataCenterId())).forEach(sg->{SecurityGroupForVnicsecurityGroupForVnic=newSecurityGroupForVnic();securityGroupForVnic.setId(Guid.createGuidFromString(sg.getId()));securityGroupForVnic.setName(sg.getName());securityGroupForVnics.add(securityGroupForVnic);});getSecurityGroups().setItems(securityGroupForVnics);initSecurityGroupsValue();将值放入保存参数SecurityGroupForVnicselectedItem=getSecurityGroups().getSelectedItem();if(selectedItem!=null&&selectedItem.getId()!=null&&!selectedItem.getId().equals(Guid.Empty)){Mapsgs=newHashMap<>();sgs.put("SecurityGroups",selectedItem.getId().toString());//$NON-NLS-1$vnicProfile.setCustomProperties(sgs);}else{vnicProfile.setCustomProperties(null);}NewVnicProfileModel.java中的区别需要从当前下拉列表中的值中选择空选项@OverrideprotectedvoidinitSecurityGroupsValue(){//什么都不做}EditVnicProfileModel.java需要将选中的值渲染到下拉列表中@OverrideprotectedvoidinitSecurityGroupsValue(){if(getProfile().getCustomProperties()!=null&&getProfile().getCustomProperties().get("SecurityGroups")!=null){getSecurityGroups().setSelectedItem(Linq.firstOrNull(getSecurityGroups().getItems(),newLinq.IdPredicate<>(Guid.createGuidFromString(getProfile().getCustomProperties().get("SecurityGroups")))));}}请注意,如果您要创建的实体类需要在该文件中声明Summary只有这个文档说明在前台新建一个GWT组件时,需要做的操作,具体页面和具体功能需要根据实际情况设计