2016-12-17 1 views
0

J'essaye de construire mon premier programme et j'ai du mal à communiquer entre les contrôleurs javaFX et ma classe d'application principale. Le programme est un compte à rebours: vous entrez un nombre d'heures et de minutes et une fenêtre pop-up s'ouvre lorsque le compte à rebours est terminé.JavaFx: Comment dire à ma classe principale de faire quelque chose avec mon contrôleur?

fonction Voilà mon contrôleur principal ButtonClicked:

@FXML 
private TextField heure; 
@FXML 
private TextField minute; 
@FXML 
private Button launchButton; 
private String hour,minutes; 

public void launchButtonClicked(){ 
    hour = heure.getText(); 
    minutes = minute.getText(); 

    try { 
      int h = Integer.parseInt(hour); 
      int m = Integer.parseInt(minutes); 

      System.out.println("MenuController"); 


    } catch (NumberFormatException e) { 
      //Will Throw exception! 
      //do something! anything to handle the exception. 
    } 

} 

et voici la classe principale:

public class Main extends Application { 
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 


@Override 
public void start(Stage primaryStage) { 
    try { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("Menu.fxml")); 
     Parent root = loader.load(); 
     Scene scene = new Scene(root,800,500); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

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

public void rappel(int h,int m){ 
    System.out.println("Rappel" + h + m); 
    int minute = (h*60 + m) - 5;   
    final Runnable rappel = new Runnable(){ 
     public void run(){ 
      AlertBox box = new AlertBox(); 
      box.display("Reminder","Rappel : 5 min"); 
     } 
    }; 

    final ScheduledFuture<?> rappelHandle = scheduler.schedule(rappel, minute, TimeUnit.MINUTES); 
    scheduler.schedule(new Runnable() { 
     public void run() { rappelHandle.cancel(true); } 
    }, 60 * 60, TimeUnit.SECONDS); 
} 
} 

Ce que je veux faire est, lorsque le launchButton est cliqué, dire à ma fonction principale d'utiliser la fonction rappel (int h, int m). Il va lancer un alertBox qui affiche une chaîne que je veux. J'ai l'impression de ne pas utiliser le contrôleur juste parce que je n'ai pas trouvé un moyen de mon contrôleur pour "donner des ordres" à ma classe d'application principale.

Avez-vous une idée comment ça pourrait fonctionner? Dois-je utiliser un autre moyen pour faire apparaître une alerte que le service d'ordonnanceur programmé? Ps: Je n'ai pas encore pris la peine d'écrire le test et la gestion des exceptions. Je promets que je ferai quand je parviens à le faire fonctionner!

+0

Quel est le point d'utiliser FXML si vous utilisez votre classe principale? Le but du FXML est de séparer le graphique de la logique de votre programme. Utilisez votre contrôleur! –

+0

Qu'en est-il de "nouveau Main(). Rappel (int, int,)"? – creativecreatorormaybenot

+0

Existe-t-il une raison pour ne pas simplement déplacer la méthode 'rappel (...)' vers le contrôleur? Cela semblerait être un endroit plus naturel pour cela. –

Répondre

0

Une manière simple de communiquer entre les composants est d'ajouter une propriété d'écouteur à la classe de contrôleur et d'ajouter un écouteur à partir de main. Notez, il existe des façons plus propres de câbler des choses JavFX ensemble, selon les besoins du programme, mais je ne vais pas entrer dans ici car cela dépend et il ya assez de tutoriels sur les modèles de conception. Voici un moyen juste pour répondre à la question de la programmation et est suffisant pour exécuter votre programme:

Dans contrôleur

class YourControllerClass{ 
... 
    Runnable launchListener; 

    public void setLaunchListener(Runnable launchListener){ 
     this.launchListener = launchListener; 
    } 
... 

dans le principal:

... 
controller = (YourControllerClass) loader 
         .getController(); 
controller.setLaunchListener(() -> { 
        rappel(1,2) 
       }); 

je Runnable ici car il est intégré dans. Si vous avez besoin de passer des paramètres du contrôleur, définir une interface et de l'utiliser au lieu de Runnable:

Dans contrôleur

class YourControllerClass{ 
... 
    public static interface ILaunchListener{ 
    public void onLaunch(int h, int m); 
    } 

    ILaunchListener launchListener; 

    public void setLaunchListener(ILaunchListener launchListener){ 
     this.launchListener = launchListener; 
    } 

    public void launchButtonClicked(){ 
    if(launchListener!=null){ 
     hour = heure.getText(); 
     minutes = minute.getText(); 

     try { 
       int h = Integer.parseInt(hour); 
       int m = Integer.parseInt(minutes); 

       launchListener.onLaunch(h, m); 


     } catch (NumberFormatException e) { 
       //Will Throw exception! 
       //do something! anything to handle the exception. 
     } 
    } 
    } 

... 

dans le principal:

... 
controller = (YourControllerClass) loader 
         .getController(); 
controller.setLaunchListener((h, m) -> { 
        rappel(h,m) 
       });