Amrmsmb
Amrmsmb

Reputation: 1

How to reference button listener in a while loop?

In my Java code I have a while loop as shown below. I want when the end of file is reached or the pause button in the GUI is pressed, the while loop exits. How can I link the button listener from the GUI to the while loop?

Note: in the below code, the this.isPausePressed is a flag inside the pause button listener which is true if the pause button is pressed and false otherwise

code:

while ( ((line = this.logFileBuffer.readLine()) != null) && (!this.isPausePressed) ) {
    statusarea.append(Log.d(TAG, "parseTimeStamp", "isPauseButtonPressed: " + this.isPausePressed) + "\n");
    String timeStamp = line.split(this.VALUE_SEPARATOR)[0];
    Thread timeStampThread = new Thread(new TimeStampTimerThread(++this.markCounter, timeStamp), "TimeStampThread_" + this.markCounter);
    timeStampThread.start();
    this.setLastFileMarker(this.markCounter);
}

Update_1

i created three threads, each controls one of the GUI buttons with actionListener(play, pause and stop). and inside each respective buttonListener i set the according flags on/off and however the problem still exists.

please see the updated code posted below. the problem is when i click pause, the debugging statement , in onPause() method, always show that the getLastFileMarker() method reached its maximum. wich means, when the pause button is clicked and its flage isPausePressed set to true, the while-loop does not exit.

note:setLastFileMarker() is set inside the wile-loop in the ParseTimeStamp() method. all these methods are posted. kindly have alook at it

createGUI {
this.playButtonThread = new Thread(this.playButtonRunnable, "playButtonThread");
    this.pauseButtonThread = new Thread(this.pauseButtonRunnable, "pauseButtonThread");
    this.stopButtonThread = new Thread(this.stopButtonRunnable, "stopButtonThread");

    this.playButtonThread.start();
    this.pauseButtonThread.start();
    this.stopButtonThread.start();
  }//CreateGui

 Runnable playButtonRunnable = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        playButtonListener();
    }
};

Runnable pauseButtonRunnable = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        pauseButtonListener();
    }
};

Runnable stopButtonRunnable = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        stopButtonListener();
    }
};

protected void playButtonListener() {
    // TODO Auto-generated method stub
    Bplay.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPausePressed) {
                isPlayPressed = true;
                isPausePressed = false;
                continueReading();
            }else if (!isPlayPressed) {
                isPlayPressed = true;
                try {
                    onPlay();
                } catch (IOException
                        | InterruptedException | MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });
}

protected void pauseButtonListener() {
    // TODO Auto-generated method stub
    Bpause.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPlayPressed) {
                isPlayPressed = false;
                isPausePressed = true;
                try {
                    onPause();
                } catch (IOException | MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });
}

protected void stopButtonListener() {
    // TODO Auto-generated method stub
    Bstop.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPlayPressed) {
                isStopPressed = true;
                try {
                    onStop();
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });
}

    protected void continueReading() {
    // TODO Auto-generated method stub

}

  private void onPause() throws IOException, MqttException {
    // TODO Auto-generated method stub
    statusarea.append(Log.w(TAG, "onPause", "onPause() is called") + "\n");

    if (!this.logFileBuffer.markSupported()) {
        statusarea.append(Log.w(TAG, "onPause", "stream does not support .mark() and .reset()   
    operations.") + "\n");
    }else {
        this.logFileBuffer.mark(this.getLastFileMarker());
        statusarea.append(Log.i(TAG, "onPause", "last mark set in line#: " + 
  this.getLastFileMarker()) + "\n");
        this.timer.cancel();
        //this.getClient().disconnect();
    }
    simulationarea.append(Log.w(TAG, "onPause", "PAUSE") + "\n");
}

ParseTimeStamp method:

 while ( ((line = this.logFileBuffer.readLine()) != null) && (!isPausePressed) ) {
                statusarea.append(Log.d(TAG, "parseTimeStamp", "isPauseButtonPressed: " +   
 isPausePressed) + "\n");
                String timeStamp = line.split(this.VALUE_SEPARATOR)[0];
                Thread timeStampThread = new Thread(new TimeStampTimerThread(++this.markCounter,   
 timeStamp), "TimeStampThread_" + this.markCounter);
                timeStampThread.start();
                this.setLastFileMarker(this.markCounter);
            }

Update_2:

I deleted the three threads control the GUI buttons as suggested. and just implemented their listeners as shown below. the onPlay() method, shown above in update_1, calls the parseTimeStamp() which has the 'while-loop ', also posted above in update_1. at run time, when pause button is clicked the while-loop does not exit.

Code

Bplay.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPausePressed) {
                isPlayPressed = true;
                isPausePressed = false;
                continueReading();
            }else if (!isPlayPressed) {
                isPlayPressed = true;
                try {
                    onPlay();
                } catch (IOException
                        | InterruptedException | MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });

    Bpause.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPlayPressed) {
                isPlayPressed = false;
                isPausePressed = true;
                try {
                    onPause();
                } catch (IOException | MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });

    Bstop.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            if (isPlayPressed) {
                isStopPressed = true;
                try {
                    onStop();
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    });

Upvotes: 0

Views: 2827

Answers (1)

geert3
geert3

Reputation: 7321

You only need to set the listener once, some place before the loop is started.

At the moment you click the button, the button's click listener will be fired asynchronously (i.e. from another thread as your loop code, a.k.a. the event dispatch thread). So the loop will suddenly "see" the changed value for isPausePressed and quit, just like that.

This implies that you should not do these kind of loops from inside the "event dispatch thread" as this would prevent loop and event to happen in parallel. See this document (and sub-documents) for more info on the "event dispatch thread" and concurrency in Swing in general.

update:

For an example, see below. Note that there's no need for any thread creation or other strange stuff. Swing automatically starts the notorious Event Dispatch Thread for you, and all event related code will automatically run inside that thread. This way, your main loop code will happily run in parallel with the actionListener's actionPerformed method (as soon as you click the button). So the isPausePressed flag will change seemingly during execution of your While loop. It's really that simple.

    private boolean isPausePressed = false;

    JButton b = new JButton("Pause!");
    b.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            isPausePressed = true;
        }
    });

    // ....

    while (!isPausePressed)
    {
        // do some work
    }

Upvotes: 2

Related Questions