001package fi.jyu.mit.fxgui; 002 003import java.io.IOException; 004import java.net.URL; 005 006import javafx.fxml.FXML; 007import javafx.fxml.FXMLLoader; 008import javafx.scene.Node; 009import javafx.scene.Parent; 010import javafx.scene.Scene; 011import javafx.stage.Modality; 012import javafx.stage.Stage; 013 014/** 015 * Modaalisen dialogin näyttäminen 016 * 017 * @author vesal 018 * @version 2.1.2016 019 * @param <TYPE> minkä tyyppinen tulos palautetaan dialogista. 020 */ 021public class ModalController<TYPE> implements ModalControllerInterface<TYPE> { 022 023 /** 024 * Funktionaalinen rajapinta takaisinkutsulle luokan alustamiseksi 025 * @author vesal 026 * @version 18.3.2016 027 * 028 * @param <TYPE> mikä on perusluokan tyyppi 029 * @param <CONTROLLERTYPE> mikä on dialogin kontrolleriluokan tyyppi 030 */ 031 public interface ModalInitializeInterface<TYPE, CONTROLLERTYPE extends ModalControllerInterface<TYPE>> { 032 /** 033 * @param ctrl kontrolleri, jonne jotakin asetetaan 034 */ 035 public void initialize(CONTROLLERTYPE ctrl); 036 } 037 038 039 class MyGenericClass<T> { 040 private final Class<T> clazz; 041 public MyGenericClass(Class<T> clazz) { 042 this.clazz = clazz; 043 } 044 public Class<T> getGenericClass() { 045 return clazz; 046 } 047 } 048 049 050 private Stage stage; 051 052 @FXML private void handleDefaultOK() { 053 stage.close(); 054 } 055 056 057 @FXML private void handleDefaultCancel() { 058 stage.close(); 059 } 060 061 062 /** 063 * @return palautetaan dialogin tulos 064 */ 065 @Override 066 public TYPE getResult() { 067 return null; 068 } 069 070 071 /** 072 * Asetetaan oletusarvo 073 * @param oletus mitä näyteteään oletuksena 074 */ 075 @Override 076 public void setDefault(TYPE oletus) { 077 // 078 } 079 080 081 /** 082 * Mitä tehdään kun dialogi on näytetty 083 */ 084 @Override 085 public void handleShown() { 086 // 087 } 088 089 090 /** 091 * Palauttaa nodea vastaavan stagen 092 * @param n minkä stagea etsitään 093 * @return nodea vstaava stage 094 */ 095 public static Stage getStage(Node n) { 096 return ((Stage)n.getScene().getWindow()); 097 } 098 099 100 /** 101 * Sulkee stagen johon node kuuluu 102 * @param n minkä stagea etsitään 103 */ 104 public static void closeStage(Node n) { 105 getStage(n).close(); 106 } 107 108 109 /** 110 * Luodaan dialogi ja palautetaan siihen täytetty data tai null 111 * @param url osoite, josta .fxml tiedosto löytyy 112 * @param title Otsikko joka näytetään 113 * @param modalityStage mille ollaan modaalisia, null = sovellukselle 114 * @param oletus mitä dataa näytetään oletuksena 115 * @return null jos painetaan Cancel, muuten kirjoitettu nimi 116 */ 117 public static <TYPE> TYPE showModal(URL url, String title, Stage modalityStage, TYPE oletus) { 118 return showModal(url, title, modalityStage, oletus, null); 119 } 120 121 122 /** 123 * Luodaan dialogi ja palautetaan siihen täytetty data tai null 124 * @param url osoite, josta .fxml tiedosto löytyy 125 * @param title Otsikko joka näytetään 126 * @param modalityStage mille ollaan modaalisia, null = sovellukselle 127 * @param oletus mitä dataa näytetään oletuksena 128 * @param initializeCallback mitä kutsutaan kun dialogi on luotu 129 * @return null jos painetaan Cancel, muuten dialogin data 130 */ 131 public static <TYPE, CONTROLLERTYPE extends ModalControllerInterface<TYPE>> 132 TYPE showModal(URL url, String title, Stage modalityStage, TYPE oletus, 133 ModalInitializeInterface<TYPE, CONTROLLERTYPE> initializeCallback) { 134 try { 135 FXMLLoader ldr = new FXMLLoader(url); 136 Parent root = ldr.load(); 137 @SuppressWarnings("unchecked") 138 final CONTROLLERTYPE dialogCtrl = (CONTROLLERTYPE)ldr.getController(); 139 Stage stage = new Stage(); 140 if ( dialogCtrl instanceof ModalController ) { 141 ((ModalController<TYPE>)dialogCtrl).stage = stage; 142 } 143 144 stage.setScene(new Scene(root)); 145 stage.setTitle(title); 146 if ( modalityStage != null ) { 147 stage.initModality(Modality.WINDOW_MODAL); 148 stage.initOwner(modalityStage); 149 } else 150 stage.initModality(Modality.APPLICATION_MODAL); 151 152 if ( dialogCtrl != null ) { 153 dialogCtrl.setDefault(oletus); 154 stage.setOnShown((e)-> { 155 // dialogCtrl.vastaus.requestFocus(); 156 //dialogCtrl.vastaus.selectAll(); 157 dialogCtrl.handleShown(); 158 }); 159 if ( initializeCallback != null ) initializeCallback.initialize(dialogCtrl); 160 stage.showAndWait(); 161 return dialogCtrl.getResult(); 162 } 163 stage.showAndWait(); 164 return null; 165 166 } catch (IOException e) { 167 System.err.println(e.toString()); 168 return null; 169 } 170 } 171 172 173 /** 174 * Luodaan modeless dialogi ja palautetaan sen käsittelijä 175 * @param url osoite, josta .fxml tiedosto löytyy 176 * @param title Otsikko joka näytetään 177 * @param oletus mitä dataa näytetään oletuksena 178 * @return null jos painetaan Cancel, muuten kirjoitettu nimi 179 */ 180 public static <TYPE, CONTROLLERTYPE extends ModalControllerInterface<TYPE>> CONTROLLERTYPE showModeless(URL url, String title, TYPE oletus) { 181 Stage stage = new Stage(); 182 try { 183 FXMLLoader ldr = new FXMLLoader(url); 184 Parent root = ldr.load(); 185 @SuppressWarnings("unchecked") 186 final CONTROLLERTYPE dialogCtrl = (CONTROLLERTYPE)ldr.getController(); 187 stage.setScene(new Scene(root)); 188 stage.setTitle(title); 189 if ( dialogCtrl != null ) { 190 dialogCtrl.setDefault(oletus); 191 stage.setOnShown((e)-> { 192 // dialogCtrl.vastaus.requestFocus(); 193 //dialogCtrl.vastaus.selectAll(); 194 dialogCtrl.handleShown(); 195 }); 196 stage.show(); 197 return dialogCtrl; 198 } 199 stage.show(); 200 return null; 201 202 } catch (IOException e) { 203 System.err.println(e.toString()); 204 return null; 205 } 206 } 207}