test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java
changeset 54505 7f53d59593e2
parent 53936 03163eb3b2d4
child 57930 020f8fab32e2
equal deleted inserted replaced
54504:55b0469425e1 54505:7f53d59593e2
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /**
    24 /*
    25  * @test
    25  * @test
    26  * @bug 8153732 8212202
    26  * @bug 8153732 8212202 8221263 8221412
    27  * @requires (os.family == "Windows")
    27  * @requires (os.family == "Windows")
    28  * @summary Windows remote printer changes do not reflect in lookupPrintServices()
    28  * @summary Windows remote printer changes do not reflect in lookupPrintServices()
    29  * @ignore Requires a new network printer installation\removal
       
    30  * @run main/manual RemotePrinterStatusRefresh
    29  * @run main/manual RemotePrinterStatusRefresh
    31  */
    30  */
    32 
    31 
    33 import java.awt.GridBagConstraints;
    32 import java.awt.BorderLayout;
    34 import java.awt.GridBagLayout;
    33 import java.awt.Color;
       
    34 import java.awt.Component;
       
    35 import java.awt.GridLayout;
    35 import java.awt.event.ActionEvent;
    36 import java.awt.event.ActionEvent;
    36 import java.awt.print.PageFormat;
    37 import java.awt.event.WindowAdapter;
    37 import java.awt.print.Paper;
    38 import java.awt.event.WindowEvent;
    38 import java.awt.print.PrinterException;
    39 import java.util.ArrayList;
       
    40 import java.util.Collections;
       
    41 import java.util.List;
    39 import java.util.concurrent.CountDownLatch;
    42 import java.util.concurrent.CountDownLatch;
    40 import java.util.concurrent.TimeUnit;
    43 import javax.print.PrintService;
       
    44 import javax.print.PrintServiceLookup;
       
    45 import javax.swing.AbstractListModel;
    41 import javax.swing.BorderFactory;
    46 import javax.swing.BorderFactory;
    42 import javax.swing.Box;
    47 import javax.swing.Box;
       
    48 import javax.swing.BoxLayout;
       
    49 import javax.swing.DefaultListCellRenderer;
       
    50 import javax.swing.GroupLayout;
    43 import javax.swing.JButton;
    51 import javax.swing.JButton;
    44 import javax.swing.JFrame;
    52 import javax.swing.JFrame;
    45 import javax.swing.JLabel;
    53 import javax.swing.JLabel;
       
    54 import javax.swing.JList;
    46 import javax.swing.JPanel;
    55 import javax.swing.JPanel;
       
    56 import javax.swing.JScrollPane;
    47 import javax.swing.JTextArea;
    57 import javax.swing.JTextArea;
       
    58 import javax.swing.JTextField;
    48 import javax.swing.SwingUtilities;
    59 import javax.swing.SwingUtilities;
    49 import java.awt.print.PrinterJob;
    60 import javax.swing.Timer;
    50 import javax.print.PrintService;
    61 
    51 
    62 import static javax.swing.BorderFactory.createTitledBorder;
    52 public class RemotePrinterStatusRefresh
    63 
    53 {
    64 public class RemotePrinterStatusRefresh extends WindowAdapter {
    54     private static TestUI test = null;
    65 
    55     public static void main(String args[]) throws Exception {
    66     private static final long refreshTime = getRefreshTime();
    56         final CountDownLatch latch = new CountDownLatch(1);
    67 
    57 
    68     private static final long TIMEOUT = refreshTime * 4 + 60;
    58         // Test UI creation
    69 
    59         test = new TestUI(latch);
    70 
    60 
    71     private static final CountDownLatch latch = new CountDownLatch(1);
    61         SwingUtilities.invokeAndWait(new Runnable() {
    72     private static volatile RemotePrinterStatusRefresh test;
    62             @Override
    73 
    63             public void run() {
    74     private volatile boolean testResult;
    64                 try {
    75     private volatile boolean testTimedOut;
    65                     test.createUI();
    76 
    66                 } catch (Exception e) {
    77     private final JFrame frame;
    67                     throw new RuntimeException(e);
    78 
    68                 }
    79     private JButton refreshButton;
       
    80     private JButton passButton;
       
    81     private JButton failButton;
       
    82 
       
    83     private final ServiceItemListModel beforeList;
       
    84     private final ServiceItemListModel afterList;
       
    85 
       
    86     private JTextField nextRefresh;
       
    87     private JTextField timeLeft;
       
    88 
       
    89     private final Timer timer;
       
    90     private final long startTime;
       
    91 
       
    92 
       
    93     private static class ServiceItem {
       
    94         private enum State {
       
    95             REMOVED, UNCHANGED, ADDED
       
    96         }
       
    97 
       
    98         final String name;
       
    99         State state;
       
   100 
       
   101         private ServiceItem(final String name) {
       
   102             this.name = name;
       
   103             state = State.UNCHANGED;
       
   104         }
       
   105 
       
   106         @Override
       
   107         public String toString() {
       
   108             return name;
       
   109         }
       
   110 
       
   111         @Override
       
   112         public boolean equals(Object obj) {
       
   113             return (obj instanceof ServiceItem)
       
   114                     && ((ServiceItem) obj).name.equals(name);
       
   115         }
       
   116 
       
   117         @Override
       
   118         public int hashCode() {
       
   119             return name.hashCode();
       
   120         }
       
   121     }
       
   122 
       
   123     private static class ServiceItemListModel extends AbstractListModel<ServiceItem> {
       
   124         private final List<ServiceItem> list;
       
   125 
       
   126         private ServiceItemListModel(List<ServiceItem> list) {
       
   127             this.list = list;
       
   128         }
       
   129 
       
   130         @Override
       
   131         public int getSize() {
       
   132             return list.size();
       
   133         }
       
   134 
       
   135         @Override
       
   136         public ServiceItem getElementAt(int index) {
       
   137             return list.get(index);
       
   138         }
       
   139 
       
   140         private void refreshList(List<ServiceItem> newList) {
       
   141             list.clear();
       
   142             list.addAll(newList);
       
   143             fireChanged();
       
   144         }
       
   145 
       
   146         private void fireChanged() {
       
   147             fireContentsChanged(this, 0, list.size() - 1);
       
   148         }
       
   149     }
       
   150 
       
   151     private static class ServiceItemListRenderer extends DefaultListCellRenderer {
       
   152         @Override
       
   153         public Component getListCellRendererComponent(JList<?> list,
       
   154                                                       Object value,
       
   155                                                       int index,
       
   156                                                       boolean isSelected,
       
   157                                                       boolean cellHasFocus) {
       
   158             Component component =
       
   159                     super.getListCellRendererComponent(list, value, index,
       
   160                                                        isSelected, cellHasFocus);
       
   161             switch (((ServiceItem) value).state) {
       
   162                 case REMOVED:
       
   163                     component.setBackground(Color.RED);
       
   164                     component.setForeground(Color.WHITE);
       
   165                     break;
       
   166                 case ADDED:
       
   167                     component.setBackground(Color.GREEN);
       
   168                     component.setForeground(Color.BLACK);
       
   169                     break;
       
   170                 case UNCHANGED:
       
   171                 default:
       
   172                     break;
    69             }
   173             }
    70         });
   174             return component;
    71 
   175         }
    72         // RemotePrinterStatusRefresh creation
   176     }
    73         RemotePrinterStatusRefresh RemotePrinterStatusRefresh = new RemotePrinterStatusRefresh();
   177 
    74         SwingUtilities.invokeAndWait(() -> {
   178     private static final String INSTRUCTIONS_TEXT =
    75             collectPrintersList(test.resultsTextArea, true);
   179             "Please follow the steps for this manual test:\n"
    76         });
   180                     + "Step 0: \"Before\" list is populated with currently "
    77 
   181                     +          "configured printers.\n"
    78         // 8 min = 480000 msec
   182                     + "Step 1: Add or Remove a network printer using "
    79         if(waitForFlag(480000)) {
   183                     +          "Windows Control Panel.\n"
    80             SwingUtilities.invokeAndWait(() -> {
   184                     + "Step 2: Wait for 4 minutes after adding or removing.\n"
    81                 collectPrintersList(test.resultsTextArea, false);
   185                     + "             \"Next printer refresh in\" gives you a "
    82             });
   186                     +          "rough estimation on when update will happen.\n"
    83         } else {
   187                     + "Step 3: Click Refresh."
    84             dispose();
   188                     +          "\"After\" list is populated with updated list "
    85             throw new RuntimeException("No new network printer got added/removed!! Test timed out!!");
   189                     +          "of printers.\n"
    86         }
   190                     + "Step 4: Compare the list of printers in \"Before\" and "
    87 
   191                     +          "\"After\" lists.\n"
    88         boolean status = latch.await(1, TimeUnit.MINUTES);
   192                     + "              Added printers are highlighted with "
    89         if (!status) {
   193                     +               "green color, removed ones \u2014 with "
    90             dispose();
   194                     +               "red color.\n"
    91             throw new RuntimeException("Test timed out.");
   195                     + "Step 5: Click Pass if the list of printers is correctly "
    92         }
   196                     +          "updated.\n"
    93 
   197                     + "Step 6: If the list is not updated, wait for another "
    94         if (test.testResult == false) {
   198                     +          "4 minutes, and then click Refresh again.\n"
    95             dispose();
   199                     + "Step 7: If the list does not update, click Fail.\n"
    96             throw new RuntimeException("Test Failed.");
   200                     + "\n"
    97         }
   201                     + "You have to click Refresh to enable Pass and Fail buttons. "
    98 
   202                     + "If no button is pressed,\n"
    99         dispose();
   203                     + "the test will time out. "
   100     }
   204                     + "Closing the window also fails the test.";
   101 
   205 
   102     public static void dispose() throws Exception {
   206     public static void main(String[] args) throws Exception {
   103         SwingUtilities.invokeAndWait(() -> {
   207         SwingUtilities.invokeAndWait(RemotePrinterStatusRefresh::createUI);
   104             test.disposeUI();
   208 
   105         });
   209         latch.await();
   106     }
   210         if (!test.testResult) {
   107 
   211             throw new RuntimeException("Test failed"
   108     public static boolean waitForFlag (long maxTimeoutInMsec) throws Exception {
   212                 + (test.testTimedOut ? " because of time out" : ""));
   109         while(!test.isAdded && maxTimeoutInMsec > 0) {
   213         }
   110             maxTimeoutInMsec -= 100;
   214     }
   111             Thread.sleep(100);
   215 
   112         }
   216     private static long getRefreshTime() {
   113 
   217         String refreshTime =
   114         if(maxTimeoutInMsec <= 0) {
   218                 System.getProperty("sun.java2d.print.minRefreshTime", "240");
   115             return false;
   219         try {
   116         } else {
   220             long value = Long.parseLong(refreshTime);
   117             return true;
   221             return value < 240L ? 240L : value;
   118         }
   222         } catch (NumberFormatException e) {
   119     }
   223             return 240L;
   120 
   224         }
   121     private static void collectPrintersList(JTextArea textArea, boolean before) {
   225     }
   122         if(before) {
   226 
   123             System.out.println("List of printers(before): ");
   227     private static void createUI() {
   124             textArea.setText("List of printers(before): \n");
   228         test = new RemotePrinterStatusRefresh();
   125             for (PrintService printServiceBefore : PrinterJob.lookupPrintServices()) {
   229     }
   126                 System.out.println(printServiceBefore);
   230 
   127                 textArea.append(printServiceBefore.toString());
   231     private RemotePrinterStatusRefresh() {
   128                 textArea.append("\n");
   232         frame = new JFrame("RemotePrinterStatusRefresh");
       
   233         frame.addWindowListener(this);
       
   234 
       
   235 
       
   236         JPanel northPanel = new JPanel(new BorderLayout());
       
   237         northPanel.add(createInfoPanel(), BorderLayout.NORTH);
       
   238         northPanel.add(createInstructionsPanel(), BorderLayout.SOUTH);
       
   239 
       
   240 
       
   241         beforeList = new ServiceItemListModel(
       
   242                 Collections.unmodifiableList(collectPrinterList()));
       
   243         afterList = new ServiceItemListModel(new ArrayList<>());
       
   244         logList("Before:", beforeList.list);
       
   245 
       
   246         JPanel listPanel = new JPanel(new GridLayout(1, 2));
       
   247         listPanel.setBorder(createTitledBorder("Print Services"));
       
   248         listPanel.add(createListPanel(beforeList, "Before:", 'b'));
       
   249         listPanel.add(createListPanel(afterList, "After:", 'a'));
       
   250 
       
   251 
       
   252         JPanel mainPanel = new JPanel(new BorderLayout());
       
   253         mainPanel.add(northPanel, BorderLayout.NORTH);
       
   254         mainPanel.add(listPanel, BorderLayout.CENTER);
       
   255         mainPanel.add(createButtonPanel(), BorderLayout.SOUTH);
       
   256 
       
   257 
       
   258         frame.add(mainPanel);
       
   259         frame.pack();
       
   260         refreshButton.requestFocusInWindow();
       
   261         frame.setVisible(true);
       
   262 
       
   263 
       
   264         timer = new Timer(1000, this::updateTimeLeft);
       
   265         timer.start();
       
   266         startTime = System.currentTimeMillis();
       
   267         updateTimeLeft(null);
       
   268     }
       
   269 
       
   270     private JPanel createInfoPanel() {
       
   271         JLabel javaLabel = new JLabel("Java version:");
       
   272         JTextField javaVersion =
       
   273                 new JTextField(System.getProperty("java.runtime.version"));
       
   274         javaVersion.setEditable(false);
       
   275         javaLabel.setLabelFor(javaVersion);
       
   276 
       
   277         JLabel refreshTimeLabel = new JLabel("Refresh interval:");
       
   278         long minutes = refreshTime / 60;
       
   279         long seconds = refreshTime % 60;
       
   280         String interval = String.format("%1$d seconds%2$s",
       
   281                 refreshTime,
       
   282                 minutes > 0
       
   283                     ? String.format(" (%1$d %2$s%3$s)",
       
   284                         minutes,
       
   285                         minutes > 1 ? "minutes" : "minute",
       
   286                         seconds > 0
       
   287                             ? String.format(" %1$d %2$s",
       
   288                                 seconds,
       
   289                                 seconds > 1 ? "seconds" : "second")
       
   290                             : "")
       
   291                     : ""
       
   292         );
       
   293         JTextField refreshInterval = new JTextField(interval);
       
   294         refreshInterval.setEditable(false);
       
   295         refreshTimeLabel.setLabelFor(refreshInterval);
       
   296 
       
   297         JLabel nextRefreshLabel = new JLabel("Next printer refresh in:");
       
   298         nextRefresh = new JTextField();
       
   299         nextRefresh.setEditable(false);
       
   300         nextRefreshLabel.setLabelFor(nextRefresh);
       
   301 
       
   302         JLabel timeoutLabel = new JLabel("Time left:");
       
   303         timeLeft = new JTextField();
       
   304         timeLeft.setEditable(false);
       
   305         timeoutLabel.setLabelFor(timeLeft);
       
   306 
       
   307         JPanel infoPanel = new JPanel();
       
   308         GroupLayout layout = new GroupLayout(infoPanel);
       
   309         infoPanel.setLayout(layout);
       
   310         infoPanel.setBorder(BorderFactory.createTitledBorder("Info"));
       
   311         layout.setAutoCreateGaps(true);
       
   312         layout.setHorizontalGroup(
       
   313             layout.createSequentialGroup()
       
   314                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
       
   315                     .addComponent(javaLabel)
       
   316                     .addComponent(refreshTimeLabel)
       
   317                     .addComponent(nextRefreshLabel)
       
   318                     .addComponent(timeoutLabel)
       
   319                 )
       
   320                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, true)
       
   321                     .addComponent(javaVersion)
       
   322                     .addComponent(refreshInterval)
       
   323                     .addComponent(nextRefresh)
       
   324                     .addComponent(timeLeft)
       
   325                 )
       
   326         );
       
   327         layout.setVerticalGroup(
       
   328             layout.createSequentialGroup()
       
   329                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
       
   330                     .addComponent(javaLabel)
       
   331                     .addComponent(javaVersion)
       
   332                 )
       
   333                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
       
   334                     .addComponent(refreshTimeLabel)
       
   335                     .addComponent(refreshInterval))
       
   336                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
       
   337                     .addComponent(nextRefreshLabel)
       
   338                     .addComponent(nextRefresh))
       
   339                 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
       
   340                     .addComponent(timeoutLabel)
       
   341                     .addComponent(timeLeft))
       
   342         );
       
   343         return infoPanel;
       
   344     }
       
   345 
       
   346     private JPanel createInstructionsPanel() {
       
   347         JPanel instructionsPanel = new JPanel(new BorderLayout());
       
   348         JTextArea instructionText = new JTextArea(INSTRUCTIONS_TEXT);
       
   349         instructionText.setEditable(false);
       
   350         instructionsPanel.setBorder(createTitledBorder("Test Instructions"));
       
   351         instructionsPanel.add(new JScrollPane(instructionText));
       
   352         return  instructionsPanel;
       
   353     }
       
   354 
       
   355     private JPanel createListPanel(final ServiceItemListModel model,
       
   356                                    final String title,
       
   357                                    final char mnemonic) {
       
   358         JPanel panel = new JPanel();
       
   359         panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
       
   360         JList<ServiceItem> list = new JList<>(model);
       
   361         list.setCellRenderer(new ServiceItemListRenderer());
       
   362 
       
   363         JLabel label = new JLabel(title);
       
   364         label.setLabelFor(list);
       
   365         label.setDisplayedMnemonic(mnemonic);
       
   366         JPanel labelPanel = new JPanel();
       
   367         labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.X_AXIS));
       
   368         labelPanel.add(label, BorderLayout.EAST);
       
   369         labelPanel.add(Box.createHorizontalGlue());
       
   370 
       
   371         panel.add(labelPanel);
       
   372         panel.add(new JScrollPane(list));
       
   373         return panel;
       
   374     }
       
   375 
       
   376     private JPanel createButtonPanel() {
       
   377         refreshButton = new JButton("Refresh");
       
   378         refreshButton.addActionListener(this::refresh);
       
   379 
       
   380         passButton = new JButton("Pass");
       
   381         passButton.addActionListener(this::pass);
       
   382         passButton.setEnabled(false);
       
   383 
       
   384         failButton = new JButton("Fail");
       
   385         failButton.addActionListener(this::fail);
       
   386         failButton.setEnabled(false);
       
   387 
       
   388         JPanel buttonPanel = new JPanel();
       
   389         buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
       
   390         buttonPanel.add(Box.createHorizontalGlue());
       
   391         buttonPanel.add(refreshButton);
       
   392         buttonPanel.add(passButton);
       
   393         buttonPanel.add(failButton);
       
   394         buttonPanel.add(Box.createHorizontalGlue());
       
   395         return buttonPanel;
       
   396     }
       
   397 
       
   398     private static List<ServiceItem> collectPrinterList() {
       
   399         PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
       
   400         List<ServiceItem> list = new ArrayList<>(printServices.length);
       
   401         for (PrintService service : printServices) {
       
   402             list.add(new ServiceItem(service.getName()));
       
   403         }
       
   404         return list;
       
   405     }
       
   406 
       
   407     private static void logList(final String title, final List<ServiceItem> list) {
       
   408         System.out.println(title);
       
   409         for (ServiceItem item : list) {
       
   410             System.out.println(item.name);
       
   411         }
       
   412         System.out.println();
       
   413     }
       
   414 
       
   415     private static void compareLists(final ServiceItemListModel before, final ServiceItemListModel after) {
       
   416         boolean beforeUpdated = false;
       
   417         boolean afterUpdated = false;
       
   418 
       
   419         for (ServiceItem item : before.list) {
       
   420             if (!after.list.contains(item)) {
       
   421                 item.state = ServiceItem.State.REMOVED;
       
   422                 beforeUpdated = true;
       
   423             } else if (item.state != ServiceItem.State.UNCHANGED) {
       
   424                 item.state = ServiceItem.State.UNCHANGED;
       
   425                 beforeUpdated = true;
   129             }
   426             }
   130         } else {
   427         }
   131             textArea.append("\n");
   428 
   132             System.out.println("List of printers(after): ");
   429         for (ServiceItem item : after.list) {
   133             textArea.append("List of printers(after): \n");
   430             if (!before.list.contains(item)) {
   134             for (PrintService printServiceAfter : PrinterJob.lookupPrintServices()) {
   431                 item.state = ServiceItem.State.ADDED;
   135                 System.out.println(printServiceAfter);
   432                 afterUpdated = true;
   136                 textArea.append(printServiceAfter.toString());
   433             } else if (item.state != ServiceItem.State.UNCHANGED) {
   137                 textArea.append("\n");
   434                 item.state = ServiceItem.State.UNCHANGED;
       
   435                 afterUpdated = true;
   138             }
   436             }
   139         }
   437         }
   140     }
   438 
       
   439         if (beforeUpdated) {
       
   440             before.fireChanged();
       
   441         }
       
   442         if (afterUpdated) {
       
   443             after.fireChanged();
       
   444         }
       
   445     }
       
   446 
       
   447     @Override
       
   448     public void windowClosing(WindowEvent e) {
       
   449         System.out.println("The window closed");
       
   450         disposeUI();
       
   451     }
       
   452 
       
   453     private void disposeUI() {
       
   454         timer.stop();
       
   455         latch.countDown();
       
   456         frame.dispose();
       
   457     }
       
   458 
       
   459     @SuppressWarnings("unused")
       
   460     private void refresh(ActionEvent e) {
       
   461         System.out.println("Refresh button pressed");
       
   462         afterList.refreshList(collectPrinterList());
       
   463         compareLists(beforeList, afterList);
       
   464         passButton.setEnabled(true);
       
   465         failButton.setEnabled(true);
       
   466         logList("After:", afterList.list);
       
   467     }
       
   468 
       
   469     @SuppressWarnings("unused")
       
   470     private void pass(ActionEvent e) {
       
   471         System.out.println("Pass button pressed");
       
   472         testResult = true;
       
   473         disposeUI();
       
   474     }
       
   475 
       
   476     @SuppressWarnings("unused")
       
   477     private void fail(ActionEvent e) {
       
   478         System.out.println("Fail button pressed");
       
   479         testResult = false;
       
   480         disposeUI();
       
   481     }
       
   482 
       
   483     @SuppressWarnings("unused")
       
   484     private void updateTimeLeft(ActionEvent e) {
       
   485         long elapsed = (System.currentTimeMillis() - startTime) / 1000;
       
   486         long left = TIMEOUT - elapsed;
       
   487         if (left < 0) {
       
   488             testTimedOut = true;
       
   489             disposeUI();
       
   490         }
       
   491         timeLeft.setText(formatTime(left));
       
   492         nextRefresh.setText(formatTime(refreshTime - (elapsed % refreshTime)));
       
   493     }
       
   494 
       
   495     private static String formatTime(final long seconds) {
       
   496         long minutes = seconds / 60;
       
   497         return String.format("%d:%02d", minutes, seconds - minutes * 60);
       
   498     }
       
   499 
   141 }
   500 }
   142 
       
   143 class TestUI {
       
   144     private static JFrame mainFrame;
       
   145     private static JPanel mainControlPanel;
       
   146 
       
   147     private static JTextArea instructionTextArea;
       
   148 
       
   149     private static JPanel resultButtonPanel;
       
   150     private static JButton passButton;
       
   151     private static JButton failButton;
       
   152     private static JButton addedButton;
       
   153 
       
   154     private static JPanel testPanel;
       
   155     private static JButton testButton;
       
   156     private static JLabel buttonPressCountLabel;
       
   157 
       
   158     private static GridBagLayout layout;
       
   159     private final CountDownLatch latch;
       
   160     public boolean testResult = false;
       
   161     public volatile Boolean isAdded = false;
       
   162     public static JTextArea resultsTextArea;
       
   163 
       
   164     public TestUI(CountDownLatch latch) throws Exception {
       
   165         this.latch = latch;
       
   166     }
       
   167 
       
   168     public final void createUI() {
       
   169         mainFrame = new JFrame("RemotePrinterStatusRefresh");
       
   170         layout = new GridBagLayout();
       
   171         mainControlPanel = new JPanel(layout);
       
   172         resultButtonPanel = new JPanel(layout);
       
   173         testPanel = new JPanel(layout);
       
   174         GridBagConstraints gbc = new GridBagConstraints();
       
   175 
       
   176         // Create Test instructions
       
   177         String instructions
       
   178                 = "This test displays the current list of printers(before) attached to \n"
       
   179                 + "this computer in the results panel.\n\n"
       
   180                 + "Please follow the below steps for this manual test\n"
       
   181                 + "--------------------------------------------------------------------\n"
       
   182                 + "Step 1: Add/Remove a new network printer and Wait for 4 minutes after adding/removing\n"
       
   183                 + "Step 2: Then click on 'Printer Added/Removed' button\n"
       
   184                 + "Step 2: Once the new network printer is added/removed, see if it is \n"
       
   185                 + "        the same as displayed/not displayed in the results panel.\n"
       
   186                 + "Step 3: If displayed/not displayed, then click 'Pass' else click on 'Fail' button";
       
   187 
       
   188         instructionTextArea = new JTextArea();
       
   189         instructionTextArea.setText(instructions);
       
   190         instructionTextArea.setEditable(false);
       
   191         instructionTextArea.setBorder(BorderFactory.
       
   192                 createTitledBorder("Test Instructions"));
       
   193 
       
   194         gbc.gridx = 0;
       
   195         gbc.gridy = 0;
       
   196         gbc.fill = GridBagConstraints.HORIZONTAL;
       
   197         mainControlPanel.add(instructionTextArea, gbc);
       
   198 
       
   199         gbc.gridx = 0;
       
   200         gbc.gridy = 1;
       
   201         testPanel.add(Box.createVerticalStrut(50));
       
   202         mainControlPanel.add(testPanel);
       
   203 
       
   204         addedButton = new JButton("Printer Added/Removed");
       
   205         addedButton.setActionCommand("Added");
       
   206         addedButton.addActionListener((ActionEvent e) -> {
       
   207             System.out.println("Added Button pressed!");
       
   208             isAdded = true;
       
   209         });
       
   210 
       
   211         // Create resultButtonPanel with Pass, Fail buttons
       
   212         passButton = new JButton("Pass");
       
   213         passButton.setActionCommand("Pass");
       
   214         passButton.addActionListener((ActionEvent e) -> {
       
   215             System.out.println("Pass Button pressed!");
       
   216             testResult = true;
       
   217             latch.countDown();
       
   218             disposeUI();
       
   219         });
       
   220 
       
   221         failButton = new JButton("Fail");
       
   222         failButton.setActionCommand("Fail");
       
   223         failButton.addActionListener((ActionEvent e) -> {
       
   224             System.out.println("Fail Button pressed!");
       
   225             testResult = false;
       
   226             latch.countDown();
       
   227             disposeUI();
       
   228         });
       
   229 
       
   230         gbc.gridx = 0;
       
   231         gbc.gridy = 0;
       
   232         resultButtonPanel.add(addedButton, gbc);
       
   233 
       
   234         gbc.gridx = 1;
       
   235         gbc.gridy = 0;
       
   236         resultButtonPanel.add(passButton, gbc);
       
   237 
       
   238         gbc.gridx = 2;
       
   239         gbc.gridy = 0;
       
   240         resultButtonPanel.add(failButton, gbc);
       
   241 
       
   242         resultsTextArea = new JTextArea();
       
   243         resultsTextArea.setEditable(false);
       
   244         resultsTextArea.setBorder(BorderFactory.
       
   245                 createTitledBorder("Results"));
       
   246 
       
   247         gbc.gridx = 0;
       
   248         gbc.gridy = 1;
       
   249         gbc.fill = GridBagConstraints.HORIZONTAL;
       
   250         mainControlPanel.add(resultsTextArea, gbc);
       
   251 
       
   252         gbc.gridx = 0;
       
   253         gbc.gridy = 2;
       
   254         mainControlPanel.add(resultButtonPanel, gbc);
       
   255 
       
   256         mainFrame.add(mainControlPanel);
       
   257         mainFrame.pack();
       
   258         mainFrame.setVisible(true);
       
   259     }
       
   260 
       
   261     public void disposeUI() {
       
   262         mainFrame.dispose();
       
   263     }
       
   264 }