2424import java .awt .AWTException ;
2525import java .awt .BorderLayout ;
2626import java .awt .Dimension ;
27+ import java .awt .Font ;
2728import java .awt .GraphicsConfiguration ;
2829import java .awt .GraphicsDevice ;
2930import java .awt .GraphicsEnvironment ;
@@ -187,7 +188,7 @@ public final class PassFailJFrame {
187188
188189 private static final CountDownLatch latch = new CountDownLatch (1 );
189190
190- private static TimeoutHandler timeoutHandler ;
191+ private static TimeoutHandlerPanel timeoutHandlerPanel ;
191192
192193 /**
193194 * The description of why the test fails.
@@ -424,10 +425,8 @@ private static JComponent createInstructionUIPanel(String instructions,
424425 int rows , int columns ,
425426 boolean enableScreenCapture ) {
426427 JPanel main = new JPanel (new BorderLayout ());
427-
428- JLabel testTimeoutLabel = new JLabel ("" , JLabel .CENTER );
429- timeoutHandler = new TimeoutHandler (testTimeoutLabel , testTimeOut );
430- main .add (testTimeoutLabel , BorderLayout .NORTH );
428+ timeoutHandlerPanel = new TimeoutHandlerPanel (testTimeOut );
429+ main .add (timeoutHandlerPanel , BorderLayout .NORTH );
431430
432431 JTextComponent text = instructions .startsWith ("<html>" )
433432 ? configureHTML (instructions , rows , columns )
@@ -439,13 +438,13 @@ private static JComponent createInstructionUIPanel(String instructions,
439438 JButton btnPass = new JButton ("Pass" );
440439 btnPass .addActionListener ((e ) -> {
441440 latch .countDown ();
442- timeoutHandler .stop ();
441+ timeoutHandlerPanel .stop ();
443442 });
444443
445444 JButton btnFail = new JButton ("Fail" );
446445 btnFail .addActionListener ((e ) -> {
447446 requestFailureReason ();
448- timeoutHandler .stop ();
447+ timeoutHandlerPanel .stop ();
449448 });
450449
451450 JPanel buttonsPanel = new JPanel ();
@@ -603,17 +602,35 @@ public interface InstructionUI {
603602 }
604603
605604
606- private static final class TimeoutHandler implements ActionListener {
607- private final long endTime ;
605+ private static final class TimeoutHandlerPanel
606+ extends JPanel
607+ implements ActionListener {
608+
609+ private static final String PAUSE_BUTTON_LABEL = "Pause" ;
610+ private static final String RESUME_BUTTON_LABEL = "Resume" ;
611+
612+ private long endTime ;
613+ private long pauseTimeLeft ;
608614
609615 private final Timer timer ;
610616
611617 private final JLabel label ;
618+ private final JButton button ;
612619
613- public TimeoutHandler (final JLabel label , final long testTimeOut ) {
614- endTime = System .currentTimeMillis () + TimeUnit .MINUTES .toMillis (testTimeOut );
620+ public TimeoutHandlerPanel (final long testTimeOut ) {
621+ endTime = System .currentTimeMillis ()
622+ + TimeUnit .MINUTES .toMillis (testTimeOut );
615623
616- this .label = label ;
624+ label = new JLabel ("" , JLabel .CENTER );
625+ button = new JButton (PAUSE_BUTTON_LABEL );
626+
627+ button .setFocusPainted (false );
628+ button .setFont (new Font (Font .DIALOG , Font .BOLD , 10 ));
629+ button .addActionListener (e -> pauseToggle ());
630+
631+ setLayout (new BorderLayout ());
632+ add (label , BorderLayout .CENTER );
633+ add (button , BorderLayout .EAST );
617634
618635 timer = new Timer (1000 , this );
619636 timer .start ();
@@ -645,6 +662,22 @@ private void updateTime(final long leftTime) {
645662 hours , minutes , seconds ));
646663 }
647664
665+
666+ private void pauseToggle () {
667+ if (timer .isRunning ()) {
668+ pauseTimeLeft = endTime - System .currentTimeMillis ();
669+ timer .stop ();
670+ label .setEnabled (false );
671+ button .setText (RESUME_BUTTON_LABEL );
672+ } else {
673+ endTime = System .currentTimeMillis () + pauseTimeLeft ;
674+ updateTime (pauseTimeLeft );
675+ timer .start ();
676+ label .setEnabled (true );
677+ button .setText (PAUSE_BUTTON_LABEL );
678+ }
679+ }
680+
648681 public void stop () {
649682 timer .stop ();
650683 }
0 commit comments