如何在 table 构造的所有列中分配总宽度?”
How to spread the total width amongst all columns on table construction?"
我正在尝试编写一个自定义调整大小策略,它的行为类似于 TableView.CONSTRAINED_RESIZE_POLICY
,因为它将所有可见列的总宽度设置为 table 中的总可用宽度,以便水平滚动条永远不会出现。
我正在使用行 double widthAvailable = table.getWidth() - getScrollbarWidth(table);
来尝试执行此操作(请参阅下面的完整代码)。
可惜,这个计算好像return4
太多了。我的猜测是我还应该从缺少的 table 宽度中减去其他一些东西,这在默认的 JavaFX 主题中恰好是 4 像素宽。
这里是演示问题的完整程序:
package net.joshuad.hypnos.test;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class CustomResizeExample extends Application {
@SuppressWarnings("unchecked")
private Parent getContent () {
TableView <Locale> table = new TableView <>( FXCollections.observableArrayList( Locale.getAvailableLocales() ) );
TableColumn <Locale, String> countryCode = new TableColumn <>( "CountryCode" );
countryCode.setCellValueFactory( new PropertyValueFactory <>( "country" ) );
TableColumn <Locale, String> language = new TableColumn <>( "Language" );
language.setCellValueFactory( new PropertyValueFactory <>( "language" ) );
table.getColumns().addAll( countryCode, language );
TableColumn <Locale, Locale> local = new TableColumn <>( "Locale" );
local.setCellValueFactory( c -> new SimpleObjectProperty <>( c.getValue() ) );
table.getColumns().addAll( local );
table.setColumnResizePolicy( new CustomResizePolicy() );
BorderPane pane = new BorderPane( table );
return pane;
}
@Override
public void start ( Stage stage ) throws Exception {
stage.setScene( new Scene( getContent(), 800, 400 ) );
stage.show();
}
public static void main ( String[] args ) {
launch ( args );
}
}
@SuppressWarnings ( "rawtypes" )
class CustomResizePolicy implements Callback <TableView.ResizeFeatures, Boolean> {
@SuppressWarnings("unchecked")
@Override
public Boolean call ( TableView.ResizeFeatures feature ) {
TableView table = feature.getTable();
List <TableColumn> columns = table.getVisibleLeafColumns();
double widthAvailable = table.getWidth() - getScrollbarWidth ( table );
double forEachColumn = widthAvailable / columns.size();
for ( TableColumn column : columns ) {
column.setMinWidth( forEachColumn );
column.setMaxWidth( forEachColumn );
}
return true;
}
private double getScrollbarWidth ( TableView table ) {
double scrollBarWidth = 0;
Set <Node> nodes = table.lookupAll( ".scroll-bar" );
for ( final Node node : nodes ) {
if ( node instanceof ScrollBar ) {
ScrollBar sb = (ScrollBar) node;
if ( sb.getOrientation() == Orientation.VERTICAL ) {
if ( sb.isVisible() ) {
scrollBarWidth = sb.getWidth();
}
}
}
}
return scrollBarWidth;
}
}
看到 table 比应有的宽一点了吗?我希望能够设置列的宽度,以便不出现水平滚动条。
Scenic View 是一个有用的工具来熟悉。它为您提供了有关场景图的许多详细信息。您要查找的 space 是 clipped-container
:
请注意,按照您有效的方式设置 CustomResizePolicy
不允许调整列的大小,因为它们总是分配相等份额的可用 space。
以下是您可能要查找的计算:
Region region = null;
Set<Node> nodes = table.lookupAll(".clipped-container");
for (Node node : nodes) {
if (node instanceof Region) {
region = (Region) node;
}
}
for (TableColumn<Locale, ?> column : table.getColumns()) {
column.setPrefWidth(region.getWidth() / table.getColumns().size());
}
我不完全理解为什么 CONSTRAINED_RESIZE_POLICY
不是你想要的,因为它平均划分 space 并且不允许调整大小超过分配的 space (因此水平滚动条不会出现),但如果您正在制定一些特殊的调整大小策略,上述内容应该会有所帮助。
我正在尝试编写一个自定义调整大小策略,它的行为类似于 TableView.CONSTRAINED_RESIZE_POLICY
,因为它将所有可见列的总宽度设置为 table 中的总可用宽度,以便水平滚动条永远不会出现。
我正在使用行 double widthAvailable = table.getWidth() - getScrollbarWidth(table);
来尝试执行此操作(请参阅下面的完整代码)。
可惜,这个计算好像return4
太多了。我的猜测是我还应该从缺少的 table 宽度中减去其他一些东西,这在默认的 JavaFX 主题中恰好是 4 像素宽。
这里是演示问题的完整程序:
package net.joshuad.hypnos.test;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class CustomResizeExample extends Application {
@SuppressWarnings("unchecked")
private Parent getContent () {
TableView <Locale> table = new TableView <>( FXCollections.observableArrayList( Locale.getAvailableLocales() ) );
TableColumn <Locale, String> countryCode = new TableColumn <>( "CountryCode" );
countryCode.setCellValueFactory( new PropertyValueFactory <>( "country" ) );
TableColumn <Locale, String> language = new TableColumn <>( "Language" );
language.setCellValueFactory( new PropertyValueFactory <>( "language" ) );
table.getColumns().addAll( countryCode, language );
TableColumn <Locale, Locale> local = new TableColumn <>( "Locale" );
local.setCellValueFactory( c -> new SimpleObjectProperty <>( c.getValue() ) );
table.getColumns().addAll( local );
table.setColumnResizePolicy( new CustomResizePolicy() );
BorderPane pane = new BorderPane( table );
return pane;
}
@Override
public void start ( Stage stage ) throws Exception {
stage.setScene( new Scene( getContent(), 800, 400 ) );
stage.show();
}
public static void main ( String[] args ) {
launch ( args );
}
}
@SuppressWarnings ( "rawtypes" )
class CustomResizePolicy implements Callback <TableView.ResizeFeatures, Boolean> {
@SuppressWarnings("unchecked")
@Override
public Boolean call ( TableView.ResizeFeatures feature ) {
TableView table = feature.getTable();
List <TableColumn> columns = table.getVisibleLeafColumns();
double widthAvailable = table.getWidth() - getScrollbarWidth ( table );
double forEachColumn = widthAvailable / columns.size();
for ( TableColumn column : columns ) {
column.setMinWidth( forEachColumn );
column.setMaxWidth( forEachColumn );
}
return true;
}
private double getScrollbarWidth ( TableView table ) {
double scrollBarWidth = 0;
Set <Node> nodes = table.lookupAll( ".scroll-bar" );
for ( final Node node : nodes ) {
if ( node instanceof ScrollBar ) {
ScrollBar sb = (ScrollBar) node;
if ( sb.getOrientation() == Orientation.VERTICAL ) {
if ( sb.isVisible() ) {
scrollBarWidth = sb.getWidth();
}
}
}
}
return scrollBarWidth;
}
}
看到 table 比应有的宽一点了吗?我希望能够设置列的宽度,以便不出现水平滚动条。
Scenic View 是一个有用的工具来熟悉。它为您提供了有关场景图的许多详细信息。您要查找的 space 是 clipped-container
:
请注意,按照您有效的方式设置 CustomResizePolicy
不允许调整列的大小,因为它们总是分配相等份额的可用 space。
以下是您可能要查找的计算:
Region region = null;
Set<Node> nodes = table.lookupAll(".clipped-container");
for (Node node : nodes) {
if (node instanceof Region) {
region = (Region) node;
}
}
for (TableColumn<Locale, ?> column : table.getColumns()) {
column.setPrefWidth(region.getWidth() / table.getColumns().size());
}
我不完全理解为什么 CONSTRAINED_RESIZE_POLICY
不是你想要的,因为它平均划分 space 并且不允许调整大小超过分配的 space (因此水平滚动条不会出现),但如果您正在制定一些特殊的调整大小策略,上述内容应该会有所帮助。