Skip to content

Commit

Permalink
Concise creation of simple DynamicTableColumns
Browse files Browse the repository at this point in the history
  • Loading branch information
fmagin committed Jan 10, 2025
1 parent 20285e2 commit 27319f8
Showing 1 changed file with 62 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import java.util.*;

import ghidra.docking.settings.Settings;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.util.Msg;

public class TableColumnDescriptor<ROW_TYPE> {
Expand Down Expand Up @@ -95,6 +97,54 @@ public void addVisibleColumn(DynamicTableColumn<ROW_TYPE, ?, ?> 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 <COLUMN_TYPE> void addColumn(String name, Class<COLUMN_TYPE> columnTypeClass, RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> rowObjectAccessor, boolean visible) {
AbstractDynamicTableColumn<ROW_TYPE, COLUMN_TYPE, Object> 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<COLUMN_TYPE> getColumnClass() {
return columnTypeClass;
}

@Override
public Class<ROW_TYPE> 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 <COLUMN_TYPE> void addColumn(String name, Class<COLUMN_TYPE> columnTypeClass, RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> rowObjectAccessor) {
addColumn(name, columnTypeClass, rowObjectAccessor, true);
}

/**
* @param column the column to add
* @param sortOrdinal the <b>ordinal (i.e., 1, 2, 3...n)</b>, not the index (i.e, 0, 1, 2...n).
Expand Down Expand Up @@ -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 <ROW_TYPE>
* @param <COLUMN_TYPE>
*/
@FunctionalInterface
public interface RowObjectAccessor<ROW_TYPE, COLUMN_TYPE> {
public COLUMN_TYPE access(ROW_TYPE rowObject) throws IllegalArgumentException;
}

}

0 comments on commit 27319f8

Please sign in to comment.