JavaFX TableColumn resize to fit cell content

前端 未结 4 915
无人共我
无人共我 2020-12-19 01:26

I\'m looking for a way to resize a TableColumn in a TableView so that all of the content is visible in each cell (i.e. no truncation).

I noticed that double clicking

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-19 02:23

    Digging through the javafx source, I found that the actual method called when you click TableView columns divider is

    /*
     * 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 tc, int maxRows) {
        if (!tc.isResizable()) return;
    
    // final TableColumn col = tc;
        List items = itemsProperty().get();
        if (items == null || items.isEmpty()) return;
    
        Callback/*, TableCell>*/ cellFactory = tc.getCellFactory();
        if (cellFactory == null) return;
    
        TableCell cell = (TableCell) 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);
    }
    

    It's declared in

    com.sun.javafx.scene.control.skin.TableViewSkinBase
    

    method signature

    protected abstract void resizeColumnToFitContent(TC tc, int maxRows)
    

    Since it's protected, You cannot call it from e.g. tableView.getSkin(), but You can always extend the TableViewSkin overriding only resizeColumnToFitContent method and make it public.

提交回复
热议问题