1

I've been trying several approaches to write a small program that allows a user to run one of three functions depending on the button they click. The code for the main program looks as follows:

public class WaspmoteSim extends JFrame implements ActionListener {
public WaspmoteSim() {
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    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);
    setFocusable(true);
}
public static void main(String[] args) {

}

@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);
        }
    }
    //else {ProcessHolder.getInstance().getProcesses().get(YOUR_PROCESS_NAME).destroy();}
}

and the function that the third button needs to call (the one which I would like to be able to interrupt) looks as follows:

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

The code for IsKeyPressed comes directly from How do I check if the user is pressing a key?.

However, when running the third function and pressing/holding the E key, the program simply continues looping. What am I doing wrong?

Community
  • 1
  • 1
Martin
  • 277
  • 2
  • 5
  • 17

1 Answers1

1

You are starting an endless loop inside the Swing event dispatching thread. This means your actionPerformed method never ends. This means Swing is blocked and cannot handle any new button clicks or any other type of event.

Use a SwingWorker to fire up your OperationsMethod(). And use a shared and synchronized variable to share the button state between your Swing class and the SwingWorker.

BetaRide
  • 16,207
  • 29
  • 99
  • 177