Acme Parts Table
Objective
Display Acme Parts table listing the Acme parts when the Acme Parts action is clicked.
Solution
1. Author TableBuilder.
a. Create the AbstractAcmeTableConfigBuilder class in the package com.example.newui.
b. Set superClass to AbstractComponentConfigBuilder (from com.ptc.mvc.components).
c. Implement the ConfigurableTableBuilder class.
2. Override buildComponentConfig to return a table. Create individual columns and import ColumnConfigandComponentConfigFactory.
@Override
public ComponentConfig buildComponentConfig(ComponentParams params) throws WTException {
ComponentConfigFactory factory = getComponentConfigFactory();
TableConfig table = factory.newTableConfig();

table.setLabel("Acme Parts");
table.setSelectable(true);
table.setActionModel("customPartTable_toolbar");

/**
* These are properties that used to be set on <renderTable>
*/
table.setShowCount(true);
table.setShowCustomViewLink(true);

table.addComponent(factory.newColumnConfig(ICON, true));
ColumnConfig col = factory.newColumnConfig(NAME, true);

table.addComponent(col);
table.addComponent(factory.newColumnConfig(FORMAT_ICON, false));
table.addComponent(factory.newColumnConfig(NUMBER, true));
table.addComponent(factory.newColumnConfig(ORG_ID, false));
table.addComponent(factory.newColumnConfig(INFO_ACTION, false));
ColumnConfig nmActionsCol = factory.newColumnConfig(NM_ACTIONS, false);

table.addComponent(factory.newColumnConfig(SHARE_STATUS_FAMILY, false));
table.addComponent(factory.newColumnConfig(GENERAL_STATUS_FAMILY, false));
table.addComponent(factory.newColumnConfig(CHANGE_STATUS_FAMILY, false));
table.addComponent(factory.newColumnConfig(VERSION, true));
table.addComponent(factory.newColumnConfig(LAST_MODIFIED, true));
table.addComponent(factory.newColumnConfig(CONTAINER_NAME, false));
table.addComponent(factory.newColumnConfig(CUSTOMNAME,customResource.getMessage(CUSTOMNAME), true));

// State column is a DataStore-only column
ColumnConfig stateColumn = factory.newColumnConfig(STATE, true);
stateColumn.setDataStoreOnly(true);
table.addComponent(stateColumn);

return table;
}
3. Override buildConfigurableTable to return the object of the class that defines views.
@Override
public ConfigurableTable buildConfigurableTable(String tableId) throws WTException {
return new MvcConfigurableTable();
}
4. Define custom views using MvcConfigurableTable.
private static class MvcConfigurableTable extends JCAConfigurableTable {

@Override
public Class<?>[] getClassTypes() {
return new Class[] { WTPart.class };
}

@Override
public String getDefaultSortColumn() {
return NUMBER;
}

@Override
public String getLabel(Locale locale) {
return "Acme Parts";
}

@Override
public String getOOTBActiveViewName() {
return "All";
}

@Override
public List<?> getOOTBTableViews(String tableId, Locale locale) throws WTException {

Vector<TableColumnDefinition> columns = getCommonColumnList();

List<TableViewDescriptor> result1 = new ArrayList<TableViewDescriptor>();

String viewName = getViewResourceEntryKey(RESOURCE, "ALL_VIEW_NAME");
String viewDesc = getViewResourceEntryKey(RESOURCE, "ALL_VIEW_NAME_DESC");
TableViewDescriptor tvd = TableViewDescriptor.newTableViewDescriptor(viewName, tableId, true, true, columns, null, true, viewDesc);
result1.add(tvd);
return result1;

}

/**
* This method will return the list of column that will be present in all views
*
* @return
* @throws WTException
*/
private Vector<TableColumnDefinition> getCommonColumnList() throws WTException {
Vector<TableColumnDefinition> columns = new Vector<TableColumnDefinition>();
columns.add(TableColumnDefinition.newTableColumnDefinition(ICON, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(NAME, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(FORMAT_ICON, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(NUMBER, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(ORG_ID, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(INFO_ACTION, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(NM_ACTIONS, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(GENERAL_STATUS_FAMILY, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(VERSION, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(CONTAINER_NAME, /* lockable */false));
columns.add(TableColumnDefinition.newTableColumnDefinition(CUSTOMNAME, /* lockable */false));
return columns;
}

@Override
public boolean isAttributeValidForColumnStep(String columnId) {
if (STATE.equals(columnId)) {
return false;
}

return super.isAttributeValidForColumnStep(columnId);
}

@Override
public List<TextAttribute> getSpecialTableColumnsAttrDefinition(Locale locale) {
List<TextAttribute> result = new ArrayList<TextAttribute>();
result.add(new Attribute.TextAttribute(NM_ACTIONS, "Action", locale));
result.add(new Attribute.TextAttribute(CUSTOMNAME, "CUSTOMNAME", locale));

return result;

}
}
5. Define the resource.
private static final String RESOURCE = "com.example.newui.customUIResource";
6. AbstractComponentConfigBuilder also requires buildComponentData to return the objects (rows) for the table. Add the following code in the method body to query all parts. For clear separation, data fetching part is moved to the subclass ConfigurableTableDataBuilder considering the design. Different data is fetched using different queries for the same table configuration.
@Override
public QueryResult buildComponentData(ComponentConfig config, ComponentParams params) throws WTException {
NmCommandBean cb = ((JcaComponentParams) params).getNmCommandBean();
WTContainer container = cb.getViewingContainer();
QuerySpec qs = new QuerySpec(WTPart.class);
SearchCondition sc = new SearchCondition(WTPart.class, WTPart.CONTAINER_REFERENCE + "." + ObjectReference.KEY,
SearchCondition.EQUAL, PersistenceHelper.getObjectIdentifier(container));
qs.appendWhere(sc, new int[1]);
// Specify latest iteration.
qs.appendAnd();
SearchCondition searchCondition = new SearchCondition(WTPart.class, WTPart.LATEST_ITERATION,
SearchCondition.IS_TRUE);
qs.appendWhere(searchCondition, new int[1]);

QueryResult qr = null;
try {
qr = PersistenceHelper.manager.find((StatementSpec) qs);
}
catch (PartialResultException pre) {
qr = pre.getQueryResult();
}
return qr;
}
7. Create a new class customUIResource to manage the localized display name of the table.
package com.example.newui;
import wt.util.resource.WTListResourceBundle;
//Resource file for the new strings used in new UI
@RBUUID("com.example.newui.customUIResource")
public final class customUIResource extends WTListResourceBundle {
@RBEntry("Custom Acme Name")
public static final String customAcmeName = "customAcmeName";

@RBEntry("All")
@RBComment("Shows All view for Product List table")
public static final String ALL_VIEW_NAME = "ALL_VIEW_NAME";

@RBEntry("Displays all products in which the user is either an active or guest member.")
@RBComment("Displays all products in which the user is either an active or guest member of")
public static final String ALL_VIEW_NAME_DESC = "ALL_VIEW_NAME_DESC";
}
8. After the MVC builders are created, register the builders:
a. Create a custom.site.xconf file in the <customizationRootDirectory>/xconf folder if it has not been already created.
b. Add the custom.mvc.builders.base-packages property in the custom.site.xconf file. Set the value of the property to the name of the base package.
<AddToProperty name="custom.mvc.builders.base-packages" value="com.example.newui.mvc.builder"/>
9. Restart Windchill to verify if the Acme Parts table appears.
Was this helpful?