|
17 | 17 |
|
18 | 18 | import java.util.*;
|
19 | 19 |
|
| 20 | +import ghidra.docking.settings.Settings; |
| 21 | +import ghidra.framework.plugintool.ServiceProvider; |
20 | 22 | import ghidra.util.Msg;
|
21 | 23 |
|
22 | 24 | public class TableColumnDescriptor<ROW_TYPE> {
|
@@ -95,6 +97,54 @@ public void addVisibleColumn(DynamicTableColumn<ROW_TYPE, ?, ?> column) {
|
95 | 97 | addVisibleColumn(column, -1, true);
|
96 | 98 | }
|
97 | 99 |
|
| 100 | + /** |
| 101 | + * Adds a column to the descriptor via an anonymous accessor function instead of an anonymous object |
| 102 | + * |
| 103 | + * The column type needs to be explicitly specified because there is no way to prevent erasure of the generic |
| 104 | + * types of an anonymous function |
| 105 | + * |
| 106 | + */ |
| 107 | + public <COLUMN_TYPE> void addColumn(String name, Class<COLUMN_TYPE> columnTypeClass, RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> rowObjectAccessor, boolean visible) { |
| 108 | + AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, Object> column = new AbstractDynamicTableColumn<>() { |
| 109 | + @Override |
| 110 | + public String getColumnName() { |
| 111 | + return name; |
| 112 | + } |
| 113 | + |
| 114 | + @Override |
| 115 | + public COLUMN_TYPE getValue(ROW_TYPE rowObject, Settings settings, Object data, ServiceProvider serviceProvider) throws IllegalArgumentException { |
| 116 | + return rowObjectAccessor.access(rowObject); |
| 117 | + } |
| 118 | + |
| 119 | + @Override |
| 120 | + public Class<COLUMN_TYPE> getColumnClass() { |
| 121 | + return columnTypeClass; |
| 122 | + } |
| 123 | + |
| 124 | + @Override |
| 125 | + public Class<ROW_TYPE> getSupportedRowType() { |
| 126 | + // The reflection tricks in the regular implementation won't work and will always return null |
| 127 | + // because of type erasure |
| 128 | + return null; |
| 129 | + } |
| 130 | + }; |
| 131 | + if (visible) { |
| 132 | + addVisibleColumn(column); |
| 133 | + } else { |
| 134 | + addHiddenColumn(column); |
| 135 | + } |
| 136 | + } |
| 137 | + /** |
| 138 | + * Adds a visible column to the descriptor via an anonymous accessor function instead of an anonymous object |
| 139 | + * |
| 140 | + * The column type needs to be explicitly specified because there is no way to prevent erasure of the generic |
| 141 | + * types of an anonymous function |
| 142 | + * |
| 143 | + */ |
| 144 | + public <COLUMN_TYPE> void addColumn(String name, Class<COLUMN_TYPE> columnTypeClass, RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> rowObjectAccessor) { |
| 145 | + addColumn(name, columnTypeClass, rowObjectAccessor, true); |
| 146 | + } |
| 147 | + |
98 | 148 | /**
|
99 | 149 | * @param column the column to add
|
100 | 150 | * @param sortOrdinal the <b>ordinal (i.e., 1, 2, 3...n)</b>, not the index (i.e, 0, 1, 2...n).
|
@@ -129,4 +179,16 @@ public int compareTo(TableColumnInfo o) {
|
129 | 179 | return sortIndex - o.sortIndex;
|
130 | 180 | }
|
131 | 181 | }
|
| 182 | + |
| 183 | + /** |
| 184 | + * A functional interface for accessing a column value from a row object |
| 185 | + * This allows for the creation of columns with anonymous functions via {@link #addColumn} |
| 186 | + * @param <ROW_TYPE> |
| 187 | + * @param <COLUMN_TYPE> |
| 188 | + */ |
| 189 | + @FunctionalInterface |
| 190 | + public interface RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> { |
| 191 | + public COLUMN_TYPE access(ROW_TYPE rowObject) throws IllegalArgumentException; |
| 192 | + } |
| 193 | + |
132 | 194 | }
|
0 commit comments