001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.ui.threads;
042:
043: import org.netbeans.lib.profiler.global.CommonConstants;
044: import org.netbeans.lib.profiler.results.DataManagerListener;
045: import org.netbeans.lib.profiler.results.threads.ThreadData;
046: import org.netbeans.lib.profiler.results.threads.ThreadsDataManager;
047: import org.netbeans.lib.profiler.ui.UIUtils;
048: import java.awt.*;
049: import java.awt.event.ActionEvent;
050: import java.awt.event.ActionListener;
051: import java.awt.event.ComponentAdapter;
052: import java.awt.event.ComponentEvent;
053: import java.awt.image.BufferedImage;
054: import java.util.ArrayList;
055: import java.util.HashMap;
056: import java.util.Iterator;
057: import java.util.ResourceBundle;
058: import javax.swing.*;
059:
060: /**
061: * A panel to display list of thread detailed information.
062: *
063: * @author Ian Formanek
064: * @author Jiri Sedlacek
065: */
066: public class ThreadsDetailsPanel extends JPanel implements
067: ActionListener, DataManagerListener {
068: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
069:
070: // -----
071: // I18N String constants
072: private static final ResourceBundle messages = ResourceBundle
073: .getBundle("org.netbeans.lib.profiler.ui.threads.Bundle"); // NOI18N
074: private static final String TEXT_DISPLAY_ALL = messages
075: .getString("ThreadsDetailsPanel_TextDisplayAll"); // NOI18N
076: private static final String TEXT_DISPLAY_ALL_EX = messages
077: .getString("ThreadsDetailsPanel_TextDisplayAllEx"); // NOI18N
078: private static final String TEXT_DISPLAY_LIVE = messages
079: .getString("ThreadsDetailsPanel_TextDisplayLive"); // NOI18N
080: private static final String TEXT_DISPLAY_LIVE_EX = messages
081: .getString("ThreadsDetailsPanel_TextDisplayLiveEx"); // NOI18N
082: private static final String TEXT_DISPLAY_FINISHED = messages
083: .getString("ThreadsDetailsPanel_TextDisplayFinished"); // NOI18N
084: private static final String TEXT_DISPLAY_FINISHED_EX = messages
085: .getString("ThreadsDetailsPanel_TextDisplayFinishedEx"); // NOI18N
086: private static final String TEXT_DISPLAY_SELECTION = messages
087: .getString("ThreadsDetailsPanel_TextDisplaySelection"); // NOI18N
088: private static final String NO_CONTENT_MSG = messages
089: .getString("ThreadsDetailsPanel_NoContentMsg"); // NOI18N
090: private static final String EVENTQUEUE_THREAD_DESCR = messages
091: .getString("ThreadsDetailsPanel_EventQueueThreadDescr"); // NOI18N
092: private static final String IMAGEFETCHER_THREAD_DESCR = messages
093: .getString("ThreadsDetailsPanel_ImageFetcherThreadDescr"); // NOI18N
094: private static final String IMAGEANIMATOR_THREAD_DESCR = messages
095: .getString("ThreadsDetailsPanel_ImageAnimatorThreadDescr"); // NOI18N
096: private static final String AWTWINDOWS_THREAD_DESCR = messages
097: .getString("ThreadsDetailsPanel_AwtWindowsThreadDescr"); // NOI18N
098: private static final String AWTMOTIF_THREAD_DESCR = messages
099: .getString("ThreadsDetailsPanel_AwtMotifThreadDescr"); // NOI18N
100: private static final String AWTSHUTDWN_THREAD_DESCR = messages
101: .getString("ThreadsDetailsPanel_AwtShutDwnThreadDescr"); // NOI18N
102: private static final String MAIN_THREAD_DESCR = messages
103: .getString("ThreadsDetailsPanel_MainThreadDescr"); // NOI18N
104: private static final String FINALIZER_THREAD_DESCR = messages
105: .getString("ThreadsDetailsPanel_FinalizerThreadDescr"); // NOI18N
106: private static final String REFHANDLER_THREAD_DESCR = messages
107: .getString("ThreadsDetailsPanel_RefHandlerThreadDescr"); // NOI18N
108: private static final String SIGDISPATCH_THREAD_DESCR = messages
109: .getString("ThreadsDetailsPanel_SigDispatchThreadDescr"); // NOI18N
110: private static final String J2DISPOSER_THREAD_DESCR = messages
111: .getString("ThreadsDetailsPanel_J2DisposerThreadDescr"); // NOI18N
112: private static final String TIMERQUEUE_THREAD_DESCR = messages
113: .getString("ThreadsDetailsPanel_TimerQueueThreadDescr"); // NOI18N
114: private static final String USER_THREAD_DESCR = messages
115: .getString("ThreadsDetailsPanel_UserThreadDescr"); // NOI18N
116: private static final String COMBO_ACCESS_NAME = messages
117: .getString("ThreadsDetailsPanel_ComboAccessName"); // NOI18N
118: private static final String COMBO_ACCESS_DESCR = messages
119: .getString("ThreadsDetailsPanel_ComboAccessDescr"); // NOI18N
120: private static final String CONTENT_ACCESS_NAME = messages
121: .getString("ThreadsDetailsPanel_ContentAccessName"); // NOI18N
122: private static final String CONTENT_ACCESS_DESCR = messages
123: .getString("ThreadsDetailsPanel_ContentAccessDescr"); // NOI18N
124: private static final String SHOW_LABEL_TEXT = messages
125: .getString("ThreadsPanel_ShowLabelText"); // NOI18N
126: // -----
127: private static final int DISPLAY_ALL = 0;
128: private static final int DISPLAY_LIVE = 1;
129: private static final int DISPLAY_FINISHED = 2;
130: private static final int DISPLAY_SELECTED = 3;
131: private static final int DISPLAY_ALL_EX = 4;
132: private static final int DISPLAY_LIVE_EX = 5;
133: private static final int DISPLAY_FINISHED_EX = 6;
134:
135: //~ Instance fields ----------------------------------------------------------------------------------------------------------
136:
137: private ArrayList displayedPanels = new ArrayList(10);
138: private ArrayList excludedThreads = new ArrayList(5);
139: private ArrayList filteredThreads = new ArrayList(10);
140: private DefaultComboBoxModel comboModel;
141: private HashMap descriptions = new HashMap(20);
142: private HashMap indexToDisplayedIndex = new HashMap(15);
143: private HashMap unusedPanels = new HashMap(5); // <thread index, ThreadDetailsComponent>
144: private JComboBox threadsSelectionCombo;
145: private JPanel content;
146: private JPanel noContentPanel;
147: private JScrollPane scrollPane;
148: private JToolBar buttonsToolBar;
149: private ThreadsDataManager manager;
150: private boolean internalChange = false;
151: private boolean noContent = false;
152: private boolean resetPerformed = true;
153: private boolean supportsSleepingState; // internal flag indicating that threads monitoring engine correctly reports the "sleeping" state
154: private int displayMode = DISPLAY_SELECTED;
155:
156: //~ Constructors -------------------------------------------------------------------------------------------------------------
157:
158: public ThreadsDetailsPanel(ThreadsDataManager manager,
159: boolean supportsSleepingState) {
160: this .manager = manager;
161: this .supportsSleepingState = supportsSleepingState;
162:
163: noContentPanel = new JPanel();
164: noContentPanel.setLayout(new BorderLayout());
165: noContentPanel.setBorder(BorderFactory.createEmptyBorder(12,
166: 12, 12, 12));
167:
168: JLabel noContentIcon = new JLabel(
169: new javax.swing.ImageIcon(
170: getClass()
171: .getResource(
172: "/org/netbeans/lib/profiler/ui/resources/threadsView.png"))); // NOI18N
173: noContentIcon.setBorder(BorderFactory.createEmptyBorder(0, 0,
174: 0, 5));
175: noContentIcon.setVerticalAlignment(SwingConstants.TOP);
176: noContentIcon.setEnabled(false);
177:
178: JTextArea noContentText = new JTextArea(NO_CONTENT_MSG);
179: noContentText.setFont(noContentText.getFont().deriveFont(14));
180:
181: noContentText.setEditable(false);
182: noContentText.setEnabled(false);
183: noContentText.setWrapStyleWord(true);
184: noContentText.setLineWrap(true);
185: noContentText.setBackground(noContentPanel.getBackground());
186:
187: JPanel containerPanel = new JPanel(new BorderLayout());
188: containerPanel.add(noContentIcon, BorderLayout.WEST);
189: containerPanel.add(noContentText, BorderLayout.CENTER);
190: noContentPanel.add(containerPanel, BorderLayout.NORTH);
191:
192: // create components
193: threadsSelectionCombo = new JComboBox() {
194: public Dimension getMaximumSize() {
195: return new Dimension(250, getPreferredSize().height);
196: };
197: };
198: threadsSelectionCombo.getAccessibleContext().setAccessibleName(
199: COMBO_ACCESS_NAME);
200: threadsSelectionCombo.getAccessibleContext()
201: .setAccessibleDescription(COMBO_ACCESS_DESCR);
202:
203: updateCombo();
204:
205: JLabel showLabel = new JLabel(SHOW_LABEL_TEXT);
206: showLabel
207: .setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
208: showLabel.setLabelFor(threadsSelectionCombo);
209:
210: int mnemCharIndex = 0;
211: showLabel.setDisplayedMnemonic(showLabel.getText().charAt(
212: mnemCharIndex));
213: showLabel.setDisplayedMnemonicIndex(mnemCharIndex);
214:
215: buttonsToolBar = new JToolBar(JToolBar.HORIZONTAL) {
216: public Component add(Component comp) {
217: if (comp instanceof JButton) {
218: UIUtils.fixButtonUI((JButton) comp);
219: }
220:
221: return super .add(comp);
222: }
223: };
224: content = new JPanel() {
225: public Dimension getPreferredSize() {
226: Dimension dim = super .getPreferredSize();
227:
228: return new Dimension(Math.min(dim.width, scrollPane
229: .getViewportBorderBounds().width), dim.height);
230: }
231: };
232: content.getAccessibleContext().setAccessibleName(
233: CONTENT_ACCESS_NAME);
234: content.getAccessibleContext().setAccessibleName(
235: CONTENT_ACCESS_DESCR);
236:
237: JPanel contentPanel = new JPanel();
238: contentPanel.setLayout(new BorderLayout());
239: scrollPane = new JScrollPane(contentPanel,
240: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
241: JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
242: scrollPane.getVerticalScrollBar().setUnitIncrement(30);
243:
244: // set properties
245: buttonsToolBar.setBorder(BorderFactory.createEmptyBorder(4, 0,
246: 4, 0));
247: buttonsToolBar.setFloatable(false);
248: buttonsToolBar.putClientProperty("JToolBar.isRollover",
249: Boolean.TRUE); // NOI18N
250:
251: // perform layout
252: setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
253: setLayout(new BorderLayout());
254: content.setLayout(new GridLayout(0, 1)); /*new GridLayout(0, 1) {
255: public void layoutContainer(Container parent) {
256: Component[] list = parent.getComponents();
257: if (list.length == 0) return;
258:
259: Insets insets = parent.getInsets();
260: Dimension parentSize = parent.getSize();
261: int availableW = parentSize.width - (insets.left + insets.right);
262: int availableH = parentSize.height - (insets.top + insets.bottom);
263:
264: int targetHeight = 0;
265: for (int i = 0; i < list.length; i++) targetHeight += list[i].getPreferredSize().height;
266: if (targetHeight >= availableH)
267: super.layoutContainer(parent);
268: else {
269: int ypos = insets.top;
270: for (int i = 0 ; i < list.length; i++) {
271: int prefHeight = list[i].getPreferredSize().height;
272: list[i].setBounds(insets.left, ypos, availableW, prefHeight);
273: ypos += prefHeight;
274: }
275: }
276: }
277: });*/
278:
279: contentPanel.add(content, BorderLayout.NORTH);
280: buttonsToolBar.add(showLabel);
281: buttonsToolBar.add(threadsSelectionCombo);
282: add(buttonsToolBar, BorderLayout.NORTH);
283: add(scrollPane, BorderLayout.CENTER);
284: //add (scrollBar, BorderLayout.EAST);
285: threadsSelectionCombo.addActionListener(this );
286: manager.addDataListener(this );
287: addComponentListener(new ComponentAdapter() {
288: public void componentShown(ComponentEvent e) {
289: // since the data were not processed when this component was not showing,
290: // we need to do the updateState when the component becomes visible
291: dataChanged();
292: }
293: });
294: }
295:
296: //~ Methods ------------------------------------------------------------------------------------------------------------------
297:
298: public BufferedImage getCurrentViewScreenshot(
299: boolean onlyVisibleArea) {
300: if (onlyVisibleArea) {
301: return UIUtils.createScreenshot(scrollPane);
302: } else {
303: return UIUtils.createScreenshot(content);
304: }
305: }
306:
307: public long getDataEndTime() {
308: return manager.getEndTime();
309: }
310:
311: public long getDataStartTime() {
312: return manager.getStartTime();
313: }
314:
315: public String getThreadClassName(int index) {
316: return manager.getThreadClassName(index);
317: }
318:
319: public ThreadData getThreadData(int index) {
320: return manager.getThreadData(index);
321: }
322:
323: public String getThreadDescription(int index) {
324: String description = (String) descriptions.get(new Integer(
325: index));
326:
327: if (description == null) {
328: description = createDescription(manager
329: .getThreadName(index));
330: descriptions.put(new Integer(index), description);
331: }
332:
333: return description;
334: }
335:
336: // ---------------------------------------------------------------------------------------
337: // Thread data
338: public String getThreadName(int index) {
339: return manager.getThreadName(index);
340: }
341:
342: // ---------------------------------------------------------------------------------------
343: // Listeners
344:
345: /** Invoked when one of the buttons is pressed */
346: public void actionPerformed(ActionEvent e) {
347: if (internalChange) {
348: return;
349: }
350:
351: if (e.getSource() == threadsSelectionCombo) {
352: String threadSelection = (String) threadsSelectionCombo
353: .getSelectedItem();
354: int oldMode = displayMode;
355:
356: switch (threadsSelectionCombo.getSelectedIndex()) {
357: case 0:
358: displayMode = DISPLAY_ALL;
359:
360: break;
361: case 1:
362: displayMode = DISPLAY_LIVE;
363:
364: break;
365: case 2:
366: displayMode = DISPLAY_FINISHED;
367:
368: break;
369: case 3:
370: displayMode = DISPLAY_SELECTED;
371:
372: break;
373: case 4:
374:
375: if (threadSelection == TEXT_DISPLAY_ALL_EX) {
376: displayMode = DISPLAY_ALL_EX;
377: } else if (threadSelection == TEXT_DISPLAY_LIVE_EX) {
378: displayMode = DISPLAY_LIVE_EX;
379: } else if (threadSelection == TEXT_DISPLAY_FINISHED_EX) {
380: displayMode = DISPLAY_FINISHED_EX;
381: }
382: }
383:
384: if (oldMode != displayMode) {
385: switch (displayMode) {
386: case DISPLAY_ALL:
387: excludedThreads.clear();
388:
389: break;
390: case DISPLAY_LIVE:
391: excludedThreads.clear();
392:
393: break;
394: case DISPLAY_FINISHED:
395: excludedThreads.clear();
396:
397: break;
398: case DISPLAY_SELECTED:
399: excludedThreads.clear();
400: filteredThreads.clear();
401:
402: break;
403: }
404:
405: updateCombo();
406: dataChanged();
407: }
408: }
409: }
410:
411: // --- Save Current View action support --------------------------------------
412: public void addSaveViewAction(AbstractAction saveViewAction) {
413: JButton actionButton = buttonsToolBar.add(saveViewAction);
414: buttonsToolBar.remove(actionButton);
415:
416: buttonsToolBar.add(actionButton, 0);
417: buttonsToolBar.add(new JToolBar.Separator(), 1);
418: }
419:
420: /** Called when data in manager change */
421: public void dataChanged() {
422: if (resetPerformed) {
423: supportsSleepingState = manager
424: .supportsSleepingStateMonitoring();
425: resetPerformed = false;
426: }
427:
428: UIUtils.runInEventDispatchThread(new Runnable() {
429: public void run() {
430: if (!isShowing()) {
431: return;
432: }
433:
434: updateFilteredData();
435:
436: if (updateDisplayedPanels()) {
437: // if the number of displayed panels changed, the scrollbar needs to be revalidated
438: content.invalidate();
439: revalidate();
440: repaint();
441: }
442: }
443: });
444: }
445:
446: public void dataReset() {
447: resetPerformed = true;
448: filteredThreads.clear();
449: excludedThreads.clear();
450: descriptions.clear();
451: content.removeAll();
452: unusedPanels.clear();
453: displayedPanels.clear();
454:
455: displayMode = DISPLAY_SELECTED;
456: UIUtils.runInEventDispatchThread(new Runnable() {
457: public void run() {
458: updateCombo();
459:
460: content.invalidate();
461: revalidate();
462: repaint();
463: }
464: });
465: }
466:
467: public boolean fitsVisibleArea() {
468: return !scrollPane.getVerticalScrollBar().isVisible();
469: }
470:
471: public boolean hasView() {
472: return !noContent && (content.getComponentCount() > 0);
473: }
474:
475: /** Called by the ThreadDetailsComponent when the Hide button has been clicked */
476: public void hideThreadDetails(int index) {
477: if (displayMode == DISPLAY_SELECTED) {
478: filteredThreads.remove(new Integer(index));
479: } else {
480: if (displayMode == DISPLAY_ALL) {
481: displayMode = DISPLAY_ALL_EX;
482: updateCombo();
483: } else if (displayMode == DISPLAY_LIVE) {
484: displayMode = DISPLAY_LIVE_EX;
485: updateCombo();
486: } else if (displayMode == DISPLAY_FINISHED) {
487: displayMode = DISPLAY_FINISHED_EX;
488: updateCombo();
489: }
490:
491: excludedThreads.add(new Integer(index));
492: updateFilteredData();
493: }
494:
495: if (updateDisplayedPanels()) {
496: content.invalidate();
497: revalidate();
498: repaint();
499: }
500: }
501:
502: public void showDetails(int[] indexes) {
503: displayMode = DISPLAY_SELECTED;
504: filteredThreads.clear();
505: excludedThreads.clear();
506:
507: for (int i = 0; i < indexes.length; i++) {
508: filteredThreads.add(new Integer(indexes[i]));
509: }
510:
511: updateCombo();
512:
513: if (updateDisplayedPanels()) {
514: content.invalidate();
515: revalidate();
516: repaint();
517: }
518: }
519:
520: private ThreadDetailsComponent getPanel(int threadIndex) {
521: ThreadDetailsComponent tdcr = (ThreadDetailsComponent) unusedPanels
522: .remove(new Integer(threadIndex));
523:
524: if (tdcr == null) {
525: if (unusedPanels.size() > 0) {
526: tdcr = (ThreadDetailsComponent) unusedPanels
527: .remove(unusedPanels.keySet().iterator().next());
528: } else {
529: tdcr = new ThreadDetailsComponent(this ,
530: supportsSleepingState);
531: }
532: }
533:
534: tdcr.setIndex(threadIndex);
535:
536: return tdcr;
537: }
538:
539: private String createDescription(String threadName) {
540: if (threadName.startsWith("AWT-EventQueue-")) {
541: return EVENTQUEUE_THREAD_DESCR; // NOI18N
542: }
543:
544: if (threadName.startsWith("Image Fetcher ")) {
545: return IMAGEFETCHER_THREAD_DESCR; // NOI18N
546: }
547:
548: if (threadName.startsWith("Image Animator ")) {
549: return IMAGEANIMATOR_THREAD_DESCR; // NOI18N
550: }
551:
552: if (threadName.equals("AWT-Windows")) {
553: return AWTWINDOWS_THREAD_DESCR; // NOI18N
554: }
555:
556: if (threadName.equals("AWT-Motif")) {
557: return AWTMOTIF_THREAD_DESCR; // NOI18N
558: }
559:
560: if (threadName.equals("AWT-Shutdown")) {
561: return AWTSHUTDWN_THREAD_DESCR; // NOI18N
562: }
563:
564: if (threadName.equals("main")) {
565: return MAIN_THREAD_DESCR; // NOI18N
566: }
567:
568: if (threadName.equals("Finalizer")) {
569: return FINALIZER_THREAD_DESCR; // NOI18N
570: }
571:
572: if (threadName.equals("Reference Handler")) {
573: return REFHANDLER_THREAD_DESCR; // NOI18N
574: }
575:
576: if (threadName.equals("Signal Dispatcher")) {
577: return SIGDISPATCH_THREAD_DESCR; // NOI18N
578: }
579:
580: if (threadName.equals("Java2D Disposer")) {
581: return J2DISPOSER_THREAD_DESCR; // NOI18N
582: }
583:
584: if (threadName.equals("TimerQueue")) {
585: return TIMERQUEUE_THREAD_DESCR; // NOI18N
586: }
587:
588: return USER_THREAD_DESCR;
589: }
590:
591: // @AWTRequired
592: private void updateCombo() {
593: internalChange = true;
594: comboModel = new DefaultComboBoxModel(new Object[] {
595: TEXT_DISPLAY_ALL, TEXT_DISPLAY_LIVE,
596: TEXT_DISPLAY_FINISHED, TEXT_DISPLAY_SELECTION });
597:
598: int displayIndex = 0;
599:
600: switch (displayMode) {
601: case DISPLAY_ALL:
602: displayIndex = 0;
603:
604: break;
605: case DISPLAY_LIVE:
606: displayIndex = 1;
607:
608: break;
609: case DISPLAY_FINISHED:
610: displayIndex = 2;
611:
612: break;
613: case DISPLAY_SELECTED:
614: displayIndex = 3;
615:
616: break;
617: case DISPLAY_ALL_EX:
618: comboModel.addElement(TEXT_DISPLAY_ALL_EX);
619: displayIndex = 4;
620:
621: break;
622: case DISPLAY_LIVE_EX:
623: comboModel.addElement(TEXT_DISPLAY_LIVE_EX);
624: displayIndex = 4;
625:
626: break;
627: case DISPLAY_FINISHED_EX:
628: comboModel.addElement(TEXT_DISPLAY_FINISHED_EX);
629: displayIndex = 4;
630:
631: break;
632: }
633:
634: threadsSelectionCombo.setModel(comboModel);
635: threadsSelectionCombo.setSelectedIndex(displayIndex);
636:
637: internalChange = false;
638: }
639:
640: /** Updates the displayed panels.
641: *
642: * The filteredThreads contains threads that need to be displayed.
643: * The displayedPanels arraylist contains panels that are currently displayed
644: * The indexToDisplayedIndex map maps real thread indexes to those displayed
645: *
646: * @return true if the number of panels changed
647: *
648: * @AWTRequired
649: **/
650: private boolean updateDisplayedPanels() {
651: boolean changed = false;
652: int filteredSize = filteredThreads.size();
653:
654: if (filteredSize == 0) {
655: if (!noContent) {
656: noContent = true;
657: remove(scrollPane);
658: add(noContentPanel, BorderLayout.CENTER);
659: invalidate();
660: revalidate();
661: repaint();
662: }
663:
664: return changed;
665: } else {
666: if (noContent) {
667: noContent = false;
668: remove(noContentPanel);
669: add(scrollPane, BorderLayout.CENTER);
670: invalidate();
671: revalidate();
672: repaint();
673: }
674: }
675:
676: int displayedSize = displayedPanels.size();
677:
678: if (filteredSize > displayedSize) { // need to get & display new panels
679:
680: for (int i = displayedSize; i < filteredSize; i++) {
681: ThreadDetailsComponent tdc = getPanel(((Integer) filteredThreads
682: .get(i)).intValue());
683: displayedPanels.add(tdc);
684: content.add(tdc);
685: }
686:
687: changed = true;
688: } else if (filteredSize < displayedSize) { // need to remove some displayed panels
689:
690: for (int i = filteredSize; i < displayedSize; i++) {
691: ThreadDetailsComponent tdc = (ThreadDetailsComponent) displayedPanels
692: .remove(filteredSize);
693: unusedPanels.put(new Integer(tdc.getIndex()), tdc);
694: content.remove(tdc);
695: }
696:
697: changed = true;
698: }
699:
700: indexToDisplayedIndex.clear();
701:
702: int count = 0;
703:
704: for (Iterator it = filteredThreads.iterator(); it.hasNext();) {
705: int indexToDisplay = ((Integer) it.next()).intValue();
706: ((ThreadDetailsComponent) displayedPanels.get(count))
707: .setIndex(indexToDisplay);
708: indexToDisplayedIndex.put(new Integer(indexToDisplay),
709: new Integer(count));
710: count++;
711: }
712:
713: return changed;
714: }
715:
716: private boolean updateDisplayedPanels1() {
717: // remove all displayed panels
718: content.removeAll();
719:
720: indexToDisplayedIndex.clear();
721:
722: // put all of them to unused map
723: for (int i = displayedPanels.size() - 1; i >= 0; i--) {
724: ThreadDetailsComponent tdcr = (ThreadDetailsComponent) displayedPanels
725: .remove(i);
726: unusedPanels.put(new Integer(tdcr.getIndex()), tdcr);
727: }
728:
729: int count = 0;
730:
731: for (Iterator it = filteredThreads.iterator(); it.hasNext();) {
732: int indexToDisplay = ((Integer) it.next()).intValue();
733: ThreadDetailsComponent tdcr = getPanel(indexToDisplay);
734: content.add(tdcr);
735: displayedPanels.add(tdcr);
736: indexToDisplayedIndex.put(new Integer(indexToDisplay),
737: new Integer(count++));
738: }
739:
740: return true;
741: }
742:
743: // ---------------------------------------------------------------------------------------
744: // Private methods
745:
746: /** Updates filteredThreads list per selection in the threadsSelectionCombo. */
747: private void updateFilteredData() {
748: if (displayMode == DISPLAY_SELECTED) {
749: return;
750: }
751:
752: filteredThreads.clear();
753:
754: if ((displayMode == DISPLAY_ALL)
755: || (displayMode == DISPLAY_ALL_EX)) {
756: for (int i = 0; i < manager.getThreadsCount(); i++) {
757: filteredThreads.add(new Integer(i)); // thread with index "i" should be displayed
758: }
759: }
760:
761: if ((displayMode == DISPLAY_LIVE)
762: || (displayMode == DISPLAY_LIVE_EX)) {
763: // view live threads
764: for (int i = 0; i < manager.getThreadsCount(); i++) {
765: ThreadData threadData = manager.getThreadData(i);
766:
767: if (threadData.size() > 0) {
768: byte state = threadData.getLastState();
769:
770: if (state != CommonConstants.THREAD_STATUS_ZOMBIE) {
771: filteredThreads.add(new Integer(i)); // thread with index "i" should be displayed
772: }
773: }
774: }
775: }
776:
777: if ((displayMode == DISPLAY_FINISHED)
778: || (displayMode == DISPLAY_FINISHED_EX)) {
779: // view finished threads
780: for (int i = 0; i < manager.getThreadsCount(); i++) {
781: ThreadData threadData = manager.getThreadData(i);
782:
783: if (threadData.size() > 0) {
784: byte state = threadData.getLastState();
785:
786: if (state == CommonConstants.THREAD_STATUS_ZOMBIE) {
787: filteredThreads.add(new Integer(i)); // thread with index "i" should be displayed
788: }
789: } else {
790: // No state defined -> THREAD_STATUS_ZOMBIE assumed (thread could finish when monitoring was disabled)
791: filteredThreads.add(new Integer(i));
792: }
793: }
794: }
795:
796: // process excludes
797: if ((displayMode == DISPLAY_ALL_EX)
798: || (displayMode == DISPLAY_LIVE_EX)
799: || (displayMode == DISPLAY_FINISHED_EX)) {
800: filteredThreads.removeAll(excludedThreads);
801: }
802: }
803: }
|