首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >场景中TableColumn的位置

场景中TableColumn的位置
EN

Stack Overflow用户
提问于 2015-06-12 12:12:03
回答 2查看 1.5K关注 0票数 2

我有一个TableView和几个TableColumns,我想把一个节点放在一个特定的TableColumn下面。如何获得TableColumn的确切位置(x,y-坐标),以便绑定节点的转换属性?

下面是我如何在TableView的右上角放置一个按钮的片段:

代码语言:javascript
复制
button.translateXProperty().unbind();
button.translateXProperty().bind(tableView.widthProperty().divide(2.0).subtract(button.getWidth() / 2.0 + 2.0) + tableView.localToScene(0.0, 0.0).getX());

这很好,但显然只适用于TableView。TableColumns没有那些转换属性或localToScene方法,因此我无法直接获得要绑定节点的位置。

我目前的解决方案(不是很好)是这样做的:我读出了场景中的TableView的位置( PointA ),然后遍历所有列的列表(tableView.getColumns()),检查每个列是否可见,如果是,将它们的宽度添加到PointA的X值中。我会这样做,直到找到我想要将Node放在下面的实际列。现在的问题是,我不能将节点的位置绑定到这一点,因为当我更改列的顺序或使其中一个列不可见时,我的列就会改变屏幕上的位置。我必须在列顺序和可见性中添加一个侦听器.

有没有更有效的方法来做我想做的事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-15 11:44:49

如果允许您使用非公共api,您可以考虑通过它的皮肤访问TableColumnHeader,条件是它的类型是TableViewSkinBase:它有访问TableRowHeader的api,这是所有TableColumnHeaders的容器,并且有api查找它包含的任何列的头。

代码片段(宽度/位置绑定从James的示例复制到标头而不是标签)

代码语言:javascript
复制
private void buttonsPerHeader(TableView<Person> table, Pane root) {
    if (!(table.getSkin() instanceof TableViewSkinBase)) return;
    TableViewSkinBase skin = (TableViewSkinBase) table.getSkin();
    TableHeaderRow headerRow = skin.getTableHeaderRow();
    for (TableColumn col : table.getColumns()) {
        TableColumnHeader header = headerRow.getColumnHeaderFor(col);
        Button button = new Button(col.getText());

        button.prefWidthProperty().bind(Bindings.createDoubleBinding(() -> 
            header.getBoundsInLocal().getWidth(), header.boundsInLocalProperty()));
        button.minWidthProperty().bind(button.prefWidthProperty());
        button.maxWidthProperty().bind(button.prefWidthProperty());

        button.layoutXProperty().bind(Bindings.createDoubleBinding(() -> 
            header.getLocalToSceneTransform().transform(header.getBoundsInLocal()).getMinX(),
            header.boundsInLocalProperty(), header.localToSceneTransformProperty()));

        button.layoutYProperty().bind(Bindings.createDoubleBinding(() ->
            table.getBoundsInParent().getMaxY() ,table.boundsInParentProperty()));

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

}
票数 1
EN

Stack Overflow用户

发布于 2015-06-12 13:02:14

我通常不喜欢使用查找,但您可以检索使用查找.table-view .column-header .label显示列标题的标签,然后使用该标签的边界绑定按钮的布局属性。

示例:

代码语言:javascript
复制
import java.util.Optional;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class TableColumnLocationExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Person> table = new TableView<>();
        table.getColumns().add(column("First Name", Person::firstNameProperty, 120));
        table.getColumns().add(column("Last Name", Person::lastNameProperty, 120));
        table.getColumns().add(column("Email", Person::emailProperty, 250));

        table.getItems().addAll(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com")        
        );

        Pane root = new Pane(table);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();


        for (TableColumn<Person, ?> col : table.getColumns()) {
            Optional<Label> header = findLabelForTableColumnHeader(col.getText(), root);
            header.ifPresent(label ->  {
                Button button = new Button(col.getText());

                button.prefWidthProperty().bind(Bindings.createDoubleBinding(() -> 
                    label.getBoundsInLocal().getWidth(), label.boundsInLocalProperty()));
                button.minWidthProperty().bind(button.prefWidthProperty());
                button.maxWidthProperty().bind(button.prefWidthProperty());

                button.layoutXProperty().bind(Bindings.createDoubleBinding(() -> 
                    label.getLocalToSceneTransform().transform(label.getBoundsInLocal()).getMinX(),
                    label.boundsInLocalProperty(), label.localToSceneTransformProperty()));

                button.layoutYProperty().bind(Bindings.createDoubleBinding(() ->
                    table.getBoundsInParent().getMaxY() ,table.boundsInParentProperty()));

                root.getChildren().add(button);

            });
        }


    }

    private Optional<Label> findLabelForTableColumnHeader(String text, Parent root) {
        return root.lookupAll(".table-view .column-header .label")
                .stream()
                .map(Label.class::cast)
                .filter(label -> label.getText().equals(text))
                .findAny(); // assumes all columns have unique text...
    }



    private <S,T> TableColumn<S,T> column(String title, Function<S,ObservableValue<T>> property, double width) {
        TableColumn<S,T> col = new TableColumn<>(title);
        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        col.setPrefWidth(width);
        return col ;
    }

    public static class Person {
        private StringProperty firstName = new SimpleStringProperty();
        private StringProperty lastName = new SimpleStringProperty();
        private StringProperty email = new SimpleStringProperty();

        public Person(String firstName, String lastName, String email) {
            setFirstName(firstName);
            setLastName(lastName);
            setEmail(email);
        }

        public final StringProperty firstNameProperty() {
            return this.firstName;
        }

        public final String getFirstName() {
            return this.firstNameProperty().get();
        }

        public final void setFirstName(final String firstName) {
            this.firstNameProperty().set(firstName);
        }

        public final StringProperty lastNameProperty() {
            return this.lastName;
        }

        public final String getLastName() {
            return this.lastNameProperty().get();
        }

        public final void setLastName(final String lastName) {
            this.lastNameProperty().set(lastName);
        }

        public final StringProperty emailProperty() {
            return this.email;
        }

        public final String getEmail() {
            return this.emailProperty().get();
        }

        public final void setEmail(final String email) {
            this.emailProperty().set(email);
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30802776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档