Я написал собственную политику изменения ширины TableColumn. Вы можете увидеть его код под Java
8 / JavaFX 8 здесь, на 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:
Глядя на исходный код TableView.UNCONSTRAINED_RESIZE_POLICY
для JavaFX, кажется, что вызванный метод в конечном итоге 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 и params [класс 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: Невозможно сделать поле приватным модуль @ 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