1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.exec; 28 29 import java.awt.BorderLayout; 30 import java.awt.CardLayout; 31 import java.awt.Component; 32 import java.awt.EventQueue; 33 import java.awt.GridBagLayout; 34 import java.awt.GridBagConstraints; 35 import java.awt.event.ActionEvent; 36 import java.awt.event.ActionListener; 37 import java.awt.event.ComponentEvent; 38 import java.awt.event.ComponentListener; 39 import java.util.ResourceBundle; 40 41 import javax.swing.JButton; 42 import javax.swing.JComboBox; 43 import javax.swing.JComponent; 44 import javax.swing.JLabel; 45 import javax.swing.JList; 46 import javax.swing.JMenuItem; 47 import javax.swing.JPanel; 48 import javax.swing.JSplitPane; 49 import javax.swing.JPopupMenu; 50 import javax.swing.JTextField; 51 import javax.swing.JToolBar; 52 import javax.swing.Timer; 53 import javax.swing.plaf.basic.BasicComboBoxRenderer; 54 import javax.swing.text.JTextComponent; 55 56 import com.sun.javatest.Harness; 57 import com.sun.javatest.Parameters; 58 import com.sun.javatest.TestResult; 59 import com.sun.javatest.tool.Preferences; 60 import com.sun.javatest.tool.UIFactory; 61 import com.sun.javatest.tool.jthelp.ContextHelpManager; 62 63 /** 64 * The panel at the bottom of exec tool. 65 * This class manages the insertion, deletion, and rearrangement of any small 66 * monitors. It also forwards informational text messages to the user. 67 */ 68 69 class MessageStrip extends JSplitPane 70 implements Harness.Observer, ComponentListener 71 { 72 MessageStrip(UIFactory uif, Monitor[] monitors, MonitorState state, 73 ActionListener zoomListener) { 74 this.uif = uif; 75 this.monitors = monitors; 76 this.state = state; 77 this.zoomListener = zoomListener; 78 79 setOrientation(JSplitPane.HORIZONTAL_SPLIT); 80 81 // left side is a simple text field 82 leftField = uif.createOutputField("strip.msg"); 83 leftField.setOpaque(false); 84 85 setLeftComponent(leftField); 86 setRightComponent(createRightPanel()); 87 88 setDividerSize(5); 89 setEnabled(true); 90 addComponentListener(this); 91 uif.setAccessibleInfo(this, "strip"); 92 setDividerLocation(0.60d); 93 } 94 95 // which to display while running tests 96 void setRunningMonitor(Monitor m) { 97 for (int i = 0; i < monitors.length; i++) 98 if (monitors[i] == m) { 99 runningMonitor = i; 100 break; 101 } 102 } 103 104 // which to display while not running tests 105 // these are not currently intended to be called after initialization 106 void setIdleMonitor(Monitor m) { 107 for (int i = 0; i < monitors.length; i++) 108 if (monitors[i] == m) { 109 idleMonitor = i; 110 break; 111 } 112 113 setMonitor(idleMonitor); 114 } 115 116 void setMonitor(final int index) { 117 if (index < 0) 118 return; 119 120 if (!EventQueue.isDispatchThread()) { 121 EventQueue.invokeLater(new Runnable() { 122 public void run() { 123 setMonitor(index); 124 } 125 }); 126 return; 127 } 128 129 if (index < monitors.length) { 130 currMonitor = index; 131 monitorCards.show(rightPanel, monitors[index].getSmallMonitorName()); 132 selector.setSelectedItem(monitors[index]); 133 validate(); // required for correct repaint 134 135 // write to preferences 136 Preferences p = Preferences.access(); 137 p.setPreference(MINI_PREF, monitors[index].getClass().getName()); 138 } 139 } 140 141 // Harness.Observer ... 142 // anything that happens here must be switched on to the event thread 143 144 public void startingTestRun(Parameters params) { 145 setText(leftField, uif.getI18NString("strip.start")); 146 setMonitor(runningMonitor); 147 148 if (clearTimer == null) 149 clearTimer = new Timer(CLEAR_TIMEOUT, new ActionListener() { 150 public void actionPerformed(ActionEvent evt) { 151 setText(leftField, ""); 152 } 153 }); 154 clearTimer.start(); 155 } 156 157 public void startingTest(TestResult tr) { 158 setText(leftField, uif.getI18NString("strip.running", tr.getTestName())); 159 } 160 161 public void finishedTest(TestResult tr) { 162 } 163 164 public void stoppingTestRun() { 165 setText(leftField, uif.getI18NString("strip.stop")); 166 } 167 168 public void finishedTesting() { 169 setText(leftField, uif.getI18NString("strip.cleanup")); 170 setMonitor(idleMonitor); 171 } 172 173 public void finishedTestRun(boolean allOk) { 174 setText(leftField, uif.getI18NString("strip.finish")); 175 if (clearTimer != null) 176 clearTimer.stop(); 177 } 178 179 public void error(String msg) { 180 } 181 182 void showMessage(ResourceBundle msgs, String key) { 183 setText(leftField, msgs.getString(key)); 184 } 185 186 private void setText(JTextComponent comp, String text) { 187 if (EventQueue.isDispatchThread()) 188 comp.setText(text); 189 else 190 EventQueue.invokeLater(new BranchPanel.TextUpdater(comp, text, uif)); 191 } 192 193 private JPopupMenu createMenu() { 194 JPopupMenu menu = uif.createPopupMenu("strip.menu"); 195 for (int i = 0; i < monitors.length; i++) { 196 JMenuItem mi = uif.createLiteralMenuItem( 197 monitors[i].getSmallMonitorName(), actionListener); 198 mi.setActionCommand(Integer.toString(i)); 199 menu.add(mi); 200 } // for 201 202 203 return menu; 204 } 205 206 private JComponent createRightPanel() { 207 JPanel right = uif.createPanel("strip.right", new GridBagLayout(), false); 208 209 selector = uif.createLiteralChoice("strip.sel", monitors); 210 uif.setAccessibleName(selector, "strip.sel"); 211 selector.addActionListener(actionListener); 212 selector.setRenderer(new BasicComboBoxRenderer() { 213 public Component getListCellRendererComponent(JList list, Object value, 214 int index, boolean isSelected, boolean cellHasFocus) { 215 Component c = super.getListCellRendererComponent(list, value, 216 index, isSelected, cellHasFocus); 217 try { 218 JLabel lab = (JLabel)c; 219 if (value instanceof Monitor) 220 lab.setText(((Monitor)value).getSmallMonitorName()); 221 } 222 catch (ClassCastException e) { 223 } 224 225 return c; 226 } 227 }); 228 ContextHelpManager.setHelpIDString(selector, "run.testProgress"); 229 230 GridBagConstraints gbc = new GridBagConstraints(); 231 gbc.weightx = 2.0d; 232 gbc.gridx = 0; 233 gbc.gridy = 0; 234 gbc.fill = GridBagConstraints.HORIZONTAL; 235 gbc.anchor = GridBagConstraints.WEST; 236 237 monitorCards = new CardLayout(); 238 rightPanel = uif.createPanel("strip.", monitorCards, false); 239 for (int i = 0; i < monitors.length; i++) 240 rightPanel.add(monitors[i].getSmallMonitorName(), monitors[i].getSmallMonitor()); 241 currMonitor = getDefaultSmallMonitor(); 242 monitorCards.show(rightPanel, monitors[currMonitor].getSmallMonitorName()); 243 244 JPanel tmpPanel = uif.createPanel("monitor container", new BorderLayout(), false); 245 tmpPanel.add(selector, BorderLayout.WEST); 246 tmpPanel.add(rightPanel, BorderLayout.CENTER); 247 248 right.add(tmpPanel, gbc); 249 250 gbc.gridx = 1; 251 gbc.weightx = 0.0d; 252 /* 253 gbc.anchor = GridBagConstraints.EAST; 254 selectButt = uif.createIconButton("strip.drop"); 255 selectButt.addMouseListener(popupListener); 256 selectButt.addActionListener(popupListener); 257 uif.setAccessibleName(selectButt, "strip.drop"); 258 259 gbc.gridx = 2; 260 */ 261 magButt = uif.createIconButton("strip.magnify"); 262 magButt.addActionListener(actionListener); 263 uif.setAccessibleName(magButt, "strip.magnify"); 264 265 JToolBar tb = uif.createToolBar("strip.tb", 266 new JButton[] {magButt}); 267 tb.setFloatable(false); 268 tb.setBorderPainted(true); 269 270 right.add(tb, gbc); 271 272 right.setEnabled(true); 273 right.setVisible(true); 274 rightPanel.setEnabled(true); 275 rightPanel.setVisible(true); 276 277 return right; 278 } 279 280 // --------------- private -------------------- 281 282 /** 283 * Determine by whatever means, which monitor should be shown. 284 */ 285 private int getDefaultSmallMonitor() { 286 if (idleMonitor != -1) 287 return idleMonitor; 288 else { 289 Preferences p = Preferences.access(); 290 String prefSetting = p.getPreference(MINI_PREF, null); 291 292 int index = 0; 293 294 // don't do anything if there's no monitors or no pref. 295 if (prefSetting != null && monitors != null) { 296 try { 297 for (int i = 0; i < monitors.length; i++) { 298 if (monitors[i].getClass().getName().equals(prefSetting)) { 299 index = i; 300 break; 301 } 302 } // for 303 } // try 304 catch (NumberFormatException excep) { 305 // ok, whatever... 306 index = 0; 307 } 308 } // outer if 309 // whatever happens, zero is the default 310 311 return index; 312 } 313 } 314 315 private int getMonitorIndex(Monitor m) { 316 if (monitors == null || monitors.length == 0) 317 return -1; 318 319 for (int i = 0; i < monitors.length; i++) 320 if (monitors[i] == m) 321 return i; 322 323 return -1; 324 } 325 326 // ---------- ComponentListener ---------- 327 public void componentHidden(ComponentEvent e) { } 328 public void componentMoved(ComponentEvent e) { } 329 public void componentResized(ComponentEvent e) { 330 setDividerLocation(0.70d); 331 } 332 public void componentShown(ComponentEvent e) { } 333 334 private JTextField leftField; 335 private JPanel rightPanel; 336 private JButton selectButt; 337 private JButton magButt; 338 339 private JComboBox<Monitor> selector; 340 private JPopupMenu popMenu; 341 private ActionListener actionListener = new SelectionListener(); 342 private ActionListener zoomListener; 343 private Monitor[] monitors; 344 private MonitorState state; 345 private int currMonitor; 346 private CardLayout monitorCards; 347 private int runningMonitor = -1; 348 private int idleMonitor = -1; 349 private Timer clearTimer; 350 private static final int CLEAR_TIMEOUT = 5000; // time before msg is cleared 351 352 private UIFactory uif; 353 354 private static final String MINI_PREF = "exec.monitorstrip.mini"; 355 356 class SelectionListener implements ActionListener { 357 public void actionPerformed(ActionEvent e) { 358 Object source = e.getSource(); 359 360 if (source == magButt) { 361 zoomListener.actionPerformed(e); 362 } 363 else if (source == selector) { 364 Object item = selector.getSelectedItem(); 365 setMonitor(getMonitorIndex((Monitor)item)); 366 } 367 else if (source instanceof JMenuItem) { 368 try { 369 int index = Integer.parseInt(e.getActionCommand()); 370 371 // no change, or index is out of valid range for some reason 372 if (currMonitor == index || index >= monitors.length) 373 return; 374 375 setMonitor(index); 376 } // try 377 catch (NumberFormatException excep) { 378 // ignore event 379 } // catch 380 } 381 } // actionPerformed() 382 } 383 384 } 385