javafx-2 tableview实现自定义列调整大小策略

时间:2022-12-20 17:05:33

In my experience CONSTRAINED_RESIZE_POLICY is broken if the TableView contains some fixed width columns unless I am doing something wrong here:

根据我的经验,如果TableView包含一些固定宽度的列,则CONSTRAINED_RESIZE_POLICY会被破坏,除非我在这里做错了:

public class JavaFX2Sandbox extends Application
{
    public static void main(String[] args)
    {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception
    {
        StackPane root = new StackPane();
        root.autosize();
        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();

        configureTable(root);
    }

    public static class Person
    {
        public Person(String firstName, String lastName)
        {
            this.fixedValue = "Dr.";
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public String fixedValue;
        public String firstName;
        public String  lastName;
    }

    private static class CellValueFactory<T> implements Callback<TableColumn.CellDataFeatures<T, Object>, ObservableValue<Object>>
    {
        private String mFieldName;

        public CellValueFactory(String fieldName)
        {
            mFieldName = fieldName;
        }

        @Override
        public ObservableValue call(TableColumn.CellDataFeatures<T, Object> p)
        {
            try
            {
                if (p == null)
                {
                    return new SimpleObjectProperty(null);
                }
                Object o = p.getValue();
                if (o == null)
                {
                    return new SimpleObjectProperty(null);
                }
                Object fieldVal = o.getClass().getField(mFieldName).get(o);
                if (fieldVal == null)
                {
                    return new SimpleObjectProperty(null);
                }

                return new SimpleObjectProperty(fieldVal);
            }
            catch (Exception ex)
            {
                return new SimpleObjectProperty(ex);
            }
        }
    }
    private void configureTable(StackPane root)
    {

        TableView<Person> table = new TableView<>();
        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        ArrayList<Person> teamMembers = new ArrayList<>();
        teamMembers.add(new Person("John", "Big"));
        teamMembers.add(new Person("Frank", "Small"));

        TableColumn col0 = new TableColumn("fixed-width");
        col0.setResizable(false);
        col0.setCellValueFactory(new CellValueFactory("fixedValue"));
        TableColumn col1 = new TableColumn("First Name");
        col1.setCellValueFactory(new CellValueFactory("firstName"));
        TableColumn col2 = new TableColumn("Last Name");
        col2.setCellValueFactory(new CellValueFactory("lastName"));
        table.getColumns().setAll(col0, col1, col2);
        table.setItems(FXCollections.observableList(teamMembers));

        root.getChildren().add(table);
    }
}

So I started to implement my own resize policy which behaves slightly differently from CONSTRAINED_RESIZE_POLICY but I like mine better :-). It is all okay except for the sum of the widths of the columns do not add up to the width of the TableView.

所以我开始实现自己的调整策略,其行为与CONSTRAINED_RESIZE_POLICY略有不同,但我更喜欢我的:-)。这一切都没关系,除了列的宽度总和不加起来与TableView的宽度相加。

Here is the implementation of my resize policy class:

以下是我的resize策略类的实现:

static class ColumnResizePolicy implements Callback<TableView.ResizeFeatures, Boolean>
{
    double mTVWidth;

    @Override
    public Boolean call(ResizeFeatures arg0)
    {
        TableView tv = arg0.getTable();
        Double tvWidth = tv.widthProperty().getValue();
        if (tvWidth == null || tvWidth <= 0.0)
        {
            return false;
        }

        if (mTVWidth != tvWidth && arg0.getColumn() == null)
        {
            mTVWidth = tvWidth;

            int numColsToSize = 0;
            double fixedColumnsWidths = 0;
            for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns()))
            {
                if (col.isResizable() && col.isVisible())
                {
                    ++numColsToSize;
                }
                else if (col.isVisible())
                {
                    fixedColumnsWidths += col.getWidth();
                }
            }

            if (numColsToSize == 0)
                return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0);

            TableColumn lastCol = null;
            for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns()))
            {
                if (col.isResizable() && col.isVisible())
                {
                    double newWidth = (tvWidth - fixedColumnsWidths) / numColsToSize;
                    col.setPrefWidth(newWidth);
                    lastCol = col;
                }
            }
            if (lastCol != null)
            {
                lastCol.setPrefWidth(lastCol.getPrefWidth()-2);
            }

            return true;
        }
        else
        {
            return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0);
        }
    }
}

And my question (ironically after this long post) is about number 2 in this line:

我的问题(具有讽刺意味的是,在这篇长篇文章之后)是关于这一行的第2个问题:

lastCol.setPrefWidth(lastCol.getPrefWidth()-2);

I assume that the table width gives back the outer width including the border, hence the difference, but how do I get the inner width?

我假设表格宽度给出了包括边框在内的外部宽度,因此差异,但我如何获得内部宽度?

3 个解决方案

#1


0  

Try next:

 double borderWidth = table.getBoundsInLocal().getWidth() - table.getWidth()

#2


0  

Have you tried getting the width of the place holder node?

您是否尝试过获取占位符节点的宽度?

#3


0  

I have a problem same https://community.oracle.com/message/12334734#12334734 And this implementing custom column resize policy of you was help me. Thanks you!

我有一个问题相同https://community.oracle.com/message/12334734#12334734这个实现自定义列调整大小的政策是帮助我。谢谢!

Your code.

if (col.isResizable() && col.isVisible()) {
    double newWidth = (tvWidth - fixedColumnsWidths) / numColsToSize;
    col.setPrefWidth(newWidth);
    lastCol = col;
}

I change to

我改为

if (col.isResizable() && col.isVisible()) {
    double newWidth = (tvWidth - fixedColumnsWidths)*col.getPercentWidth();
    col.setPrefWidth(newWidth);
    lastCol = col;
}

With col is

与col是

public class PTableColumn<S, T> extends javafx.scene.control.TableColumn<S, T>

And getPercentWidth is

并且getPercentWidth是

private DoubleProperty percentWidth = new SimpleDoubleProperty(1);

#1


0  

Try next:

 double borderWidth = table.getBoundsInLocal().getWidth() - table.getWidth()

#2


0  

Have you tried getting the width of the place holder node?

您是否尝试过获取占位符节点的宽度?

#3


0  

I have a problem same https://community.oracle.com/message/12334734#12334734 And this implementing custom column resize policy of you was help me. Thanks you!

我有一个问题相同https://community.oracle.com/message/12334734#12334734这个实现自定义列调整大小的政策是帮助我。谢谢!

Your code.

if (col.isResizable() && col.isVisible()) {
    double newWidth = (tvWidth - fixedColumnsWidths) / numColsToSize;
    col.setPrefWidth(newWidth);
    lastCol = col;
}

I change to

我改为

if (col.isResizable() && col.isVisible()) {
    double newWidth = (tvWidth - fixedColumnsWidths)*col.getPercentWidth();
    col.setPrefWidth(newWidth);
    lastCol = col;
}

With col is

与col是

public class PTableColumn<S, T> extends javafx.scene.control.TableColumn<S, T>

And getPercentWidth is

并且getPercentWidth是

private DoubleProperty percentWidth = new SimpleDoubleProperty(1);