简体   繁体   English

在按下按钮之前,如何在Java中运行进程?

[英]How do I run a process in Java until a button is pressed?

I'm writing a small program that runs one of three samples of code depending on which button is pressed. 我正在编写一个小程序,该程序根据所按下的按钮运行三个代码示例之一。 With the third button, a sample of code should run until the JFrame is closed, or until a button is pressed (I don't really mind how it's stopped, just as long as the user has a method of stopping the loop). 使用第三个按钮,应该运行示例代码,直到关闭JFrame或按下按钮为止(我不介意如何停止它,只要用户有停止循环的方法即可)。 The code is run, and a delay of 8 seconds is added to ensure the code finished running before it loops. 代码将运行,并且添加了8秒的延迟以确保代码在循环之前完成运行。

How do I implement this? 我该如何实施? The program doesn't seem to terminate when looping, even when I try to close it by clicking the close button in the JFrame. 该程序似乎在循环时不会终止,即使我尝试通过单击JFrame中的关闭按钮将其关闭。

The main part of the program looks as follows: 该程序的主要部分如下所示:

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);
        }
    }
}

The code that I want to run on a loop looks like this: 我要在循环上运行的代码如下所示:

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);
        }
    }

The procedure you can follow is this: 您可以遵循的过程是这样的:

1) Create a Process using ProcessBuilder and store it for later use (You can use a holder singleton class "ProcessHolder" for this). 1)使用ProcessBuilder创建一个Process并将其存储以备后用(您可以为此使用持有人单例类“ ProcessHolder”)。

2) Register an event function to your button that takes You register an event function to your button that has access to the ProcessHolder , and terminates the process using destroy() method. 2)在您的按钮上注册一个事件函数,然后将其注册到可以访问ProcessHolder按钮上,并使用destroy()方法终止该过程。

Check for more 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();
    }

}

Also a notice: 还要注意:

You are doing: 您正在执行:

 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);
 }

This will attempt to start a new process every 8 seconds (!). 这将尝试每8秒(!)启动一个新进程。 In order to start a process, do it once, store it, then kill it when needed using destroy, unless your target is to create new processes like this, indeed. 为了启动一个进程,只需执行一次,存储一次,然后在需要时使用destroy销毁它,除非您的目标确实是创建这样的新进程。

first define a new boolean variable isClosed in your JFrame add a close-listener to your JFrame and set a boolean variable to true 首先定义一个新的布尔变量isClosedJFrame添加关闭监听到你JFrame和一个布尔变量设置为true

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

now change your while(true) to while(!isClosed) 现在将您的while(true)更改为while(!isClosed)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM