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}