allora, ho provato a fare in questo modo.
controller base:
controller che estende quello base:codice:public class ControllerAuthorEditor<T> { private ReadJson jsonRead; protected Stage stage; @FXML protected BorderPane aePane; @FXML public void initialize() { jsonRead = new ReadJson(); TypeToken<List<T>> token = getToken(); try { List<T> list = jsonRead.readJson(new File(UrlAndPath.JSON_AUTORI), token); ObservableList<T> oList = FXCollections.observableArrayList(list); oList = postRead(oList); } catch (IOException e) { GenericDialog.showDialog(e.getMessage(), Alert.AlertType.ERROR); } } protected TypeToken<List<T>> getToken() { return new TypeToken<List<T>>() { }; } protected ObservableList<T> postRead(ObservableList<T> input) { return input; } protected Stage getStage() { stage = (Stage) aePane.getScene().getWindow(); return stage; } @FXML protected void escPressed(KeyEvent event) { if (event.getCode() == KeyCode.ESCAPE) { getStage(); stage.close(); } } }
funzionare funziona.codice:public class ControllerAuthor extends ControllerAuthorEditor<Author> { @FXML private ComboBox<Author> comboAE; @Override protected TypeToken<List<Author>> getToken() { return new TypeToken<List<Author>>() { }; } @Override protected ObservableList<Author> postRead(ObservableList<Author> input) { comboAE.setItems(input); comboAE.setCellFactory(new ComboListCell<Author>()); return input; } }
è anche corretto secondo te??
Innanzitutto la implementazione di getToken in ControllerAuthorEditor ha poco senso. Come ho già detto, fare new TypeToken<List<T>>() {} è inutile, cioè non è un "default" valido. Sarebbe stato meglio obbligare le sottoclassi ad implementare il metodo.
Poi non ho capito perché devi mettere il ComboBox e quei setItems e setCellFactory nella sottoclasse. Questi mi pare che puoi trattarli in modo "generico".
Lo ripeto ancora: tutto quello che puoi trattare in modo generico senza dover sapere se sono Author o Editor, lo puoi mettere nella superclasse.
Quello che devi fare sapendo esattamente se è Author o Editor (la creazione del TypeToken è un caso), lo devi fare nella sottoclasse dove hai fissato tu la parametrizzazione.
ok, intendi una cosa del genere??
e nella sottoclasse:codice:public abstract class ControllerAuthorEditor<T> { private ReadJson jsonRead; protected Stage stage; @FXML protected BorderPane aePane; @FXML private ComboBox<T> comboAE; @FXML public void initialize() { jsonRead = new ReadJson(); TypeToken<List<T>> token = getToken(); try { List<T> list = jsonRead.readJson(new File(UrlAndPath.JSON_AUTORI), token); ObservableList<T> oList = FXCollections.observableArrayList(list); oList = postRead(oList); comboAE.setItems(oList); comboAE.setCellFactory(new ComboListCell<T>()); } catch (IOException e) { GenericDialog.showDialog(e.getMessage(), Alert.AlertType.ERROR); } } protected abstract TypeToken<List<T>> getToken(); protected ObservableList<T> postRead(ObservableList<T> input) { return input; } protected Stage getStage() { stage = (Stage) aePane.getScene().getWindow(); return stage; } @FXML protected void escPressed(KeyEvent event) { if (event.getCode() == KeyCode.ESCAPE) { getStage(); stage.close(); } } }
codice:public class ControllerAuthor extends ControllerAuthorEditor<Author> { @Override protected TypeToken<List<Author>> getToken() { return new TypeToken<List<Author>>() { }; } }
Sì, esatto. Il getToken è un "obbligo" implementarlo nella sottoclasse (nella superclasse non avrebbe un default valido). Mentre invece postRead è un altro "punto di estensione" che però è facoltativo da ridefinire. Mettendolo hai solo tenuta "aperta" la possibilità di ridefinirlo. Noto anche che il postRead l'hai fatto basato su ObservableList invece che List. Va bene, cioè ... è una scelta.
In futuro, visto che è tutto sotto il tuo controllo, potrai aggiungere altri "punti di estensione" come vorrai, se ce ne fosse bisogno.