2015-10-11 1 views
0

J'écris un petit programme qui exécute l'un des trois échantillons de code selon le bouton qui est pressé. Avec le troisième bouton, un échantillon de code devrait fonctionner jusqu'à ce que le JFrame soit fermé, ou jusqu'à ce qu'un bouton soit pressé (ça ne me dérange pas vraiment comment il est arrêté, aussi longtemps que l'utilisateur a une méthode pour arrêter la boucle). Le code est exécuté et un délai de 8 secondes est ajouté pour garantir l'exécution du code avant sa mise en boucle.Comment exécuter un processus en Java jusqu'à ce qu'un bouton soit enfoncé?

Comment l'implémenter? Le programme ne semble pas se terminer en boucle, même lorsque j'essaie de le fermer en cliquant sur le bouton de fermeture dans le JFrame.

La partie principale du programme se présente comme suit:

public class WaspmoteSim extends JFrame implements ActionListener { 
public WaspmoteSim() { 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    //getContentPane().setLayout(new GridLayout(1, 3, 10, 10)); 
    getContentPane().setLayout(new GridBagLayout()); 
    GridBagConstraints c = new GridBagConstraints(); 
    c.insets = new Insets(30,30,30,30); 
    c.ipadx = 10; 
    c.ipady = 30; 
    setSize(700, 150); 
    setLocation(100, 100); 

    JButton button1 = new JButton("Demonstration Mode"); 
    button1.addActionListener(this); 
    add(button1, c); 

    JButton button2 = new JButton("Distribution Fitting Mode"); 
    button2.addActionListener(this); 
    add(button2, c); 

    JButton button3 = new JButton("Operational Mode"); 
    button3.addActionListener(this); 
    add(button3, c); 

    setVisible(true); 
} 
public static void main(String[] args) { 
    new WaspmoteSim(); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    String command = e.getActionCommand(); 

    if (command.equals("Demonstration Mode")) { 
     try { 
      DemoMethod(); 
     } catch (IOException ex) { 
      Logger.getLogger(WaspmoteSim.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
    if (command.equals("Distribution Fitting Mode")) { 
     try { 
      FittingMethod(); 
     } catch (IOException ex) { 
      Logger.getLogger(WaspmoteSim.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
    if (command.equals("Operational Mode")) { 
     try { 
      OperationsMethod(); 
     } catch (IOException ex) { 
      Logger.getLogger(WaspmoteSim.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(WaspmoteSim.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

Le code que je veux courir sur une boucle ressemble à ceci:

public void OperationsMethod() throws IOException, InterruptedException { 
     while(true) { 
      String workingDir = System.getProperty("user.dir"); 
      System.out.println(workingDir); 
      Process proc; 
      proc = Runtime.getRuntime().exec("cmd.exe /C C:\\Progra~1\\R\\R-3.2.1.\\bin\\Rscript.exe " + workingDir + "\\Fitter.r"); 
      TimeUnit.SECONDS.sleep(8); 
     } 
    } 

Répondre

1

La procédure que vous pouvez suivre est la suivante:

1) Créez un Processus en utilisant ProcessBuilder et stockez-le pour une utilisation ultérieure (Vous pouvez utiliser un support "ProcessHolder" pour cette classe).

2) Enregistrer une fonction d'événement sur votre bouton pour enregistrer une fonction d'événement sur votre bouton ayant accès au ProcessHolder et terminer le processus en utilisant la méthode destroy().

Vérifiez pour plus here.

//Process Holder singleton 
public class ProcessHolder { 
    private Map<String, Process> _processes; 

    private static ProcessHolder _processHolder; 

    private ProcessHolder() { 
     _processes = new HashMap<>(); 
    } 

    public static ProcessHolder getInstance() { 
     if(_processHolder == null) { 
      _processHolder = new ProcessHolder(); 
     } 
     return _processHolder; 
    } 

    public void getProcesses() { 
     return _processes; 
    } 

} 

//...... 
public class WaspmoteSim extends JFrame implements ActionListener { 

    public static final String YOUR_PROCESS_NAME = "Rscript.exe"; 

    public WaspmoteSim() { 
     //.... 
     JButton button = new JButton("Destroy Process"); 

     Process process = Runtime.getRuntime().exec(
      System.getenv("cmd.exe /C C:\\Progra~1\\R\\R-3.2.1.\\bin\\" + YOUR_PROCESS_NAME + " + workingDir + "\\Fitter.r"); 
     ProcessHolder.getInstance().getProcesses().put(processName, p); 
     button.addActionListener(this); 
     //.... 
    } 

    //Callback: 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     ProcessHolder.getInstance().getProcesses().get(YOUR_PROCESS_NAME).destroy(); 
    } 

} 

également un avis:

Vous faites:

while(true) { 
    Process proc; 
    proc = Runtime.getRuntime().exec("cmd.exe /C C:\\Progra~1\\R\\R-3.2.1.\\bin\\Rscript.exe " + workingDir + "\\Fitter.r"); 
    TimeUnit.SECONDS.sleep(8); 
} 

Cela va tenter de lancer un nouveau processus toutes les 8 secondes (!). Pour démarrer un processus, faites-le une fois, stockez-le, puis détruisez-le au besoin en utilisant destroy, à moins que votre cible ne soit de créer de nouveaux processus comme celui-ci, en effet.

+0

Je suis encore avoir quelques problèmes pour implémenter votre exemple; Java indique que la méthode abstraite Process a besoin d'une liste vide pour être instanciée, pas d'une chaîne (qui est le nom du processus que j'essaie de créer). Est-ce que je fais quelque chose d'autre? – Martin

+0

Réponse mise à jour, vous le faites, vous utilisez 'Runtime.getRuntime(). Exec (....)' pour le créer. –

+0

Merci; Je serai de retour à la maison dans une heure ou deux et l'essayerai alors. Merci beaucoup pour votre temps! – Martin

0

d'abord définir une nouvelle variable booléenne isClosed dans votre JFrame ajouter un gros auditeur à votre JFrame et définir une variable booléenne true

addWindowListener(new WindowAdapter() 
{ 
    public void windowClosing(WindowEvent e) 
    { 
     isClosed = true; 
    } 
}); 

changer maintenant votre while(true) à while(!isClosed)