Reputation: 121702
The FXML for the TableView
is as such:
<TableView fx:id="invocationStatsTable">
<columns>
<TableColumn fx:id="ruleName" text="Rule"/>
<TableColumn fx:id="ruleClass" text="Rule class"/>
<TableColumn fx:id="ruleType" text="Rule type"/>
<TableColumn fx:id="nrCalls" text="Invocations"
sortType="DESCENDING"/>
<TableColumn fx:id="callDetail" text="N / E / F (*)"
sortable="false"/>
<TableColumn fx:id="callGraph" text="Graph" sortable="false"
prefWidth="200.0"/>
</columns>
</TableView>
which gives this (bottom):
The problem is immediately, well, visible: columns are not sized correctly.
And I'd like to avoid having to set prefWidth
by hand on all columns since
I'd much rather the resize were automatic AND bound to the maximum width or either the column header or any data within, if possible...
For now, here is the code, first of the column initialization in the StatsTabDisplay
class (which is the "JavaFX controller"):
@Override
public void init()
{
setColumnValue(ruleName, r -> r.getRuleInfo().getName());
setColumnValue(ruleClass, r -> r.getRuleInfo().getClassName());
setColumnValue(ruleType, r -> r.getRuleInfo().getType());
setColumnValue(nrCalls, r -> r.getEmptyMatches() + r.getFailedMatches()
+ r.getNonEmptyMatches());
setColumnValue(callDetail, r -> String.format("%d / %d / %d",
r.getNonEmptyMatches(), r.getEmptyMatches(), r.getFailedMatches()));
setColumnValue(callGraph, Function.identity());
callGraph.setCellFactory(CallGraphTableCell::new);
}
The setColumnValue()
method is defined in a utility class:
public static <S, T> void setColumnValue(final TableColumn<S, T> column,
final Function<? super S, ? extends T> f)
{
column.setCellValueFactory(
param -> new SimpleObjectProperty<T>()
{
@Override
public T get()
{
return f.apply(param.getValue());
}
}
);
}
The code to trigger the table refresh is:
public void handleRefreshInvocationStatistics()
{
final boolean complete = model.isLoadComplete();
taskRunner.computeOrFail(
view::disableTableRefresh,
model::getRuleInvocationStatistics,
stats -> view.displayRuleInvocationStatistics(complete, stats),
throwable -> mainView.showError("Load error",
"Unable to load matcher statistics", throwable)
);
}
and the matching code fragments in the view
is this (the display
member of the view is the instance of StatsTabDisplay
):
@Override
public void displayRuleInvocationStatistics(final boolean complete,
final List<RuleInvocationStatistics> stats)
{
if (complete) {
display.completionStatus.setVisible(false);
display.tableRefresh.setVisible(false);
}
display.invocationStatsTable.getSortOrder().setAll(display.nrCalls);
display.invocationStatsTable.getItems().setAll(stats);
display.invocationStatsTable.sort();
display.tableRefresh.setDisable(false);
}
@Override
public void disableTableRefresh()
{
display.tableRefresh.setDisable(true);
}
It is possible to achieve the required feature?
EDIT well, I know it is definitely possible, since when you double click on the "right of the column header" (I don't know the exact term for it) it achieves exactly what I want; except that I'd like it to be in code, not requiring a user interaction...
Upvotes: 0
Views: 129
Reputation: 11134
I would suggest making use of the columnResizePolicy
.
If you set tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY)
all columns will be equally resized until the TableView
s maximum width is reached. But you can write your own policy:
The policy is just a Callback
where ResizeFeatures
is given as input from where you have access to the TableColumn
.
Upvotes: 2