tableview中的javafx列自动调整大小

yel*_*ver 33 javafx javafx-2

据我所知的的TableView JavaFX中有2列调整政策:CONSTRAINED_RESIZE_POLICY和UNCONSTRAINED_RESIZE_POLICY,但我想列调整大小以适应他们的单元格的内容,我认为它在其他平台(如C#中的DataGridView)一个简单的问题,但解决不了

yel*_*ver 26

3年后我再次回到这个问题,一些建议正在计算每个单元格中数据文本的大小(根据字体大小,字体系列,填充......这很复杂)

但我意识到,当我点击表头上的分隔符时,它的大小适合我想要的内容.所以我深入研究JavaFX源代码我终于在TableViewSkin中找到了resizeColumnToFitContent方法,但它是受保护的方法,我们可以通过反射来解决:

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();
                    }
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

注意我们调用" tableView.getItems() "所以我们必须在setItems()之后调用这个函数

  • 在 JavaFx 16 中,方法 `resizeColumnToFitContent` 现在位于 javafx.scene.control.skin.TableColumnHeader 中 (3认同)
  • 方法“ resizeColumnToFitContent”已移至javafx.scene.control.skin.TableSkinUtils。 (2认同)

Har*_*son 8

在测试了以前的解决方案后,我终于找到了一个适合我的解决方 所以这是我的(在将数据插入表后调用方法):

public static void autoResizeColumns( TableView<?> table )
{
    //Set the right policy
    table.setColumnResizePolicy( TableView.UNCONSTRAINED_RESIZE_POLICY);
    table.getColumns().stream().forEach( (column) ->
    {
        //Minimal width = columnheader
        Text t = new Text( column.getText() );
        double max = t.getLayoutBounds().getWidth();
        for ( int i = 0; i < table.getItems().size(); i++ )
        {
            //cell must not be empty
            if ( column.getCellData( i ) != null )
            {
                t = new Text( column.getCellData( i ).toString() );
                double calcwidth = t.getLayoutBounds().getWidth();
                //remember new max-width
                if ( calcwidth > max )
                {
                    max = calcwidth;
                }
            }
        }
        //set the new max-widht with some extra space
        column.setPrefWidth( max + 10.0d );
    } );
}
Run Code Online (Sandbox Code Playgroud)


vip*_*tal 5

我认为只要通过覆盖一个返回true的回调函数来解决你的问题,它将禁用列的重新调整大小,并且所有列都将重新调整大小以适合其单元格的内容.

例:

TableView<String[]> table = new TableView<>();
table.setColumnResizePolicy(new Callback<TableView.ResizeFeatures, Boolean>() {
  @Override
  public Boolean call(ResizeFeatures p) {
     return true;
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,它会阻止用户调整列的大小. (10认同)

Jef*_* S. 5

如果您希望只有一列填充表格的剩余宽度,我找到了一个非常直接的解决方案,该解决方案很短并且不需要上述的hacky反射解决方案:

DoubleBinding usedWidth = columnA.widthProperty().add(columnB.widthProperty()).add(columnC.widthProperty());

fillingColumn.prefWidthProperty().bind(tableView.widthProperty().subtract(usedWidth));
Run Code Online (Sandbox Code Playgroud)