基本自定义 > 用户界面自定义 > 在 UI 中呈现信息 > 图标委派
  
图标委派
目标
您想要创作一个 IconDelegate 以显示 Windchill 对象类型的图标。
背景
对象图标的目的是让用户轻松分辨出 Windchill UI 中的不同 Windchill 业务对象。可以在对类进行建模时将图标与模型化类型关联。当显示此类型的对象时,将使用此图标。对于子项类型,“类型和属性管理”实用程序允许用户在 UI 中关联用于表示此子项类型的图标。如果指定的图标无效或为空白,则使用父项类型的图标。此行为使用 IconDelegates 来完成。
但是,在某些情况下,这些图标由其他因素 (如对象的属性) 动态确定。下表显示了一些适用于某些 Windchill 类型的预设 IconDelegates
Windchill 类型
IconDelegate
wt.part.WTPart
com.ptc.windchill.enterprise.part.commands.delegate.WTPartIconDelegate
wt.epm.EPMDocument
wt.epm.identity.EPMDocumentIconDelegate
wt.doc.WTDocument
wt.doc.DocumentIconDelegate
如果用户需要针对类型 (非预设) 或用户创建的模型类型/子类型使用不同的图标,则用户需要为相应的类型创作自定义 IconDelegate。
范围/适用性/假设
用户不应该为存在预设 IconDelegate 的类型创作自定义 IconDelegates
预期结果
用户可通过查看由用户为相应 Windchill 类型创作的 IconDelegate 所定义的图标来指定您的图标。
解决方案
Windchill 类型创作自定义 IconDelegate 以指定您的图标。
必备知识
要实现此目标,需要了解以下内容:
Java
Windchill 类型标识符
解决方案元素
元素
类型
说明
<custom_IconDelegate>.java
java
您的 IcondDelegate
运行时位置:
<Windchill>\codebase\*
您的 xconf 文件
xconf
注册您的 IconDelegate
运行时位置:
<Windchill>\codebase\*
过程 - 创作自定义 IconDelegate
Windchill UI 可以处理 Persistable 形式或 TypeInstance 形式的对象,因此 IconDelegates 应该能够处理这两种形式。如果具有 Persistable 形式的对象,则可以轻松使用参与确定图标的属性。如果对象为 TypeInstance 形式且属性不可用,则 TypeInstance 必须对其进行扩展以获得属性,这可能会降低其性能。如果其位于 TypeInstance 对象中,则图标和图标的工具提示将作为 SCA 属性提供,该属性在 <Windchill>\codebase\LogicalAttributes.xml 中定义
<Class name="wt.fc.Persistable">
-------
<Property>
<LogicalForm>objectIcon</LogicalForm>
<ExternalForm>SCA|objectIcon</ExternalForm>
</Property>
<Property>
<!-- This attribute is populated by the SCA|objectIcon
function -->
<LogicalForm>objectTooltip</LogicalForm>
<ExternalForm>NPA|objectTooltip</ExternalForm>
</Property>
创作自定义 IconDelegate
1. 您可以扩展 wt.fc.IconDelegatewt.fc.IconDelegate 的现有子类。
2. 有少数几个 API 需要覆盖,必须在此处放置用于确定逻辑的图标。
a. 这两个 API 返回一个 IconSelector 对象,其中保存了特定 Windchill 对象的图标信息。
API 签名
说明
public IconSelector getStandardIconSelector() throws WTException, IllegalAccessException, InvocationTargetException;
获取图标的标准选择器
public IconSelector getOpenIconSelector() throws WTException, IllegalAccessException, InvocationTargetException;
在打开对象时获取选择器 (例如,打开文件夹时)
b. 此 API 返回需要为图标显示的本地化工具提示值。
API 签名
说明
public String getToolTip()
要与图标一起显示的工具提示。
c. 需要使用此 API 处理 TypeInstances。在此方法中,必须检查可用的 TypeInstance 是否具有满足确定图标和工具提示最低要求的属性值。如果没有,则需要对 TypeInstance 进行扩展。
API 签名
说明
protected Boolean inflateRequired()
如果 TypeInstance 没有计算图标/工具提示必需的属性,则需要进行扩展。
@Override
protected boolean inflateRequired() {
boolean need = super.inflateRequired();
TypeInstance ti = getTypeInstanceObject();
if(ti != null && !need){
//check you necessary attributes in TypeInstance
// to determine to inflate it or not.
}
}
return need;
}
d. 需要使用此 API 处理 TypeInstances。在此方法中,必须添加驱动图标/工具提示确定的所有属性。这将确保其在调用 getStandardIconSelector()getOpenIconSelector() 时可正确填充。
API 签名
说明
protected void initAttributes(Set<AttributeTypeIdentifier> attributes)
使用驱动确定图标/工具提示的属性更新 <AttributeTypeIdentifier>。
@Override
protected void initAttributes(Set<AttributeTypeIdentifier>
attributes) {
super.initAttributes(attributes);
//add your attributes here
}
3. IconDelegate 将定义一个静态帮助程序来创建您的子类可使用的 AttributeTypeIdentifierTypeIdentifier 对象,例如
AttributeTypeIdentifier NAME_ATI = getIdentifier("name",
"wt.part.WTPart");
TypeIdentifier WTPART_TI = getIdentifier("wt.part.WTPart",
null);
4. 如果不可用,getObject() API 会将当前 TypeInstance 转换为 Persistable。因此,为了支持 getObject(false),应避免使用此方法。
编码模式
许多 IconDelegate 子类现在都使用内部 "params" 对象来封装,而无论其是否与 Persistable 或 TypeInstance 搭配使用。params 对象具有图标解析逻辑可使用的简单特性,无论这些属性是从 Persistable 还是 TypeInstance 进行填充。
AttributeTypeIdentifier PERSONAL_CABINET_ATI =
getIdentifier("personalCabinet", "wt.folder.Cabinet");
TypeIdentifier CABINET_TID = getIdentifier("wt.folder.Cabinet",
null);
protected void initAttributes(Set<AttributeTypeIdentifier>
attributes) {
super.initAttributes(attributes);
attributes.add(PERSONAL_CABINET_ATI);
}
private static class ObjectParams {
Cabinet cabinet = null;
TypeInstance ti = null;
ObjectParams(Cabinet cabinet){
if(cabinet != null)
this.cabinet = cabinet;
}
ObjectParams(TypeInstance ti){
if(ti != null)
this.ti = ti;
}
void reSetObject(Cabinet cabinet){
if(cabinet != null)
this.cabinet = cabinet;
}
boolean isPersonalCabinet(){
if(cabinet != null){
return (cabinet.isPersonalCabinet());
}else{
return (Boolean)ti.get(PERSONAL_CABINET_ATI);
}
}
}
protected boolean inflateRequired() {
boolean need = false;
TypeInstance ti = getTypeInstanceObject();
if(ti != null){
need = super.inflateRequired();
if(!need){
if(ti.get(PERSONAL_CABINET_ATI) == null){ // should contain
PERSONAL_CABINET_ATI
need = true;
}
}
}
return need;
}
private ObjectParams getObjectParams(){
ObjectParams object_params = null;
WTObject obj = super.getObject(false);
TypeInstance ti = getTypeInstanceObject();
if (obj != null && obj instanceof Cabinet) {//Object is available
object_params = new ObjectParams((Cabinet)obj);
} else if(ti != null) {//TypeInstance is available
if(inflateRequired()){
obj = super.getObject(true);
if (obj != null && obj instanceof Cabinet) {
object_params = new ObjectParams((Cabinet)obj);
}else{
object_params = null;
}
} else {
object_params = new ObjectParams(ti);
}
}
return object_params;
}

public IconSelector getStandardIconSelector()
throws WTException, IllegalAccessException,
InvocationTargetException {
IconSelector icon = null;
ObjectParams object_params = getObjectParams();
if(object_params != null){
boolean is_personal_cabinet =
object_params.isPersonalCabinet();
if(is_personal_cabinet)
icon = new IconSelector(PERSONAL_ICON);
else
icon = new IconSelector(SHARED_ICON);
}
if (icon == null)
icon = super.getStandardIconSelector();
return icon;
}
注册自定义 IconDelegate
您需要在 xconf 文件中注册自定义 IconDelegate,并通过 xconfmanager 将其传播到 <Windchill>\codebase\service.properties 文件中。
<Service context="default" name="wt.fc.IconDelegate">
<Option cardinality="duplicate" requestor="<your_type>"
serviceClass="<your_IconDelegate>"/>
</Service>