-1

I have a Java method which, when called, will listen for any traffic being sent across the network, and print information about that traffic to the console. My program currently runs in the console, but I am now looking at creating a graphical user interface to allow the user to interact with the program.

Currently, when I run my program, it continually prints statements about the network traffic to the console for as long as it is running, and the only way I have to stop it running is by clicking the 'terminate' button in the Eclipse console window.

However, with the graphical user interface that I am making, I have a 'start' button, which the user can click to begin listening for any traffic on the network- but once it starts listening, I have no way of allowing the user to stop it via the GUI.

Since there will always be information being sent over the network, I cannot wait until no information is being received to stop the call- what I would like to do is add a 'stop' button that will stop the call to the method (i.e. stop my program from listening for network traffic), but I don't know what method I need to write/ call to stop the first method from listening.

For my 'start' button, I have an ActionListener that listens for a click on the button, and calls the method from another class when it hears one. I can create a 'stop' button, but what I don't know is what method to call when the ActionListener hears a click on it, to stop the first method from being called.

Anyone have any suggestions?

Edit 28/04/2014 @ 14:15

This is the code that I am using to create the 'stop' button:

JButton stopCaptureButton = new JButton("Stop");
panel.add(stopCaptureButton);
stopCaptureButton.setBounds(875, 350, 80, 30);

stopCaptureButton.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e){
        EspduReceiver.stopCapture = true;
        pool.shutdown();
    }
});

But for some reason, absolutely nothing happens when I click it...

The method that I am using to capture the network information is called receivePdu(), at the start of this method, I have the condition while(true){..., then all of the code for capturing the information that's being sent over the network.

At the end of the receivePdu() method, I have the following code:

Boolean queryStopCapture = stopCapture;
if(queryStopCapture == true){
    break;
}

The variable stopCapture is a global variable, defined in the same class as the receivePdu() method with the line public static Boolean stopCapture = false;'

As you can see, I am setting the value of stopCapture to true when a click is detected on my stopCaptureButton, which should trigger the break; at the end of my receivePdu() method, but it doesn't seem to be doing that.

Any ideas why? Or what I'm doing wrong?

Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118

3 Answers3

0

You need to put this task into an ExecutorService and then call shutdown in your ActionListener for stop.

// this could be cachedThreadPool or whatever
ExecutorService pool = Executors.newSingleThreadExecutor();

ActionListener start = new ActionListener(){

    public void actionPerformed(ActionEvent e) {
        pool.execute(new Runnable(){
            public void run(){
                checkTraffic();
            }
        });
    }
};

ActionListener stop = new ActionListener(){

    public void actionPerformed(ActionEvent e) {
        pool.shutdown();
    }
};

you could put in checks or whatever to make sure that execute is only called once.

Robert
  • 8,406
  • 9
  • 38
  • 57
  • Hey, thanks for your answer. I've tried giving the code you suggested a go, and although I can now click the buttons on the windows while the capture is running, my 'stop' button does not have any effect... do I need to add a call to another function to it? – Noble-Surfer Apr 28 '14 at 11:58
0

You can invert the control in the loop that checks the traffic :

while(true) {
  checkTraffic();
  Thread.sleep(1000);
}

You can add a control :

while(true) {
  checkTraffic();
  boolean shouldIStop = lookAVariableSomewhere(); //File or database
  if(shouldIStop) {
    break;
  }
  Thread.sleep(1000);
}

Then your "stop" button updates this variable.

Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • Hey, thanks for your answer- that definitely seems like it is what I want to do, and I've tried giving it a go, but I'm having some trouble: when I click 'run' on the Gui.java class, and my window opens up, once I click the 'start' button to start the capture (the traffic being captured is displayed in the console as it was previously), I am then unable to click any of the other buttons on the window (Stop- which is setting the value of the `shouldIStop` variable to true, or quit). The window becomes non-responsive, and I have to stop the method call using the 'terminate' button in the console – Noble-Surfer Apr 28 '14 at 11:21
  • Should I try putting the `shouldIStop` variable inside the brackets at the start of the while loop instead of `true`? I.e. `while(shouldIStop == true){...` – Noble-Surfer Apr 28 '14 at 11:26
  • Well my last idea doesn't work- if I do that, then run my code, for some reason the whole of Windows crashes... – Noble-Surfer Apr 28 '14 at 11:40
  • @someone2088 it is because of the infinite loop witout tempo. You should add a `Thread.sleep(1000)` for example. I edited the answer. – Arnaud Denoyelle Apr 28 '14 at 11:42
  • So I tried adding the `Thread.sleep(1000);` line that you suggested, and that makes the program 'pause' for a second between each set of prints in the console- which is what it should do, but the 'stop' button that I've added to my GUI still doesn't do anything... – Noble-Surfer Apr 28 '14 at 13:09
0

It seems the problem was that I had an infinite loop which meant that the break; statement was never called.

Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118