图标委派
目标
您想要创作一个 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>
* 
建议创建一个自定义 LogicalAttributesSite.xml 文件来配置自定义逻辑属性,并使用特性 com.ptc.core.meta.common.impl.LogicalIdentifierFactory.translatorSelectors 指定此自定义 LogicalAttributesSite.xml 文件的位置。通过设置此特性,管理员可以确保 Windchill 对逻辑属性使用正确的自定义配置。
创作自定义 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>
这对您有帮助吗?