JavaFx: CustomTableSkin с CustomTableHeaderRow - PullRequest
0 голосов
/ 12 апреля 2019

Я работаю над CustomTableViewSkin, где я передаю некоторые аргументы конфигурации, чтобы настроить мой скин в зависимости от переданного параметра.Одна из возможностей конфигурации связана с TableHeaderRow, который инициализируется в методе init для ableHeaderRow, который вызывается в конструкторе.Так как я вынужден вызывать супер-конструктор, мои параметры конфигурации еще не инициализированы, и даже если я @Override createTableHeaderRow(), он на самом деле не работает так, как мне нужно.

Я нашелрешение или, точнее сказать, обходной путь, но я не уверен, насколько безопасно его использовать.

Вот простой код, который показывает, что я имею в виду.

public class MyTableSkin<T> extends TableViewSkin<T> {

    private Set<Param> params;

    public MyTableSkin(TableView<T> tableView, Set<Param> params) {
        super(tableView);
        this.params = params;
    }

    @Override
    protected TableHeaderRow createTableHeaderRow() {
        // NPE at params since this method is called in super constructor there params are not initialized.
        if (params.contains(Param.TABLE_HEADER)) {
            return new MyTableHeaderRow(this);
        }
        return super.createTableHeaderRow();
    }

    private static class MyTableHeaderRow extends TableHeaderRow {

        public MyTableHeaderRow(TableViewSkinBase skin) {
            super(skin);
        }
    }

    public enum Param {
        TABLE_HEADER
    }
}

Через некоторое времянемного поэкспериментировав, я нашел этот способ:

public class MyTableSkin<T> extends TableViewSkin<T> {

    private Set<Param> params;

    public MyTableSkin(TableView<T> tableView, Set<Param> params) {
        super(tableView);
        this.params = params;
        getChildren().clear(); // if I didn't do this an exception is thrown
        // calling init again to "reinitialize" the skin.
        super.init(tableView); // how safe is this? :)
    }

    @Override
    protected TableHeaderRow createTableHeaderRow() {
        // Now it enters the if after the second init call, after params are initialized.
        if (params != null && params.contains(Param.TABLE_HEADER)) {
            return new MyTableHeaderRow(this);
        }
        return super.createTableHeaderRow();
    }

    private static class MyTableHeaderRow extends TableHeaderRow {

        public MyTableHeaderRow(TableViewSkinBase skin) {
            super(skin);
        }
    }

    public enum Param {
        TABLE_HEADER
    }
}

Таким образом, он работает, и я получаю свой новый причудливый заголовок таблицы, однако я вижу, что в init есть много вещей, он выполняет инициализацию слушателя и многие другие.другие вещи.

Главный вопрос: так ли это безопасно?Должен ли я беспокоиться о других вещах, которые выполняются в init, или просто игнорировать их?Например, я имею в виду двойную регистрацию слушателей.

Если это не так безопасно или вообще, я бы предложил любую модификацию моего кода или даже совершенно новое решение, которое позволяет мне настраиватьзаголовок, если задан параметр.Этот пользовательский скин предназначен не только для заголовка.params может содержать множество конфигураций, которые можно выполнить для скина, поэтому я не могу создать новый скин для каждой конфигурации / параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...