Почему компилятор генерирует непроверенные предупреждения при использовании TableColumnа не TableColumnвыбрать ячейку в JavaFX8 TableView? - PullRequest
0 голосов
/ 08 октября 2018

Относительный вопрос новичка в Java.

Я очищаю свой код и натолкнулся на два непроверенных предупреждения (" непроверенный вызов метода " и " непроверенное преобразование msgstr ") при программном выборе ячейки в TableView.Мне удалось разрешить предупреждения, но я не понимаю, что их вызвало.

Именно так я первоначально кодировал select():

TablePosition<?, ?> previousPos;
//...
table.getSelectionModel().select
    (previousPos.getRow(), previousPos.getTableColumn());

, и я решил предупреждения, изменив ихк этому.

table.getSelectionModel().select
    (previousPos.getRow(), table.getColumns().get(previousPos.getColumn()));

Я не понял разницу, поэтому я взглянул на исходный код Java.Если я правильно его интерпретирую, метод select() в TableView.java ожидает TableColumn<S, ?>.Однако getTableColumn() в TablePosition.java возвращает TableColumn<S,T>, в то время как getColumns() в TableView.java возвращает ObservableList типа TableColumn(S, ?).

Наверное, поэтому table.getColumns().get(...) компилирует чисто, а previousPos.getTableColumn() генерирует ошибки.

Но в чем же разница между TableColumn<S, ?> и TableColumn<S,T> с точки зрения компилятора?Почему он не разрешает (это правильный термин?) T до ?.

Если это помогает, вот MVCE, с которым я играл, чтобы попытаться выяснить это, ноОтвет за пределами моего текущего знания Java.select() находится в moveToPreviousPos().

Я использую JavaFX8 (JDK1.8.0_181), NetBeans 8.2 и Scene Builder 8.3.

package test27;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Test27 extends Application {

    TableView<TestModel> table = new TableView<>();

    //Both of these stop the "unchecked conversion" error on line #51 (previousPos = table.getFocusModel().getFocusedCell();)
    //    TablePosition previousPos;
        TablePosition<?, ?> previousPos;
    //but using the following generates the "unchecked conversion" error
    //    TablePosition<TestModel, ?> previousPos;

    private Parent createContent() {

        ObservableList<TestModel> olTestModel = FXCollections.observableArrayList();

        olTestModel.add(new TestModel("A"));
        olTestModel.add(new TestModel("B"));
        olTestModel.add(new TestModel("C"));

        table.setItems(olTestModel);

        TableColumn<TestModel, String> colText = new TableColumn<>("text");
        colText.setCellValueFactory(cellData -> cellData.getValue().textProperty());
        colText.setCellFactory(TextFieldTableCell.forTableColumn());

        table.getSelectionModel().setCellSelectionEnabled(true);
        table.setEditable(true);
        table.getColumns().add(colText);

        Button btnGetTablePosition = new Button("get table position");
        btnGetTablePosition.setOnAction(event -> {
            //TableView.java:  getFocusedCell returns TablePosition<S, ?>
            previousPos = table.getFocusModel().getFocusedCell(); //Line #51
            outputPreviousPos(previousPos);
        });

        Button btnMoveToPreviousPos = new Button("move to previous pos");
        btnMoveToPreviousPos.setOnAction(event -> {
            moveToPreviousPos(previousPos);
        });

        BorderPane content = new BorderPane(table);
        HBox hb = new HBox();
        hb.getChildren().addAll(btnGetTablePosition, btnMoveToPreviousPos);

        content.setTop(hb);

        return content;

    }

    public void outputPreviousPos(TablePosition previousPos){

        System.out.println("previousPos = " + previousPos);

    }

    public void moveToPreviousPos(TablePosition previousPos) {

        //select() in TableView.java expects TableColumn<S, ?>
        //getTableColumn() in TablePosition.java returns TableColumn<S,T>
        //getColumns() in TableView.java returns an ObservableList of type TableColumn(S, ?)

        //Is that why the following line generates  "unchecked method invocation" and "unchecked conversion" errors
        //table.getSelectionModel().select
        //      (previousPos.getRow(), previousPos.getTableColumn());
        //but the following line compiles clean?
        table.getSelectionModel().select
                (previousPos.getRow(), table.getColumns().get(previousPos.getColumn()));        

    }

    public class TestModel {

        private StringProperty text;

        public TestModel() {
            this("");
        }

        public TestModel(
            String text
        ) {
            this.text = new SimpleStringProperty(text);
        }

        public String getText() {
            return text.get();
        }

        public void setText(String text) {
            this.text.set(text);
        }

        public StringProperty textProperty() {
            return text;
        }

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setTitle("Test");
        stage.setWidth(500);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

1 Ответ

0 голосов
/ 08 октября 2018

Прежде всего, я бы сказал, что это был конструктивный недостаток: TableView.getFocusModel().getFocusedCell() (или focusedCellProperty()) использует тип raw TablePosition (raw TablePosition может быть приведен только к TablePositon<?, ?> без выдачи предупреждения).,Более подходящая версия могла бы быть TablePosition<S, ?>.

, поскольку TablePosition представляет конкретную ячейку в любом месте в TableView, тогда для TableView.getFocusModel().focusedCellProperty():

  1. Тип S фиксирован для TableView<S> (т.е. тип известен).
  2. Тип T относится к типу определенного * 1024.*, который может меняться в зависимости от того, какая ячейка была сфокусирована.Вы не можете определить тип во время компиляции, потому что вы не знаете, какой TableColumn<S, T> будет выбран.

Теперь ко второй точке.

Но в чем разница?тогда между TableColumn<S, ?> и TableColumn<S,T> с точки зрения компилятора?Почему он не разрешает (это правильный термин?) T до ?.

Это потому, что ? в TableColumn<S, ?> является подстановочным знаком.Поскольку TableViewFocusModel<S> не имеет типа T и что он не работает на основе фиксированного столбца, поэтому он должен использовать ? здесь (см. Первый пункт, который я объяснил).

Вкл.с другой стороны, TableView.getSelectionModel().select() ожидает int для row и TableColumn<S, ?> для столбца.Поскольку у вас было TablePosition<?, ?> previousPos, то previousPos также вернет TableColumn<?, ?>.TableColumn<S, ? и TableColumn<?, ?> очень разные - вы можете использовать TableColumn от другого TableView, если разрешено TableColumn<?, ?>.

Наконец, если API для TableView.getFocusModel().getFocusedCell() фиксирован, то естьне будет проблем при использовании select().До этого вы могли вручную привести его к TablePosition<TestModel, ?> с подавлением или использовать TableView.getColumns().get(index) как то, что вы сделали.

...