// when the "Start/Pause/Continue/Restart" button is pressed...
  void onStart()
  {
    switch (m_state) {

      case WaitingToWork:
      case Paused: {
	m_state = Working;
	m_start.setText("Pause"); // convert the button to "Pause"...

	// this is "The Loop", where the real work is done
	do {
	  // when we pump the message queue, we can get events like onClose()
	  Thread::pumpMessageQueue();

	  // work done
	  if (m_progressBar1.getValue() == m_progressBar1.getMaximum()) {
	    m_state = WorkDone;
	    m_start.setText("Restart"); // convert the button to "Restart"
	  }
	  else {
	    m_progressBar1.addValue(1);
	    m_progressBar2.addValue(1);

	    // in our case, the "real work" is sleep :) ...but for
	    // your application this could be "loading a file"...
	    Sleep(10);
	  }

	  // still working?
	} while (m_state == Working);
	// aborting work? hide the frame...
	if (m_state == Aborting)
	  setVisible(false);
	break;
      }

      case Working:
	m_state = Paused;
	m_start.setText("Continue"); // convert the button to "Continue"
	break;

      // the work is done? the user press the "Restart" button
      case WorkDone:
	// restart progress bars
	m_progressBar1.setValue(m_progressBar1.getMinimum());
	m_progressBar2.setValue(m_progressBar2.getMinimum());
	m_start.setText("Start"); // convert the button to "Start"
	m_state = WaitingToWork;
	break;

      case Aborting:
	assert(false);		// impossible
	break;
    }
  }