Почему экземпляр JavaF XML TablePosition считается необработанным типом при объявлении аргументов типа? - PullRequest
0 голосов
/ 07 января 2020

Следующий код изолирован от довольно сложного бухгалтерского приложения, которое я разрабатываю, но предупреждение компилятора точно такое же, как и при компиляции приложения. Некоторая логика c, необходимая приложению, заключается в том, чтобы гарантировать, что область просмотра TableView начинается с определенной транзакции.

package tabpane2.view;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import newdawn.model.TxnObject;

public class MainController implements Initializable {
  @FXML private Button exitBtn;
  @FXML private Button goBtn;
  @FXML private TableView<TxnObject> txnTable;
  @FXML private TableColumn<TxnObject, String> txnDateCol;
  @FXML private TableColumn<TxnObject, String> toFromCol;
  private ObservableList<TxnObject> txnData = FXCollections.observableArrayList(); 


  @Override
  public void initialize(URL location, ResourceBundle resources) {
    txnDateCol.setCellValueFactory(cellData -> cellData.getValue().localtxnDateProperty());
    toFromCol.setCellValueFactory(cellData -> cellData.getValue().toFromProperty());
    setTableView();
    txnTable.setItems(txnData);
  }

  private void getTablePosition() { 
    ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
    for (int i = 0; i < rowvals.size(); i++) {
      TablePosition pos = txnTable.getSelectionModel().getSelectedCells().get(i);
      int row = pos.getRow();
      TxnObject obj = txnTable.getItems().get(row);
      System.out.println("Txn is " + obj.toString());
    }
  }

  private void setTableView(){
    txnData.add(new TxnObject("19000101","001","Fred","B","C","D","0.00","0.00","0.00"));
    txnData.add(new TxnObject("19000102","001","Lars","B","C","D","0.00","0.00","0.00"));
    txnData.add(new TxnObject("19000102","002","Bertil","B","C","D","0.00","0.00","0.00"));
  }

  @FXML private void handleGoBtn() {
    getTablePosition();
  }

  @FXML private void handleExitBtn() {
    System.exit(0);
  }
}

Возвращаемый дамп выглядит так:

G:\J2EE\TabPane_2\src\tabpane2\view\MainController.java:33: warning: [rawtypes] found raw type: TablePosition
    ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
  missing type arguments for generic class TablePosition<S,T>
  where S,T are type-variables:
    S extends Object declared in class TablePosition
    T extends Object declared in class TablePosition
G:\J2EE\TabPane_2\src\tabpane2\view\MainController.java:35: warning: [rawtypes] found raw type: TablePosition
      TablePosition pos = txnTable.getSelectionModel().getSelectedCells().get(i);
  missing type arguments for generic class TablePosition<S,T>
  where S,T are type-variables:
    S extends Object declared in class TablePosition
    T extends Object declared in class TablePosition

Читая дамп, он говорит, что TablePosition, ie, S и T нужны два аргумента типа. Поэтому я попытался заменить объявление pos на:

TablePosition<TxnObject, TxnObject> pos = txnTable.getSelectionModel().getSelectedCells().get(i);

, а также попытался:

TablePosition<TxnObject, String> pos = txnTable.getSelectionModel().getSelectedCells().get(i);

Но затем возвращается компиляция:

G:\J2EE\TabPane_2\src\tabpane2\view\MainController.java:33: warning: [rawtypes] found raw type: TablePosition
    ObservableList<TablePosition> rowvals  = txnTable.getSelectionModel().getSelectedCells();
  missing type arguments for generic class TablePosition<S,T>
  where S,T are type-variables:
    S extends Object declared in class TablePosition
    T extends Object declared in class TablePosition
G:\J2EE\TabPane_2\src\tabpane2\view\MainController.java:36: warning: [unchecked] unchecked conversion
      TablePosition<TxnObject, TxnObject> pos = txnTable.getSelectionModel().getSelectedCells().get(i);
  required: TablePosition<TxnObject,TxnObject>
  found:    TablePosition

или

  required: TablePosition<TxnObject,String>
  found:    TablePosition

Я не понимаю, почему возникает предупреждение, хотя я даю TablePosition аргументы, которые он просил. Что я делаю не так?

1 Ответ

1 голос
/ 08 января 2020

Это ошибка в (или, если дизайн на самом деле намеренный, следствие) подписи API. Если вы посмотрите на метод TableViewSelectionModel#getSelectedCells(), вы обнаружите, что он возвращает ObservableList<TablePosition>. Как видите, список объявляет необработанный тип из TablePosition, который эффективно стирает обобщенную c информацию, используемую с TableView. Если бы он был реализован без необработанных типов, этот метод возвратил бы ObservableList<TablePosition<S, ?>>.

Вы пытаетесь обойти это путем (неявного) приведения к типу generi c, но переход от необработанного типа к типу generi c является непроверенной операцией, поэтому предупреждение (s) ).

Есть сообщение об ошибке, связанное с этой проблемой: JDK-8089446 . Однако, основываясь на комментариях, исправление ошибки может быть несовместимо и, следовательно, ошибка может никогда не быть исправлена. Обратите внимание, что проблема связана не только с вышеприведенным, но и со свойством TableViewFocusModel#focusedCell; для этого есть запрос на улучшение, JDK-8212737 , но решение проблемы имеет те же потенциальные проблемы с обратной совместимостью.

К сожалению, вы ничего не можете сделать, кроме как подавить предупреждения. Если это проблема во всем приложении, вы можете создать служебный метод для «восстановления» обобщенной c информации:

@SuppressWarnings("unchecked")
public static <S> ObservableList<TablePosition<S, ?>> getSelectedCells(TableView<S> table) {
  return (ObservableList<TablePosition<S, ?>>)
      (ObservableList<?>) table.getSelectionModel().getSelectedCells();
}

Обратите внимание, что аргумент второго типа TablePosition<S, ?> является подстановочным знаком (т.е. ?). Это необходимо, поскольку каждый столбец таблицы в табличном представлении может содержать другой произвольный тип.

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