diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/TableColumnDescriptor.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/TableColumnDescriptor.java index a4e1fb9537b..b38708b7339 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/TableColumnDescriptor.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/TableColumnDescriptor.java @@ -17,6 +17,8 @@ import java.util.*; +import ghidra.docking.settings.Settings; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.util.Msg; public class TableColumnDescriptor { @@ -95,6 +97,54 @@ public void addVisibleColumn(DynamicTableColumn column) { addVisibleColumn(column, -1, true); } + /** + * Adds a column to the descriptor via an anonymous accessor function instead of an anonymous object + * + * The column type needs to be explicitly specified because there is no way to prevent erasure of the generic + * types of an anonymous function + * + */ + public void addColumn(String name, Class columnTypeClass, RowObjectAccessor rowObjectAccessor, boolean visible) { + AbstractDynamicTableColumn column = new AbstractDynamicTableColumn<>() { + @Override + public String getColumnName() { + return name; + } + + @Override + public COLUMN_TYPE getValue(ROW_TYPE rowObject, Settings settings, Object data, ServiceProvider serviceProvider) throws IllegalArgumentException { + return rowObjectAccessor.access(rowObject); + } + + @Override + public Class getColumnClass() { + return columnTypeClass; + } + + @Override + public Class getSupportedRowType() { + // The reflection tricks in the regular implementation won't work and will always return null + // because of type erasure + return null; + } + }; + if (visible) { + addVisibleColumn(column); + } else { + addHiddenColumn(column); + } + } + /** + * Adds a visible column to the descriptor via an anonymous accessor function instead of an anonymous object + * + * The column type needs to be explicitly specified because there is no way to prevent erasure of the generic + * types of an anonymous function + * + */ + public void addColumn(String name, Class columnTypeClass, RowObjectAccessor rowObjectAccessor) { + addColumn(name, columnTypeClass, rowObjectAccessor, true); + } + /** * @param column the column to add * @param sortOrdinal the ordinal (i.e., 1, 2, 3...n), not the index (i.e, 0, 1, 2...n). @@ -129,4 +179,16 @@ public int compareTo(TableColumnInfo o) { return sortIndex - o.sortIndex; } } + + /** + * A functional interface for accessing a column value from a row object + * This allows for the creation of columns with anonymous functions via {@link #addColumn} + * @param + * @param + */ + @FunctionalInterface + public interface RowObjectAccessor { + public COLUMN_TYPE access(ROW_TYPE rowObject) throws IllegalArgumentException; + } + }