Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX TableView具有两个固定列,最后一列占用可用空间_Java_Javafx_Tableview_Javafx 8 - Fatal编程技术网

JavaFX TableView具有两个固定列,最后一列占用可用空间

JavaFX TableView具有两个固定列,最后一列占用可用空间,java,javafx,tableview,javafx-8,Java,Javafx,Tableview,Javafx 8,我正在尝试制作一个简单的3列TableView: 一个包含固定大小图标的图标列。此列不能调整大小,并且必须具有固定大小 一个具有预定义首选大小的文本列,可根据需要调整其大小 最后一列占用所有可用空间 不幸的是,这个简单的用例对于JavaFX8来说似乎非常复杂。根据我对文档的理解,我尝试了以下方法: TableColumn<DebuggerItem, ImageView> iconColumn = new TableColumn<>("ICON"); TableColu

我正在尝试制作一个简单的3列TableView:

  • 一个包含固定大小图标的图标列。此列不能调整大小,并且必须具有固定大小
  • 一个具有预定义首选大小的文本列,可根据需要调整其大小
  • 最后一列占用所有可用空间
不幸的是,这个简单的用例对于JavaFX8来说似乎非常复杂。根据我对文档的理解,我尝试了以下方法:

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最后一列的宽度,即:

  • 有任意数量的列
  • 可能在运行时隐藏或显示列
  • 可能有定制的插图
  • 可能有滚动条,可能在运行时显示和隐藏
用法: bindLastColumnWidth(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最后一列的宽度:

  • 有任意数量的列
  • 可能在运行时隐藏或显示列
  • 可能有定制的插图
  • 可能有滚动条,可能在运行时显示和隐藏
用法: bindLastColumnWidth(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