代码之家  ›  专栏  ›  技术社区  ›  Marv

防止TableColumn仅由用户调整大小

  •  0
  • Marv  · 技术社区  · 8 年前

    有没有办法阻止任何或至少所有JavaFX TableColumn TableView 由用户调整大小,同时仍允许调整大小策略工作?

    存在 TableColumn::setResizable ,但同时阻止用户调整 表列 ,它还阻止调整大小策略调整 .

    1 回复  |  直到 8 年前
        1
  •  3
  •   Sai Dandem    8 年前

    一个快速的解决方案是为鼠标拖动表标题行添加事件过滤器。创建自定义tableView并在标题行上添加事件过滤器,如下所示:

    class CustomTableView<S> extends TableView<S>{
            private Node headerRow;
    
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                if(headerRow ==null){
                    headerRow = (Region) lookup("TableHeaderRow");
                    headerRow.addEventFilter(MouseEvent.MOUSE_DRAGGED, MouseEvent::consume);
                }
            }
        }
    

    下面是一个快速工作的演示,在仍然允许调整大小策略的情况下禁用列大小和重新排列。

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Region;
    import javafx.stage.Stage;
    
    public class TableResizeRestrictionDemo extends Application {
        @Override
        public void start(Stage primaryStage) throws Exception {
            ObservableList<Person> persons = FXCollections.observableArrayList();
            persons.add(new Person("Harry","John","LS"));
            persons.add(new Person("Mary","King","MS"));
            persons.add(new Person("Don","Bon","CAT"));
            persons.add(new Person("Pink","Wink","IND"));
    
            CustomTableView<Person> tableView = new CustomTableView<>();
            TableColumn<Person, String> fnCol = new TableColumn<>("First Name");
            fnCol.setCellValueFactory(param -> param.getValue().firstNameProperty());
    
            TableColumn<Person, String> lnCol = new TableColumn<>("Last Name");
            lnCol.setCellValueFactory(param -> param.getValue().lastNameProperty());
    
            TableColumn<Person, String> cityCol = new TableColumn<>("City");
            cityCol.setCellValueFactory(param -> param.getValue().cityProperty());
    
            tableView.getColumns().addAll(fnCol, lnCol, cityCol);
            tableView.setItems(persons);
            tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    
            Scene sc = new Scene(tableView);
            primaryStage.setScene(sc);
            primaryStage.show();
    
        }
    
        class Person{
            private StringProperty firstName = new SimpleStringProperty();
            private StringProperty lastName = new SimpleStringProperty();
            private StringProperty city = new SimpleStringProperty();
    
            public Person(String fn, String ln, String cty){
                setFirstName(fn);
                setLastName(ln);
                setCity(cty);
            }
    
            public String getFirstName() {
                return firstName.get();
            }
    
            public StringProperty firstNameProperty() {
                return firstName;
            }
    
            public void setFirstName(String firstName) {
                this.firstName.set(firstName);
            }
    
            public String getLastName() {
                return lastName.get();
            }
    
            public StringProperty lastNameProperty() {
                return lastName;
            }
    
            public void setLastName(String lastName) {
                this.lastName.set(lastName);
            }
    
            public String getCity() {
                return city.get();
            }
    
            public StringProperty cityProperty() {
                return city;
            }
    
            public void setCity(String city) {
                this.city.set(city);
            }
        }
    
        class CustomTableView<S> extends TableView<S>{
            private Node headerRow;
    
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                if(headerRow ==null){
                    headerRow = (Region) lookup("TableHeaderRow");
                    headerRow.addEventFilter(MouseEvent.MOUSE_DRAGGED, MouseEvent::consume);
                }
            }
        }
    }
    

    更新:: 在检查NestedTableColumnHeader类中的源代码之后,负责调整大小的节点实际上是矩形。不幸的是,没有为这个矩形设置样式类。因此,假设HeaderRow中的所有矩形都是为了调整大小,我们将查找所有矩形节点并设置事件过滤器。

    内部按下-拖动-释放处理程序用于调整大小,而进入-退出处理程序用于更改光标。因此,与其为5种类型的事件设置过滤器,不如设置一个超级事件MouseEvent.ANY。这也将解决更改光标的问题。

    class CustomTableView<S> extends TableView<S> {
            private final EventHandler<MouseEvent> consumeEvent = MouseEvent::consume;
    
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                final Set<Node> dragRects = lookup("TableHeaderRow").lookupAll("Rectangle");
                for (Node dragRect : dragRects) {
                    dragRect.removeEventFilter(MouseEvent.ANY, consumeEvent);
                    dragRect.addEventFilter(MouseEvent.ANY, consumeEvent);
                }
            }
        }
    

    推荐文章