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