我写了一个自定义的TableColumn宽度调整大小策略。您可以在Java下查看其代码
8 / JavaFX 8 here on github。如您所见,在方法distributeSpaceRatio()
和其他地方,计算完成后取决于TableColumn.impl_setWidth()
将列的宽度设置为所需的值。
我正在将项目迁移到Java 11 / JavaFX 11,并且方法impl_setWidth()
已从公共视图中删除。
还有另一种方法可以告诉表格列设置其宽度吗?我愿意接受任何可靠的解决方案,只要将其设置为(或接近)请求的值即可。
到目前为止,我尝试过的两个想法没有用:
尝试1:
这给出了NoMethodFoundException:
private void setColumnWidth ( TableColumn column, double targetWidth ) {
try {
Method method = column.getClass().getDeclaredMethod( "setWidth" );
method.setAccessible( true );
Object r = method.invoke( targetWidth );
} catch ( Exception e ) {
e.printStackTrace();
}
}
尝试2:
此无效:
private void setColumnWidth ( TableColumn column, double targetWidth ) {
double oldMax = column.getMaxWidth();
double oldMin = column.getMinWidth();
double oldPref = column.getPrefWidth();
column.setMaxWidth( targetWidth );
column.setMinWidth( targetWidth );
column.setPrefWidth( targetWidth );
column.getTableView().refresh();
column.setPrefWidth( oldPref );
column.setMinWidth( oldMin );
column.setMaxWidth( oldMax );
}
尝试3:
看一下JavaFX的TableView.UNCONSTRAINED_RESIZE_POLICY
的来源,看来所调用的方法最终是TableColumnBase.doSetWidth()
,但是在这里我也不起作用:
private void setColumnWidth ( TableColumn column, double targetWidth ) {
try {
Method method = column.getClass().getDeclaredMethod( "doSetWidth" );
method.setAccessible( true );
Object r = method.invoke( targetWidth );
} catch ( Exception e ) {
e.printStackTrace();
}
}
尝试4:
我还尝试使用this answer中提供的解决方案来执行私有方法,并且遇到了相同的例外-“找不到名称为doSetWidth和params [class java.lang.Double]的方法”。
尝试5:
我以为这将是可行的,但是没有这种运气。它抛出了“ java.lang.NoSuchFieldException:宽度”。但是,当我转到TableColumnBase源代码时,我清楚地在第412行看到一个称为width的私有字段。不知道为什么这会失败。
private void setColumnWidth ( TableColumnBase column, double targetWidth ) {
try {
Field widthField = column.getClass().getDeclaredField( "width" );
widthField.setAccessible( true );
ReadOnlyDoubleWrapper width = (ReadOnlyDoubleWrapper)widthField.get( column );
width.set( targetWidth );
} catch ( Exception e ) {
e.printStackTrace();
}
}
尝试6:
这使我们更加接近,但仍然失败:
private void setColumnWidth ( TableColumnBase column, double targetWidth ) {
try {
Field widthField = column.getClass().getSuperclass().getDeclaredField( "width" );
widthField.setAccessible( true );
ReadOnlyDoubleWrapper width = (ReadOnlyDoubleWrapper)widthField.get( column );
width.set( targetWidth );
} catch ( Exception e ) {
e.printStackTrace();
}
}
java.lang.reflect.InaccessibleObjectException:无法将字段设置为私有javafx.beans.property.ReadOnlyDoubleWrapper javafx.scene.control.TableColumnBase.width可以访问:模块javafx.controls不会“打开javafx.scene.control”为未命名模块@ 649dcffc
尝试7:
private void setColumnWidth ( TableColumn column, double targetWidth ) {
try {
Method method = column.getClass().getSuperclass().getDeclaredMethod( "setWidth", double.class );
method.setAccessible( true );
method.invoke ( targetWidth );
//ReadOnlyDoubleWrapper width = (ReadOnlyDoubleWrapper)widthField.get( column );
//width.set( targetWidth );
} catch ( Exception e ) {
e.printStackTrace();
}
}
java.lang.reflect.InaccessibleObjectException:无法使void javafx.scene.control.TableColumnBase.setWidth(double)可访问:模块javafx.controls不会“打开javafx.scene.control”到未命名的模块@ 5063f647 >
答案 0 :(得分:2)
基于测试和其他人的帮助,我找到了以下解决方案:
class array<int> a(5);
a[0] = 8;
a[1] = 6;
a[2] = 7;
a[3] = 1;
a[4] = 3;
std::cout << "attempting sort" << std::endl;
a.sort(wrap_insertion_sort_recursive<int>, custom_comparator<int>);
此外,需要使用以下参数来调用JVM:
private void setColumnWidth ( TableColumn column, double targetWidth ) {
try {
Method method = TableColumnBase.class.getDeclaredMethod( "doSetWidth", double.class );
method.setAccessible( true );
method.invoke( column, targetWidth );
} catch ( NoSuchMethodException | InvocationTargetException | IllegalAccessException e ) {
e.printStackTrace();
}
}