column.impl_setWidth() 的 JavaFX 11 替代品?
JavaFX 11 Replacement for column.impl_setWidth()?
我编写了自定义 TableColumn 宽度调整策略。你可以在 Java 下看到它的代码
8 / JavaFX 8 here on github。可以看到,在方法distributeSpaceRatio()
等地方,是靠TableColumn.impl_setWidth()
在我们计算之后将列的宽度设置为想要的值。
我正在将我的项目迁移到 Java 11 / JavaFX 11,方法 impl_setWidth()
已从 public 视图中删除。
是否有另一种方法可以告诉 table 列设置其宽度?我对任何解决方案都持开放态度,只要它是可靠的并将 with 设置为(或接近)请求的值。
以下是我迄今为止尝试过但没有奏效的两个想法:
尝试 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中提供的解决方案执行私有方法,得到同样的异常--"There are no methods found with name doSetWidth and params [class java.lang.Double]".
尝试 5:
我以为这个会起作用,但没有这样的运气。它扔了一个"java.lang.NoSuchFieldException: width"。但是,当我转到 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: Unable to make field private javafx.beans.property.ReadOnlyDoubleWrapper javafx.scene.control.TableColumnBase.width accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @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: Unable to make void javafx.scene.control.TableColumnBase.setWidth(double) accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @5063f647
根据测试和其他人的帮助,我找到了这个解决方案:
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();
}
}
此外,需要使用以下参数调用JVM:
--add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED
我编写了自定义 TableColumn 宽度调整策略。你可以在 Java 下看到它的代码
8 / JavaFX 8 here on github。可以看到,在方法distributeSpaceRatio()
等地方,是靠TableColumn.impl_setWidth()
在我们计算之后将列的宽度设置为想要的值。
我正在将我的项目迁移到 Java 11 / JavaFX 11,方法 impl_setWidth()
已从 public 视图中删除。
是否有另一种方法可以告诉 table 列设置其宽度?我对任何解决方案都持开放态度,只要它是可靠的并将 with 设置为(或接近)请求的值。
以下是我迄今为止尝试过但没有奏效的两个想法:
尝试 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中提供的解决方案执行私有方法,得到同样的异常--"There are no methods found with name doSetWidth and params [class java.lang.Double]".
尝试 5:
我以为这个会起作用,但没有这样的运气。它扔了一个"java.lang.NoSuchFieldException: width"。但是,当我转到 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: Unable to make field private javafx.beans.property.ReadOnlyDoubleWrapper javafx.scene.control.TableColumnBase.width accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @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: Unable to make void javafx.scene.control.TableColumnBase.setWidth(double) accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @5063f647
根据测试和其他人的帮助,我找到了这个解决方案:
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();
}
}
此外,需要使用以下参数调用JVM:
--add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED