JavaFX TableView具有两个固定列,最后一列占用可用空间
我正在尝试制作一个简单的3列TableView:JavaFX TableView具有两个固定列,最后一列占用可用空间,java,javafx,tableview,javafx-8,Java,Javafx,Tableview,Javafx 8,我正在尝试制作一个简单的3列TableView: 一个包含固定大小图标的图标列。此列不能调整大小,并且必须具有固定大小 一个具有预定义首选大小的文本列,可根据需要调整其大小 最后一列占用所有可用空间 不幸的是,这个简单的用例对于JavaFX8来说似乎非常复杂。根据我对文档的理解,我尝试了以下方法: TableColumn<DebuggerItem, ImageView> iconColumn = new TableColumn<>("ICON"); TableColu
- 一个包含固定大小图标的图标列。此列不能调整大小,并且必须具有固定大小
- 一个具有预定义首选大小的文本列,可根据需要调整其大小
- 最后一列占用所有可用空间
TableColumn<DebuggerItem, ImageView> iconColumn = new TableColumn<>("ICON");
TableColumn<DebuggerItem, String> typeColumn = new TableColumn<>("TEXT");
TableColumn<DebuggerItem, String> textColumn = new TableColumn<>("DATA");
setColumnResizePolicy(CONSTRAINED_RESIZE_POLICY);
// Fixed size column
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setResizable(false);
// Predefined preferred size of 100px
typeColumn.setPrefWidth(100);
getColumns().addAll(iconColumn, typeColumn, textColumn);
TableColumn图标column=新的TableColumn(“图标”);
TableColumn typeColumn=新的TableColumn(“文本”);
TableColumn textColumn=新的TableColumn(“数据”);
setColumnResizePolicy(受约束的调整大小策略);
//固定大小列
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setresizeable(false);
//预定义的首选大小为100px
typeColumn.setPrefWidth(100);
getColumns().addAll(iconColumn、typeColumn、textColumn);
这将产生以下TableView:
我们可以看到,如果第一列的大小正确,那么第二列和hird的大小相同,这不是我所期望的。第二列应为100px宽,最后一列占用剩余空间
我遗漏了什么?根据@kleopatra link,解决方案是使用属性来计算最后一列的宽度,而不是使用
受约束的调整大小策略
:
LastColumnWidth = TableViewWidth - SUM(Other Columns Widths)
根据我的示例,给出以下Java代码:
TableColumn<DebuggerItem, ImageView> iconColumn = new TableColumn<>("ICON");
TableColumn<DebuggerItem, String> typeColumn = new TableColumn<>("TEXT");
TableColumn<DebuggerItem, String> textColumn = new TableColumn<>("DATA");
// Fixed size column
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setResizable(false);
// Predefined preferred size of 100px
typeColumn.setPrefWidth(100);
// Automatic width for last column
textColumn.prefWidthProperty().bind(
widthProperty().subtract(
iconColumn.widthProperty()).subtract(
typeColumn.widthProperty()).subtract(2)
);
getColumns().addAll(iconColumn, typeColumn, textColumn);
TableColumn图标column=新的TableColumn(“图标”);
TableColumn typeColumn=新的TableColumn(“文本”);
TableColumn textColumn=新的TableColumn(“数据”);
//固定大小列
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setresizeable(false);
//预定义的首选大小为100px
typeColumn.setPrefWidth(100);
//最后一列的自动宽度
textColumn.prefWidthProperty().bind(
widthProperty()(
iconColumn.widthProperty()).subtract(
typeColumn.widthProperty()).subtract(2)
);
getColumns().addAll(iconColumn、typeColumn、textColumn);
请注意,我们需要减去2个像素以获得准确的宽度,原因尚不清楚。根据@kleopatra link,解决方案是使用属性来计算最后一列宽度,而不是使用
受约束的调整大小策略
:
LastColumnWidth = TableViewWidth - SUM(Other Columns Widths)
根据我的示例,给出以下Java代码:
TableColumn<DebuggerItem, ImageView> iconColumn = new TableColumn<>("ICON");
TableColumn<DebuggerItem, String> typeColumn = new TableColumn<>("TEXT");
TableColumn<DebuggerItem, String> textColumn = new TableColumn<>("DATA");
// Fixed size column
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setResizable(false);
// Predefined preferred size of 100px
typeColumn.setPrefWidth(100);
// Automatic width for last column
textColumn.prefWidthProperty().bind(
widthProperty().subtract(
iconColumn.widthProperty()).subtract(
typeColumn.widthProperty()).subtract(2)
);
getColumns().addAll(iconColumn, typeColumn, textColumn);
TableColumn图标column=新的TableColumn(“图标”);
TableColumn typeColumn=新的TableColumn(“文本”);
TableColumn textColumn=新的TableColumn(“数据”);
//固定大小列
iconColumn.setPrefWidth(40);
iconColumn.setMinWidth(40);
iconColumn.setMaxWidth(40);
iconColumn.setresizeable(false);
//预定义的首选大小为100px
typeColumn.setPrefWidth(100);
//最后一列的自动宽度
textColumn.prefWidthProperty().bind(
widthProperty()(
iconColumn.widthProperty()).subtract(
typeColumn.widthProperty()).subtract(2)
);
getColumns().addAll(iconColumn、typeColumn、textColumn);
请注意,我们需要减去2个像素以获得准确的宽度,原因尚不清楚。我创建了一个更通用的解决方案,该像素完美地计算了TableView最后一列的宽度,即:
- 有任意数量的列
- 可能在运行时隐藏或显示列
- 可能有定制的插图
- 可能有滚动条,可能在运行时显示和隐藏
public static <T> void bindLastColumnWidth (TableView<T> tableView) {
List<TableColumn<T,?>> columns = tableView.getColumns();
List<TableColumn<T,?>> columnsWithoutLast = columns.subList(0, columns.size() - 1);
TableColumn lastColumn = columns.get(columns.size() - 1);
NumberExpression expression = tableView.widthProperty();
Insets insets = tableView.getInsets();
expression = expression.subtract(insets.getLeft() + insets.getRight());
for (TableColumn column : columnsWithoutLast) {
NumberExpression columnWidth = Bindings.when(column.visibleProperty())
.then(column.widthProperty())
.otherwise(0);
expression = expression.subtract(columnWidth);
}
ScrollBar verticalScrollBar = getScrollBar(tableView, Orientation.VERTICAL);
if (verticalScrollBar != null) {
NumberExpression scrollBarWidth = Bindings.when(verticalScrollBar.visibleProperty())
.then(verticalScrollBar.widthProperty())
.otherwise(0);
expression = expression.subtract(scrollBarWidth);
}
expression = Bindings.max(lastColumn.getPrefWidth(), expression);
lastColumn.prefWidthProperty().bind(expression);
}
private static ScrollBar getScrollBar (Node control, Orientation orientation) {
for (Node node : control.lookupAll(".scroll-bar")) {
if (node instanceof ScrollBar) {
ScrollBar scrollBar = (ScrollBar)node;
if (scrollBar.getOrientation().equals(orientation)) {
return scrollBar;
}
}
}
return null;
}
publicstaticvoidbindlastcolumnwidth(TableView TableView){
List columns=tableView.getColumns();
List columnsWithoutLast=columns.subList(0,columns.size()-1);
TableColumn lastColumn=columns.get(columns.size()-1);
NumberPression表达式=tableView.widthProperty();
Insets Insets=tableView.getInsets();
expression=expression.subtract(insets.getLeft()+insets.getRight());
for(表列列:列SwithOutLast){
NumberExpression columnWidth=Bindings.when(column.visibleProperty())
.then(column.widthProperty())
。否则(0);
表达式=表达式。减法(列宽度);
}
ScrollBar verticalScrollBar=getScrollBar(表格视图,方向.VERTICAL);
如果(垂直滚动条!=null){
NumberPression scrollBarWidth=Bindings.when(verticalScrollBar.visibleProperty())
.then(verticalScrollBar.widthProperty())
。否则(0);
表达式=表达式。减法(滚动条宽度);
}
expression=Bindings.max(lastColumn.getPrefWidth(),expression);
lastColumn.prefWidthProperty().bind(表达式);
}
专用静态滚动条getScrollBar(节点控件、方向){
对于(节点:control.lookupAll(“.scroll bar”)){
if(滚动条的节点实例){
滚动条滚动条=(滚动条)节点;
if(scrollBar.getOrientation().equals(方向)){
返回滚动条;
}
}
}
返回null;
}
我创建了一个更通用的解决方案,该像素完美地计算了TableView最后一列的宽度:
- 有任意数量的列
- 可能在运行时隐藏或显示列
- 可能有定制的插图
- 可能有滚动条,可能在运行时显示和隐藏
public static <T> void bindLastColumnWidth (TableView<T> tableView) {
List<TableColumn<T,?>> columns = tableView.getColumns();
List<TableColumn<T,?>> columnsWithoutLast = columns.subList(0, columns.size() - 1);
TableColumn lastColumn = columns.get(columns.size() - 1);
NumberExpression expression = tableView.widthProperty();
Insets insets = tableView.getInsets();
expression = expression.subtract(insets.getLeft() + insets.getRight());
for (TableColumn column : columnsWithoutLast) {
NumberExpression columnWidth = Bindings.when(column.visibleProperty())
.then(column.widthProperty())
.otherwise(0);
expression = expression.subtract(columnWidth);
}
ScrollBar verticalScrollBar = getScrollBar(tableView, Orientation.VERTICAL);
if (verticalScrollBar != null) {
NumberExpression scrollBarWidth = Bindings.when(verticalScrollBar.visibleProperty())
.then(verticalScrollBar.widthProperty())
.otherwise(0);
expression = expression.subtract(scrollBarWidth);
}
expression = Bindings.max(lastColumn.getPrefWidth(), expression);
lastColumn.prefWidthProperty().bind(expression);
}
private static ScrollBar getScrollBar (Node control, Orientation orientation) {
for (Node node : control.lookupAll(".scroll-bar")) {
if (node instanceof ScrollBar) {
ScrollBar scrollBar = (ScrollBar)node;
if (scrollBar.getOrientation().equals(orientation)) {
return scrollBar;
}
}
}
return null;
}
publicstaticvoidbindlastcolumnwidth(TableView TableView){
List columns=tableView.getColumns();
List columnsWithoutLast=columns.subList(0,columns.size()-1);
TableColumn lastColumn=columns.get(columns.size()-1);
NumberPression表达式=tableView.widthProperty();
Insets Insets=tableView.getInsets();
表达式=表达式.减法(insets.ge