Запрет изменения размера TableColumn только пользователем - PullRequest
0 голосов
/ 20 сентября 2018

Есть ли способ предотвратить изменение размера любого или по крайней мере всех JavaFX TableColumn в TableView пользователем, при этом позволяя политике изменения размера работать?

Существует TableColumn::setResizable, но, не позволяя пользователю изменить размер TableColumn, он также не позволяет политике изменения размера изменить TableColumn.

1 Ответ

0 голосов
/ 20 сентября 2018

Быстрое решение - добавить фильтр событий для перетаскивания мышью по строке заголовка таблицы.Создайте пользовательский 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);
            }
        }
    }
}

Update :: После проверки исходного кода в классе NestedTableColumnHeader узлы, отвечающие за изменение размера, действительно являются Rectangle (s).К сожалению, для этого прямоугольника не установлен класс стиля.Таким образом, предполагая, что все прямоугольники в HeaderRow предназначены для изменения размера, мы ищем все узлы Rectangle и устанавливаем фильтр событий.

Внутренние обработчики PRESSED-DRAGGED-RELEASED установлены для изменения размера, а обработчики ENTER-EXIT установлены дляизменение курсора.Поэтому вместо установки фильтров для 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);
            }
        }
    }

Причина, по которой вы не сохраняете ссылку на прямоугольники (как, например, HeaderRow в демоверсии), заключается в том, что каждый раз, когда вы перестраиваете столбец, появляется новый набор прямоугольников.генерироваться.Таким образом, вы не можете полагаться на любые ссылки Rectangle.Чтобы избежать дублирования фильтров, мы создаем ссылку на обработчик, сначала удаляем, а затем добавляем обработчик.

...