Я написал пользовательскую политику изменения ширины TableColumn. Вы можете увидеть его код в Java 8 / JavaFX 8 здесь, на github. Как видите, в методе distributeSpaceRatio()
и других местах от TableColumn.impl_setWidth()
зависит установка ширины столбцов на желаемое значение после выполнения наших вычислений.
Я переношу свой проект на Java 11/JavaFX 11, и метод impl_setWidth()
был удален из общего доступа.
Есть ли другой способ указать столбцу таблицы установить его ширину? Я открыт для любого решения, если оно надежно и устанавливает 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:
Я также попытался использовать решение, представленное в этом ответе, для выполнения частного метода и получил то же исключение: "Есть методы с именем doSetWidth и параметрами [класс java.lang.Double] не найдены".
Попытка 5:
Я думал, что это сработает, но не тут-то было. Он выдал «java.lang.NoSuchFieldException: ширина». Однако, когда я перехожу к исходному коду TableColumnBase, я ясно вижу в строке 412 приватное поле, называемое шириной. Не уверен, почему это не удается.
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: невозможно сделать поле закрытым
Попытка 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
TableColumnBase.class.getDeclaredField("width")
. Класс среды выполнения экземпляраcolumn
, вероятно,TableColumn
, что не соответствует. - person Jai   schedule 12.11.2018--add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED
в командной строке. - person Slaw   schedule 12.11.2018TableColumnBase.doSetWidth(double)
задумчиво. Предполагается, что это прямая заменаimpl_setWidth(double)
, за исключением того, что теперь он является частным пакетом. - person Jai   schedule 12.11.2018