【问题标题】:JavaFx: disable reordering for first/last columnJavaFx:禁用第一列/最后一列的重新排序
【发布时间】:2018-04-04 01:49:35
【问题描述】:

我想禁用 tableView 中第一列或最后一列的重新排序。 我可以通过两种方式禁用第一列或最后一列,因此我不能移动第一列/最后一列,但两种方式都可以让我将另一列拖到第一列/最后一列。我该如何防止这种情况。我想以某种方式在那里设置一个“障碍”,以便始终有一个固定的列。

我如何禁用 firstColumn:

firstColumn.impl_setReorderable(false); // I know the method is @Deprecated  but it works :)

另一种解决方案是使用反射,获取TableHeaderRow 的引用,然后禁用重新排序。但是这个解决方案的问题是,它禁用了所有列进行重新排序,而我只想要第一个或最后一个。

任何简单的想法我该怎么做这样的事情?

【问题讨论】:

    标签: java javafx tableview javafx-8 tablecolumn


    【解决方案1】:

    您可以“让”重新排序,然后监听更改,在活动结束时,您可以按照自己喜欢的方式重新排列列。关于重新排序列的一个非常有用的帖子是this one(嗯,有很多很好的答案你应该考虑看看)。因此,您可以在表的 skin 属性中添加一个侦听器,并在其中执行以下操作:

    table.skinProperty().addListener((obs, oldSkin, newSkin) -> {
        final TableHeaderRow header = (TableHeaderRow) table.lookup("TableHeaderRow");
        header.reorderingProperty().addListener((o, oldVal, newVal) -> {
            ObservableList columns = table.getColumns();
    
            // If the first columns is not in the first index change it
            if (columns.indexOf(firstNameCol) != 0) {
                    columns.remove(firstNameCol);
                    columns.add(0, firstNameCol);
                }
            // Use the same logic for the last column
            if (columns.indexOf(phoneCol) != columns.size() - 1) {
                columns.remove(phoneCol);
                columns.add(columns.size() , phoneCol);
            }
        });
    });
    

    这是一个完整的工作示例:

    import com.sun.javafx.scene.control.skin.TableHeaderRow;
    
    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.VBox;
    import javafx.scene.text.Font;
    import javafx.stage.Stage;
    
    public class TestApp extends Application {
    
        private TableView<Person> table = new TableView<Person>();
        private final ObservableList<Person> data = FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "jacob.smith@example.com", "845-548-600"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com", "455-777-645"),
                new Person("Ethan", "Williams", "ethan.williams@example.com", "888-504-254"),
                new Person("Emma", "Jones", "emma.jones@example.com", "123-548-350"),
                new Person("Michael", "Brown", "michael.brown@example.com", "650-120-600"));
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage stage) {
            Scene scene = new Scene(new Group());
            stage.setTitle("Table View Sample");
            stage.setWidth(550);
            stage.setHeight(500);
    
            final Label label = new Label("Address Book");
            label.setFont(new Font("Arial", 20));
    
            table.setEditable(true);
    
            TableColumn firstNameCol = new TableColumn("First Name");
            firstNameCol.setMinWidth(100);
            firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
    
            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setMinWidth(100);
            lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
    
            TableColumn emailCol = new TableColumn("Email");
            emailCol.setMinWidth(200);
            emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
    
            TableColumn phoneCol = new TableColumn("Phone");
            phoneCol.setMinWidth(100);
            phoneCol.setCellValueFactory(new PropertyValueFactory<Person, String>("phone"));
    
            table.setItems(data);
            table.getColumns().addAll(firstNameCol, lastNameCol, emailCol, phoneCol);
    
            table.skinProperty().addListener((obs, oldSkin, newSkin) -> {
                final TableHeaderRow header = (TableHeaderRow) table.lookup("TableHeaderRow");
                header.reorderingProperty().addListener((o, oldVal, newVal) -> {
                    ObservableList columns = table.getColumns();
    
                    // If the first columns is not in the first index change it
                    if (columns.indexOf(firstNameCol) != 0) {
                        columns.remove(firstNameCol);
                        columns.add(0, firstNameCol);
                    }
                    // Use the same logic for the last column
                    if (columns.indexOf(phoneCol) != columns.size() - 1) {
                        columns.remove(phoneCol);
                        columns.add(columns.size(), phoneCol);
                    }
                });
            });
    
            final VBox vbox = new VBox();
            vbox.setSpacing(5);
            vbox.setPadding(new Insets(10, 0, 0, 10));
            vbox.getChildren().addAll(label, table);
    
            ((Group) scene.getRoot()).getChildren().addAll(vbox);
    
            stage.setScene(scene);
            stage.show();
        }
    
        public static class Person {
    
            private final SimpleStringProperty firstName;
            private final SimpleStringProperty lastName;
            private final SimpleStringProperty email;
            private final SimpleStringProperty phone;
    
            private Person(String fName, String lName, String email, String phone) {
                this.firstName = new SimpleStringProperty(fName);
                this.lastName = new SimpleStringProperty(lName);
                this.email = new SimpleStringProperty(email);
                this.phone = new SimpleStringProperty(phone);
            }
    
            public String getPhone() {
                return phone.get();
            }
    
            public String getFirstName() {
                return firstName.get();
            }
    
            public String getLastName() {
                return lastName.get();
            }
    
            public String getEmail() {
                return email.get();
            }
    
        }
    }
    

    您还可以添加firstNameCol.impl_setReorderable(false);phoneCol.impl_setReorderable(false); 以防止拖动第一列和最后一列。

    【讨论】:

    • 是的,这是有效的,但我认为有一种方法可以防止即使你允许它会改变位置的移动。如果可能的话,最好的解决方案是防止拖到第一列/最后一列,如果不是,我就这样。
    • @Sunflame 您可以将impl_setReorderable(false); 用于您不想被拖动的列,但我不相信有办法(至少是一种简单的方法)来防止即使没有重新排列列,也可以将其他列拖到不可拖动列上的视觉效果。
    • 是的,你可能是对的,但是,我使用了检查第一个是否移动的部分,然后我把它放回了正确的位置。不是最优雅的解决方案,但它有效。感谢您提出这种解决方案的建议。
    猜你喜欢
    • 2016-11-07
    • 2013-03-21
    • 1970-01-01
    • 2013-12-31
    • 2012-08-14
    • 1970-01-01
    • 2022-12-10
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多