我正在寻找一种方法来调整TableView中TableColumn的大小,以便所有内容在每个单元格中都可见(即没有截断)。
我注意到双击列分隔符会自动使列适合其单元格的内容。有没有办法以编程方式触发它?
答案 0 :(得分:8)
通过javafx源代码挖掘,我发现单击TableView列分隔符时调用的实际方法是
/*
* FIXME: Naive implementation ahead
* Attempts to resize column based on the pref width of all items contained
* in this column. This can be potentially very expensive if the number of
* rows is large.
*/
@Override protected void resizeColumnToFitContent(TableColumn<T, ?> tc, int maxRows) {
if (!tc.isResizable()) return;
// final TableColumn<T, ?> col = tc;
List<?> items = itemsProperty().get();
if (items == null || items.isEmpty()) return;
Callback/*<TableColumn<T, ?>, TableCell<T,?>>*/ cellFactory = tc.getCellFactory();
if (cellFactory == null) return;
TableCell<T,?> cell = (TableCell<T, ?>) cellFactory.call(tc);
if (cell == null) return;
// set this property to tell the TableCell we want to know its actual
// preferred width, not the width of the associated TableColumnBase
cell.getProperties().put(TableCellSkin.DEFER_TO_PARENT_PREF_WIDTH, Boolean.TRUE);
// determine cell padding
double padding = 10;
Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
if (n instanceof Region) {
Region r = (Region) n;
padding = r.snappedLeftInset() + r.snappedRightInset();
}
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
double maxWidth = 0;
for (int row = 0; row < rows; row++) {
cell.updateTableColumn(tc);
cell.updateTableView(tableView);
cell.updateIndex(row);
if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
getChildren().add(cell);
cell.applyCss();
maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
getChildren().remove(cell);
}
}
// dispose of the cell to prevent it retaining listeners (see RT-31015)
cell.updateIndex(-1);
// RT-36855 - take into account the column header text / graphic widths.
// Magic 10 is to allow for sort arrow to appear without text truncation.
TableColumnHeader header = getTableHeaderRow().getColumnHeaderFor(tc);
double headerTextWidth = Utils.computeTextWidth(header.label.getFont(), tc.getText(), -1);
Node graphic = header.label.getGraphic();
double headerGraphicWidth = graphic == null ? 0 : graphic.prefWidth(-1) + header.label.getGraphicTextGap();
double headerWidth = headerTextWidth + headerGraphicWidth + 10 + header.snappedLeftInset() + header.snappedRightInset();
maxWidth = Math.max(maxWidth, headerWidth);
// RT-23486
maxWidth += padding;
if(tableView.getColumnResizePolicy() == TableView.CONSTRAINED_RESIZE_POLICY) {
maxWidth = Math.max(maxWidth, tc.getWidth());
}
tc.impl_setWidth(maxWidth);
}
在
中声明com.sun.javafx.scene.control.skin.TableViewSkinBase
方法签名
protected abstract void resizeColumnToFitContent(TC tc, int maxRows)
由于受到保护,您无法通过例如tableView.getSkin(),但您始终可以扩展TableViewSkin,只覆盖resizeColumnToFitContent方法并将其公开。
答案 1 :(得分:6)
作为@Tomasz的建议,我通过反思来解决:
import com.sun.javafx.scene.control.skin.TableViewSkin;
import javafx.scene.control.Skin;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GUIUtils {
private static Method columnToFitMethod;
static {
try {
columnToFitMethod = TableViewSkin.class.getDeclaredMethod("resizeColumnToFitContent", TableColumn.class, int.class);
columnToFitMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void autoFitTable(TableView tableView) {
tableView.getItems().addListener(new ListChangeListener<Object>() {
@Override
public void onChanged(Change<?> c) {
for (Object column : tableView.getColumns()) {
try {
columnToFitMethod.invoke(tableView.getSkin(), column, -1);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
});
}
}
答案 2 :(得分:2)
如果从不设置prefWidth(或将其设置为80.0F,请参见TableColumnHeader enter link description here),则当前版本的JavaFX(例如15-ea + 1)将调整表列的大小。
答案 3 :(得分:0)
您可以使用tableView.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
您还可以尝试在两个策略TableView.CONSTRAINED_RESIZE_POLICY之间切换 如果TableView.UNCONSTRAINED_RESIZE_POLICY不适合您的需要,请使用TableView.UNCONSTRAINED_RESIZE_POLICY。
Here's一个有用的链接。