Source Code Cross Referenced for ThreadsPanel.java in  » IDE-Netbeans » cvsclient » org » netbeans » lib » profiler » ui » threads » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » cvsclient » org.netbeans.lib.profiler.ui.threads 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         * The Original Software is NetBeans. The Initial Developer of the Original
0026:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0027:         * Microsystems, Inc. All Rights Reserved.
0028:         *
0029:         * If you wish your version of this file to be governed by only the CDDL
0030:         * or only the GPL Version 2, indicate your decision by adding
0031:         * "[Contributor] elects to include this software in this distribution
0032:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0033:         * single choice of license, a recipient has the option to distribute
0034:         * your version of this file under either the CDDL, the GPL Version 2 or
0035:         * to extend the choice of license to its licensees as provided above.
0036:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0037:         * Version 2 license, then the option applies only if the new code is
0038:         * made subject to such option by the copyright holder.
0039:         */
0040:
0041:        package org.netbeans.lib.profiler.ui.threads;
0042:
0043:        import org.netbeans.lib.profiler.global.CommonConstants;
0044:        import org.netbeans.lib.profiler.results.DataManagerListener;
0045:        import org.netbeans.lib.profiler.results.threads.ThreadData;
0046:        import org.netbeans.lib.profiler.results.threads.ThreadsDataManager;
0047:        import org.netbeans.lib.profiler.ui.UIConstants;
0048:        import org.netbeans.lib.profiler.ui.UIUtils;
0049:        import org.netbeans.lib.profiler.ui.components.CellTipManager;
0050:        import org.netbeans.lib.profiler.ui.components.FlatToolBar;
0051:        import org.netbeans.lib.profiler.ui.components.JExtendedTable;
0052:        import org.netbeans.lib.profiler.ui.components.table.LabelTableCellRenderer;
0053:        import java.awt.*;
0054:        import java.awt.event.*;
0055:        import java.awt.image.BufferedImage;
0056:        import java.util.ArrayList;
0057:        import java.util.HashSet;
0058:        import java.util.ResourceBundle;
0059:        import java.util.Set;
0060:        import javax.swing.*;
0061:        import javax.swing.border.Border;
0062:        import javax.swing.border.CompoundBorder;
0063:        import javax.swing.event.ChangeEvent;
0064:        import javax.swing.event.ListSelectionEvent;
0065:        import javax.swing.event.TableColumnModelEvent;
0066:        import javax.swing.event.TableColumnModelListener;
0067:        import javax.swing.table.AbstractTableModel;
0068:        import javax.swing.table.DefaultTableCellRenderer;
0069:        import javax.swing.table.TableColumnModel;
0070:
0071:        /**
0072:         * A panel to display TA threads and their state.
0073:         *
0074:         * @author Ian Formanek
0075:         * @author Jiri Sedlacek
0076:         */
0077:        public class ThreadsPanel extends JPanel implements  AdjustmentListener,
0078:                ActionListener, TableColumnModelListener, DataManagerListener {
0079:            //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------
0080:
0081:            /** A callback interface - implemented by provider of additional details of a set of threads */
0082:            public interface ThreadsDetailsCallback {
0083:                //~ Methods --------------------------------------------------------------------------------------------------------------
0084:
0085:                /** Displays a panel with details about specified threads
0086:                 *
0087:                 * @param indexes array of int indexes for threads to display
0088:                 */
0089:                public void showDetails(int[] indexes);
0090:            }
0091:
0092:            //~ Inner Classes ------------------------------------------------------------------------------------------------------------
0093:
0094:            class ThreadsScrollBar extends JScrollBar {
0095:                //~ Constructors ---------------------------------------------------------------------------------------------------------
0096:
0097:                public ThreadsScrollBar() {
0098:                    super (JScrollBar.HORIZONTAL);
0099:                }
0100:
0101:                //~ Methods --------------------------------------------------------------------------------------------------------------
0102:
0103:                public Dimension getPreferredSize() {
0104:                    Dimension pref = super .getPreferredSize();
0105:
0106:                    return new Dimension(table.getTableHeader().getHeaderRect(
0107:                            DISPLAY_COLUMN_INDEX).width, pref.height);
0108:                }
0109:            }
0110:
0111:            // ---------------------------------------------------------------------------------------
0112:            // Model for the table
0113:            private class ThreadsTableModel extends AbstractTableModel {
0114:                //~ Methods --------------------------------------------------------------------------------------------------------------
0115:
0116:                public Class getColumnClass(int column) {
0117:                    // The main purpose of this method is to make numeric values aligned properly inside table cells
0118:                    switch (column) {
0119:                    case NAME_COLUMN_INDEX:
0120:                        return ThreadNameCellRenderer.class;
0121:                    case DISPLAY_COLUMN_INDEX:
0122:                        return ThreadStateCellRenderer.class;
0123:                    default:
0124:                        return String.class;
0125:                    }
0126:                }
0127:
0128:                public int getColumnCount() {
0129:                    return 2;
0130:                }
0131:
0132:                /**
0133:                 * Returns a default name for the column using spreadsheet conventions:
0134:                 * A, B, C, ... Z, AA, AB, etc.  If <code>column</code> cannot be found,
0135:                 * returns an empty string.
0136:                 *
0137:                 * @param column the column being queried
0138:                 * @return a string containing the default name of <code>column</code>
0139:                 */
0140:                public String getColumnName(int column) {
0141:                    switch (column) {
0142:                    case NAME_COLUMN_INDEX:
0143:                        return THREADS_COLUMN_NAME;
0144:                    case DISPLAY_COLUMN_INDEX:
0145:                        return TIMELINE_COLUMN_NAME;
0146:                    default:
0147:                        return null;
0148:                    }
0149:                }
0150:
0151:                public int getRowCount() {
0152:                    //return manager.getThreadsCount();
0153:                    return filteredDataToDataIndex.size();
0154:                }
0155:
0156:                public Object getValueAt(int rowIndex, int columnIndex) {
0157:                    switch (columnIndex) {
0158:                    case NAME_COLUMN_INDEX:
0159:                        return (Integer) (filteredDataToDataIndex.get(rowIndex));
0160:                    case DISPLAY_COLUMN_INDEX:
0161:                        return getThreadData(((Integer) (filteredDataToDataIndex
0162:                                .get(rowIndex))).intValue());
0163:                    default:
0164:                        return null;
0165:                    }
0166:                }
0167:            }
0168:
0169:            //~ Static fields/initializers -----------------------------------------------------------------------------------------------
0170:
0171:            // -----
0172:            // I18N String constants
0173:            private static final ResourceBundle messages = ResourceBundle
0174:                    .getBundle("org.netbeans.lib.profiler.ui.threads.Bundle"); // NOI18N
0175:            private static final String VIEW_THREADS_ALL = messages
0176:                    .getString("ThreadsPanel_ViewThreadsAll"); // NOI18N
0177:            private static final String VIEW_THREADS_LIVE = messages
0178:                    .getString("ThreadsPanel_ViewThreadsLive"); // NOI18N
0179:            private static final String VIEW_THREADS_FINISHED = messages
0180:                    .getString("ThreadsPanel_ViewThreadsFinished"); // NOI18N
0181:            private static final String VIEW_THREADS_SELECTION = messages
0182:                    .getString("ThreadsPanel_ViewThreadsSelection"); // NOI18N
0183:            private static final String THREADS_TABLE = messages
0184:                    .getString("ThreadsPanel_ThreadsTable"); // NOI18N
0185:            private static final String ENABLE_THREADS_PROFILING = messages
0186:                    .getString("ThreadsPanel_EnableThreadsProfiling"); // NOI18N
0187:            private static final String ZOOM_IN_TOOLTIP = messages
0188:                    .getString("ThreadsPanel_ZoomInToolTip"); // NOI18N
0189:            private static final String ZOOM_OUT_TOOLTIP = messages
0190:                    .getString("ThreadsPanel_ZoomOutToolTip"); // NOI18N
0191:            private static final String FIXED_SCALE_TOOLTIP = messages
0192:                    .getString("ThreadsPanel_FixedScaleToolTip"); // NOI18N
0193:            private static final String SCALE_TO_FIT_TOOLTIP = messages
0194:                    .getString("ThreadsPanel_ScaleToFitToolTip"); // NOI18N
0195:            private static final String THREADS_MONITORING_DISABLED_1_MSG = messages
0196:                    .getString("ThreadsPanel_ThreadsMonitoringDisabled1Msg"); // NOI18N
0197:            private static final String THREADS_MONITORING_DISABLED_2_MSG = messages
0198:                    .getString("ThreadsPanel_ThreadsMonitoringDisabled2Msg"); // NOI18N
0199:            private static final String NO_PROFILING_MSG = messages
0200:                    .getString("ThreadsPanel_NoProfilingMsg"); // NOI18N
0201:            private static final String THREADS_COLUMN_NAME = messages
0202:                    .getString("ThreadsPanel_ThreadsColumnName"); // NOI18N
0203:            private static final String TIMELINE_COLUMN_NAME = messages
0204:                    .getString("ThreadsPanel_TimelineColumnName"); // NOI18N
0205:            private static final String SELECTED_THREADS_ITEM = messages
0206:                    .getString("ThreadsPanel_SelectedThreadsItem"); // NOI18N
0207:            private static final String THREAD_DETAILS_ITEM = messages
0208:                    .getString("ThreadsPanel_ThreadDetailsItem"); // NOI18N
0209:            private static final String TABLE_ACCESS_NAME = messages
0210:                    .getString("ThreadsPanel_TableAccessName"); // NOI18N
0211:            private static final String TABLE_ACCESS_DESCR = messages
0212:                    .getString("ThreadsPanel_TableAccessDescr"); // NOI18N
0213:            private static final String COMBO_ACCESS_NAME = messages
0214:                    .getString("ThreadsPanel_ComboAccessName"); // NOI18N
0215:            private static final String COMBO_ACCESS_DESCR = messages
0216:                    .getString("ThreadsPanel_ComboAccessDescr"); // NOI18N
0217:            private static final String ENABLE_THREADS_MONITORING_BUTTON_ACCESS_NAME = messages
0218:                    .getString("ThreadsPanel_EnableThreadsMonitoringAccessName"); // NOI18N
0219:            private static final String SHOW_LABEL_TEXT = messages
0220:                    .getString("ThreadsPanel_ShowLabelText"); // NOI18N
0221:            // -----
0222:            private static final int NAME_COLUMN_INDEX = 0;
0223:            private static final int DISPLAY_COLUMN_INDEX = 1;
0224:            private static final int RIGHT_DISPLAY_MARGIN = 20; // extra space [pixels] on the right end of the threads display
0225:            private static final int LEFT_DISPLAY_MARGIN = 20;
0226:            private static final int NAME_COLUMN_WIDTH = 190;
0227:            private static final int MIN_NAME_COLUMN_WIDTH = 55;
0228:
0229:            //~ Instance fields ----------------------------------------------------------------------------------------------------------
0230:
0231:            private ArrayList filteredDataToDataIndex = new ArrayList();
0232:            private CustomTimeLineViewport viewPort;
0233:            private DefaultComboBoxModel comboModel;
0234:            private DefaultComboBoxModel comboModelWithSelection;
0235:            private JButton enableThreadsMonitoringButton;
0236:            private JButton scaleToFitButton;
0237:            private JButton zoomInButton;
0238:            private JButton zoomOutButton;
0239:            private JComboBox threadsSelectionCombo;
0240:            private JLabel enableThreadsMonitoringLabel1;
0241:            private JLabel enableThreadsMonitoringLabel2;
0242:            private JLabel enableThreadsMonitoringLabel3;
0243:            private JLabel monitorLegend;
0244:            private JLabel runningLegend;
0245:            private JLabel sleepingLegend;
0246:            private JLabel waitLegend;
0247:            private JMenuItem showOnlySelectedThreads;
0248:            private JMenuItem showThreadsDetails;
0249:            private JPanel contentPanel; // panel with CardLayout containing threadsTable & enable threads profiling notification and button
0250:            private JPanel notificationPanel;
0251:            private JPopupMenu popupMenu;
0252:            private JScrollBar scrollBar; // scrollbar that is displayed in zoomed mode that allows to scroll in history
0253:            private JScrollPane tableScroll;
0254:            private JTable table; // table that displays individual threads
0255:            private JToolBar buttonsToolBar;
0256:            private ThreadsDataManager manager;
0257:            private ThreadsDetailsCallback detailsCallback;
0258:            private boolean internalChange = false; // prevents cycles in event handling
0259:            private boolean internalScrollbarChange = false;
0260:            private boolean resetPerformed = true;
0261:            private boolean scaleToFit = false;
0262:            private boolean supportsSleepingState; // internal flag indicating that threads monitoring engine correctly reports the "sleeping" state
0263:            private boolean threadsMonitoringEnabled = false;
0264:            private boolean trackingEnd = true;
0265:            private float zoomResolutionPerPixel = 50f;
0266:            private long viewEnd;
0267:            private long viewStart = -1;
0268:
0269:            //~ Constructors -------------------------------------------------------------------------------------------------------------
0270:
0271:            /**
0272:             * Creates a new threads panel that displays threads timeline from data provided
0273:             * by specified ThreadsDataManager.
0274:             * @param manager The provider of threads data
0275:             * @param detailsCallback A handler of displaying additional threads details or null, in which case the
0276:             *                        popup menu action to display details will not be present
0277:             */
0278:            public ThreadsPanel(ThreadsDataManager manager,
0279:                    ThreadsDetailsCallback detailsCallback,
0280:                    boolean supportsSleepingState) {
0281:                this .manager = manager;
0282:                this .detailsCallback = detailsCallback;
0283:                this .supportsSleepingState = supportsSleepingState;
0284:
0285:                // create components
0286:
0287:                // contentPanel for threadsTable and enable threads profiling notification
0288:                contentPanel = new JPanel(new CardLayout());
0289:
0290:                // threads table components
0291:                table = createViewTable();
0292:                table.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);
0293:                table.getAccessibleContext().setAccessibleName(
0294:                        TABLE_ACCESS_NAME);
0295:                table.getAccessibleContext().setAccessibleDescription(
0296:                        TABLE_ACCESS_DESCR);
0297:                table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
0298:                        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
0299:                                "DEFAULT_ACTION"); // NOI18N
0300:                table.getActionMap().put("DEFAULT_ACTION",
0301:                        new AbstractAction() {
0302:                            public void actionPerformed(ActionEvent e) {
0303:                                performDefaultAction();
0304:                            }
0305:                        }); // NOI18N
0306:
0307:                scrollBar = new ThreadsScrollBar();
0308:                zoomInButton = new JButton(
0309:                        new ImageIcon(
0310:                                ThreadsPanel.class
0311:                                        .getResource("/org/netbeans/lib/profiler/ui/resources/zoomIn.png"))); // NOI18N
0312:                zoomOutButton = new JButton(
0313:                        new ImageIcon(
0314:                                ThreadsPanel.class
0315:                                        .getResource("/org/netbeans/lib/profiler/ui/resources/zoomOut.png"))); // NOI18N
0316:                scaleToFitButton = new JButton(
0317:                        new ImageIcon(
0318:                                getClass()
0319:                                        .getResource(
0320:                                                scaleToFit ? "/org/netbeans/lib/profiler/ui/resources/zoom.png"
0321:                                                        : "/org/netbeans/lib/profiler/ui/resources/scaleToFit.png"))); // NOI18N
0322:                comboModel = new DefaultComboBoxModel(new Object[] {
0323:                        VIEW_THREADS_ALL, VIEW_THREADS_LIVE,
0324:                        VIEW_THREADS_FINISHED });
0325:                comboModelWithSelection = new DefaultComboBoxModel(
0326:                        new Object[] { VIEW_THREADS_ALL, VIEW_THREADS_LIVE,
0327:                                VIEW_THREADS_FINISHED, VIEW_THREADS_SELECTION });
0328:                threadsSelectionCombo = new JComboBox(comboModel) {
0329:                    public Dimension getMaximumSize() {
0330:                        return new Dimension(250, getPreferredSize().height);
0331:                    };
0332:                };
0333:                threadsSelectionCombo.getAccessibleContext().setAccessibleName(
0334:                        COMBO_ACCESS_NAME);
0335:                threadsSelectionCombo.getAccessibleContext()
0336:                        .setAccessibleDescription(COMBO_ACCESS_DESCR);
0337:
0338:                JLabel showLabel = new JLabel(SHOW_LABEL_TEXT);
0339:                showLabel
0340:                        .setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
0341:                showLabel.setLabelFor(threadsSelectionCombo);
0342:
0343:                int mnemCharIndex = 0;
0344:                showLabel.setDisplayedMnemonic(showLabel.getText().charAt(
0345:                        mnemCharIndex));
0346:                showLabel.setDisplayedMnemonicIndex(mnemCharIndex);
0347:
0348:                buttonsToolBar = new JToolBar(JToolBar.HORIZONTAL) {
0349:                    public Component add(Component comp) {
0350:                        if (comp instanceof  JButton) {
0351:                            UIUtils.fixButtonUI((JButton) comp);
0352:                        }
0353:
0354:                        return super .add(comp);
0355:                    }
0356:                };
0357:
0358:                JPanel tablePanel = new JPanel();
0359:                JPanel scrollPanel = new JPanel();
0360:                popupMenu = initPopupMenu();
0361:
0362:                // set properties
0363:                zoomInButton.setEnabled(!scaleToFit);
0364:                zoomOutButton.setEnabled(!scaleToFit);
0365:                zoomInButton.setToolTipText(ZOOM_IN_TOOLTIP);
0366:                zoomOutButton.setToolTipText(ZOOM_OUT_TOOLTIP);
0367:                scaleToFitButton
0368:                        .setToolTipText(scaleToFit ? FIXED_SCALE_TOOLTIP
0369:                                : SCALE_TO_FIT_TOOLTIP);
0370:                zoomInButton.getAccessibleContext().setAccessibleName(
0371:                        zoomInButton.getToolTipText());
0372:                zoomOutButton.getAccessibleContext().setAccessibleName(
0373:                        zoomOutButton.getToolTipText());
0374:                scaleToFitButton.getAccessibleContext().setAccessibleName(
0375:                        scaleToFitButton.getToolTipText());
0376:
0377:                table
0378:                        .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0379:                table
0380:                        .setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);
0381:                table
0382:                        .setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);
0383:                table.setShowGrid(false);
0384:                table.setRowMargin(0);
0385:                table.setRowHeight(23);
0386:
0387:                DefaultTableCellRenderer defaultHeaderRenderer = new DefaultTableCellRenderer() {
0388:                    public Component getTableCellRendererComponent(
0389:                            JTable table, Object value, boolean isSelected,
0390:                            boolean hasFocus, int row, int column) {
0391:                        Component component = super 
0392:                                .getTableCellRendererComponent(table, value,
0393:                                        isSelected, hasFocus, row, column);
0394:                        component.setBackground(Color.WHITE);
0395:                        component
0396:                                .setFont(table.getFont().deriveFont(Font.BOLD));
0397:
0398:                        if (component instanceof  JComponent) {
0399:                            ((JComponent) component)
0400:                                    .setBorder(new javax.swing.border.EmptyBorder(
0401:                                            0, 3, 0, 3));
0402:                        }
0403:
0404:                        return component;
0405:                    }
0406:                };
0407:
0408:                table.getTableHeader()
0409:                        .setDefaultRenderer(defaultHeaderRenderer);
0410:                table.getTableHeader().setReorderingAllowed(false);
0411:
0412:                // fix the first column's width, and make the display column resize
0413:                table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
0414:                table.getColumnModel().getColumn(NAME_COLUMN_INDEX)
0415:                        .setMinWidth(MIN_NAME_COLUMN_WIDTH);
0416:                table.getColumnModel().getColumn(NAME_COLUMN_INDEX)
0417:                        .setMaxWidth(1000); // this is for some reason needed for the width to actually work
0418:                table.getColumnModel().getColumn(NAME_COLUMN_INDEX)
0419:                        .setPreferredWidth(NAME_COLUMN_WIDTH);
0420:
0421:                ThreadStateHeaderRenderer headerRenderer = new ThreadStateHeaderRenderer(
0422:                        this );
0423:                headerRenderer.setBackground(Color.WHITE);
0424:                table.getColumnModel().getColumn(DISPLAY_COLUMN_INDEX)
0425:                        .setHeaderRenderer(headerRenderer);
0426:
0427:                TableColumnModel columnModel = table.getColumnModel();
0428:                columnModel.setColumnSelectionAllowed(false);
0429:                columnModel.setColumnMargin(0);
0430:                table.setDefaultRenderer(ThreadNameCellRenderer.class,
0431:                        new ThreadNameCellRenderer(this ));
0432:                table.setDefaultRenderer(ThreadStateCellRenderer.class,
0433:                        new ThreadStateCellRenderer(this ));
0434:                buttonsToolBar.setFloatable(false);
0435:                buttonsToolBar.putClientProperty("JToolBar.isRollover",
0436:                        Boolean.TRUE); // NOI18N
0437:
0438:                // perform layout
0439:                tablePanel.setLayout(new BorderLayout());
0440:                scrollPanel.setLayout(new BorderLayout());
0441:                scrollPanel.setBackground(Color.WHITE);
0442:
0443:                buttonsToolBar.add(zoomInButton);
0444:                buttonsToolBar.add(zoomOutButton);
0445:                buttonsToolBar.add(scaleToFitButton);
0446:                buttonsToolBar.addSeparator();
0447:                buttonsToolBar.add(showLabel);
0448:                buttonsToolBar.add(threadsSelectionCombo);
0449:                scrollPanel.add(scrollBar, BorderLayout.EAST);
0450:
0451:                //
0452:                ThreadStateIcon runningIcon = new ThreadStateIcon(
0453:                        CommonConstants.THREAD_STATUS_RUNNING, 18, 9);
0454:                ThreadStateIcon sleepingIcon = new ThreadStateIcon(
0455:                        CommonConstants.THREAD_STATUS_SLEEPING, 18, 9);
0456:                ThreadStateIcon monitorIcon = new ThreadStateIcon(
0457:                        CommonConstants.THREAD_STATUS_MONITOR, 18, 9);
0458:                ThreadStateIcon waitIcon = new ThreadStateIcon(
0459:                        CommonConstants.THREAD_STATUS_WAIT, 18, 9);
0460:
0461:                runningLegend = new JLabel(
0462:                        CommonConstants.THREAD_STATUS_RUNNING_STRING,
0463:                        runningIcon, SwingConstants.LEADING);
0464:                runningLegend.setBorder(BorderFactory.createEmptyBorder(0, 5,
0465:                        0, 0));
0466:                sleepingLegend = new JLabel(
0467:                        CommonConstants.THREAD_STATUS_SLEEPING_STRING,
0468:                        sleepingIcon, SwingConstants.LEADING);
0469:                sleepingLegend.setBorder(BorderFactory.createEmptyBorder(0, 5,
0470:                        0, 0));
0471:                waitLegend = new JLabel(
0472:                        CommonConstants.THREAD_STATUS_WAIT_STRING, waitIcon,
0473:                        SwingConstants.LEADING);
0474:                waitLegend.setBorder(BorderFactory
0475:                        .createEmptyBorder(0, 5, 0, 0));
0476:                monitorLegend = new JLabel(
0477:                        CommonConstants.THREAD_STATUS_MONITOR_STRING,
0478:                        monitorIcon, SwingConstants.LEADING);
0479:                monitorLegend.setBorder(BorderFactory.createEmptyBorder(0, 5,
0480:                        0, 0));
0481:
0482:                JPanel legendPanel = new JPanel();
0483:                legendPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0,
0484:                        0));
0485:                legendPanel.add(runningLegend);
0486:                legendPanel.add(sleepingLegend);
0487:
0488:                if (!supportsSleepingState) {
0489:                    sleepingLegend.setVisible(false);
0490:                }
0491:
0492:                legendPanel.add(waitLegend);
0493:                legendPanel.add(monitorLegend);
0494:
0495:                //legendPanel.add(unknownLegend);
0496:                JPanel bottomPanel = new JPanel();
0497:                bottomPanel.setLayout(new BorderLayout());
0498:                bottomPanel.add(legendPanel, BorderLayout.EAST);
0499:
0500:                //scrollPanel.add(bottomPanel, BorderLayout.SOUTH);
0501:                JPanel dataPanel = new JPanel();
0502:                dataPanel.setLayout(new BorderLayout());
0503:                dataPanel
0504:                        .setBorder(BorderFactory
0505:                                .createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
0506:
0507:                tableScroll = new JScrollPane();
0508:                tableScroll.setBorder(new javax.swing.border.EmptyBorder(0, 0,
0509:                        0, 0));
0510:                tableScroll.setCorner(JScrollPane.UPPER_RIGHT_CORNER,
0511:                        new JPanel());
0512:                tableScroll.getCorner(JScrollPane.UPPER_RIGHT_CORNER)
0513:                        .setBackground(Color.WHITE);
0514:                viewPort = new CustomTimeLineViewport(this );
0515:                viewPort.setView(table);
0516:                viewPort.setBackground(table.getBackground());
0517:                tableScroll.setViewport(viewPort);
0518:                tableScroll
0519:                        .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0520:                tableScroll
0521:                        .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
0522:                dataPanel.add(tableScroll, BorderLayout.CENTER);
0523:                dataPanel.add(scrollPanel, BorderLayout.SOUTH);
0524:                tablePanel.add(dataPanel, BorderLayout.CENTER);
0525:                tablePanel.add(bottomPanel, BorderLayout.SOUTH);
0526:
0527:                // enable threads profiling components
0528:                notificationPanel = new JPanel(new FlowLayout(
0529:                        FlowLayout.LEADING, 0, 15));
0530:                notificationPanel.setBorder(dataPanel.getBorder());
0531:                notificationPanel.setBackground(table.getBackground());
0532:
0533:                Border myRolloverBorder = new CompoundBorder(
0534:                        new FlatToolBar.FlatRolloverButtonBorder(Color.GRAY,
0535:                                Color.LIGHT_GRAY),
0536:                        new FlatToolBar.FlatMarginBorder());
0537:
0538:                enableThreadsMonitoringLabel1 = new JLabel(
0539:                        THREADS_MONITORING_DISABLED_1_MSG);
0540:                enableThreadsMonitoringLabel1.setBorder(BorderFactory
0541:                        .createEmptyBorder(20, 20, 20, 3));
0542:                enableThreadsMonitoringLabel1.setForeground(Color.DARK_GRAY);
0543:
0544:                enableThreadsMonitoringButton = new JButton(
0545:                        new ImageIcon(
0546:                                getClass()
0547:                                        .getResource(
0548:                                                "/org/netbeans/lib/profiler/ui/resources/threadsView.png"))); // NOI18N
0549:                enableThreadsMonitoringButton.setContentAreaFilled(false);
0550:                enableThreadsMonitoringButton.setMargin(new Insets(3, 3, 0, 0));
0551:                enableThreadsMonitoringButton
0552:                        .setVerticalTextPosition(SwingConstants.BOTTOM);
0553:                enableThreadsMonitoringButton
0554:                        .setHorizontalTextPosition(SwingConstants.CENTER);
0555:                enableThreadsMonitoringButton.setRolloverEnabled(true);
0556:                enableThreadsMonitoringButton.setBorder(myRolloverBorder);
0557:                enableThreadsMonitoringButton.getAccessibleContext()
0558:                        .setAccessibleName(
0559:                                ENABLE_THREADS_MONITORING_BUTTON_ACCESS_NAME);
0560:
0561:                enableThreadsMonitoringLabel2 = new JLabel(
0562:                        THREADS_MONITORING_DISABLED_2_MSG);
0563:                enableThreadsMonitoringLabel2.setBorder(BorderFactory
0564:                        .createEmptyBorder(20, 3, 20, 0));
0565:                enableThreadsMonitoringLabel2.setForeground(Color.DARK_GRAY);
0566:
0567:                enableThreadsMonitoringLabel3 = new JLabel(NO_PROFILING_MSG);
0568:                enableThreadsMonitoringLabel3.setBorder(BorderFactory
0569:                        .createEmptyBorder(20, 20, 20, 0));
0570:                enableThreadsMonitoringLabel3.setForeground(Color.DARK_GRAY);
0571:                enableThreadsMonitoringLabel3.setVisible(false);
0572:
0573:                notificationPanel.add(enableThreadsMonitoringLabel1);
0574:                notificationPanel.add(enableThreadsMonitoringButton);
0575:                notificationPanel.add(enableThreadsMonitoringLabel2);
0576:                notificationPanel.add(enableThreadsMonitoringLabel3);
0577:
0578:                setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
0579:                setLayout(new BorderLayout());
0580:
0581:                contentPanel.add(notificationPanel, ENABLE_THREADS_PROFILING);
0582:                contentPanel.add(tablePanel, THREADS_TABLE);
0583:
0584:                add(buttonsToolBar, BorderLayout.NORTH);
0585:                add(contentPanel, BorderLayout.CENTER);
0586:
0587:                scrollBar.addAdjustmentListener(this );
0588:                zoomInButton.addActionListener(this );
0589:                zoomOutButton.addActionListener(this );
0590:                scaleToFitButton.addActionListener(this );
0591:                threadsSelectionCombo.addActionListener(this );
0592:                showOnlySelectedThreads.addActionListener(this );
0593:
0594:                if (detailsCallback != null) {
0595:                    showThreadsDetails.addActionListener(this );
0596:                }
0597:
0598:                table.getColumnModel().addColumnModelListener(this );
0599:                table.addComponentListener(new ComponentAdapter() {
0600:                    public void componentResized(ComponentEvent e) {
0601:                        refreshViewData();
0602:                        updateScrollbar();
0603:                        updateZoomButtonsEnabledState();
0604:                        ThreadsPanel.this .revalidate();
0605:                    }
0606:                });
0607:
0608:                table.addKeyListener(new KeyAdapter() {
0609:                    public void keyPressed(KeyEvent e) {
0610:                        if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)
0611:                                || ((e.getKeyCode() == KeyEvent.VK_F10) && (e
0612:                                        .getModifiers() == InputEvent.SHIFT_MASK))) {
0613:                            int selectedRow = table.getSelectedRow();
0614:
0615:                            if (selectedRow != -1) {
0616:                                Rectangle cellRect = table.getCellRect(
0617:                                        selectedRow, 0, false);
0618:                                popupMenu
0619:                                        .show(
0620:                                                e.getComponent(),
0621:                                                ((cellRect.x + table.getSize().width) > 50) ? 50
0622:                                                        : 5, cellRect.y);
0623:                            }
0624:                        }
0625:                    }
0626:                });
0627:
0628:                table.addMouseListener(new MouseAdapter() {
0629:                    public void mousePressed(MouseEvent e) {
0630:                        if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
0631:                            int line = table.rowAtPoint(e.getPoint());
0632:
0633:                            if ((line != -1) && (!table.isRowSelected(line))) {
0634:                                if (e.isControlDown()) {
0635:                                    table.addRowSelectionInterval(line, line);
0636:                                } else {
0637:                                    table.setRowSelectionInterval(line, line);
0638:                                }
0639:                            }
0640:                        }
0641:                    }
0642:
0643:                    public void mouseClicked(MouseEvent e) {
0644:                        int clickedLine = table.rowAtPoint(e.getPoint());
0645:
0646:                        if (clickedLine != -1) {
0647:                            if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
0648:                                popupMenu.show(e.getComponent(), e.getX(), e
0649:                                        .getY());
0650:                            } else if ((e.getModifiers() == InputEvent.BUTTON1_MASK)
0651:                                    && (e.getClickCount() == 2)) {
0652:                                performDefaultAction();
0653:                            }
0654:                        }
0655:                    }
0656:                });
0657:                addComponentListener(new ComponentAdapter() {
0658:                    public void componentShown(ComponentEvent e) {
0659:                        // since the data were not processed when this component was not showing,
0660:                        // we need to do the updateState when the component becomes visible
0661:                        dataChanged();
0662:                    }
0663:                });
0664:
0665:                // Disable traversing table cells using TAB and Shift+TAB
0666:                Set keys = new HashSet(
0667:                        table
0668:                                .getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
0669:                keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
0670:                table.setFocusTraversalKeys(
0671:                        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);
0672:
0673:                keys = new HashSet(
0674:                        table
0675:                                .getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
0676:                keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
0677:                        InputEvent.SHIFT_MASK));
0678:                table.setFocusTraversalKeys(
0679:                        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);
0680:
0681:                updateScrollbar();
0682:                updateZoomButtonsEnabledState();
0683:                manager.addDataListener(this );
0684:            }
0685:
0686:            //~ Methods ------------------------------------------------------------------------------------------------------------------
0687:
0688:            public BufferedImage getCurrentViewScreenshot(
0689:                    boolean onlyVisibleArea) {
0690:                if (onlyVisibleArea) {
0691:                    return UIUtils.createScreenshot(tableScroll);
0692:                } else {
0693:                    return UIUtils.createScreenshot(table);
0694:                }
0695:            }
0696:
0697:            public long getDataEnd() {
0698:                return manager.getEndTime();
0699:            }
0700:
0701:            public long getDataStart() {
0702:                return manager.getStartTime();
0703:            }
0704:
0705:            public int getDisplayColumnWidth() {
0706:                return table.getTableHeader().getHeaderRect(
0707:                        DISPLAY_COLUMN_INDEX).width;
0708:            }
0709:
0710:            public String getThreadClassName(int index) {
0711:                return manager.getThreadClassName(index);
0712:            }
0713:
0714:            public ThreadData getThreadData(int index) {
0715:                return manager.getThreadData(index);
0716:            }
0717:
0718:            // ---------------------------------------------------------------------------------------
0719:            // Thread data
0720:            public String getThreadName(int index) {
0721:                return manager.getThreadName(index);
0722:            }
0723:
0724:            public long getViewEnd() {
0725:                return viewEnd;
0726:            }
0727:
0728:            // ---------------------------------------------------------------------------------------
0729:            // View controller
0730:            public long getViewStart() {
0731:                return viewStart;
0732:            }
0733:
0734:            /** Invoked when one of the buttons is pressed */
0735:            public void actionPerformed(ActionEvent e) {
0736:                if (internalChange) {
0737:                    return;
0738:                }
0739:
0740:                if (e.getSource() == scaleToFitButton) {
0741:                    if (!scaleToFit) {
0742:                        scrollBar.setVisible(true);
0743:                        scaleToFitButton
0744:                                .setIcon(new ImageIcon(
0745:                                        ThreadsPanel.class
0746:                                                .getResource("/org/netbeans/lib/profiler/ui/resources/zoom.png"))); // NOI18N
0747:                        scaleToFit = true;
0748:                    } else {
0749:                        scaleToFit = false;
0750:                        scaleToFitButton
0751:                                .setIcon(new ImageIcon(
0752:                                        getClass()
0753:                                                .getResource(
0754:                                                        "/org/netbeans/lib/profiler/ui/resources/scaleToFit.png"))); // NOI18N
0755:                        scrollBar.setVisible(false);
0756:                        scrollBar.setValues(0, 0, 0, 0);
0757:                    }
0758:
0759:                    refreshViewData();
0760:                    updateScrollbar();
0761:                    updateZoomButtonsEnabledState();
0762:                    table.getTableHeader().repaint();
0763:                    viewPort.repaint();
0764:                } else if (e.getSource() == zoomInButton) {
0765:                    zoomInButton.setEnabled(zoomResolutionPerPixel > 0.1);
0766:                    zoomResolutionPerPixel /= 2;
0767:                    refreshViewData();
0768:                    updateScrollbar();
0769:                    updateZoomButtonsEnabledState();
0770:                    table.getTableHeader().repaint();
0771:                    viewPort.repaint();
0772:                } else if (e.getSource() == zoomOutButton) {
0773:                    zoomResolutionPerPixel *= 2;
0774:                    refreshViewData();
0775:                    updateScrollbar();
0776:                    updateZoomButtonsEnabledState();
0777:                    table.getTableHeader().repaint();
0778:                    viewPort.repaint();
0779:                } else if (e.getSource() == threadsSelectionCombo) {
0780:                    if ((threadsSelectionCombo.getModel() == comboModelWithSelection)
0781:                            && (threadsSelectionCombo.getSelectedItem() != VIEW_THREADS_SELECTION)) {
0782:                        internalChange = true;
0783:
0784:                        Object selectedItem = threadsSelectionCombo
0785:                                .getSelectedItem();
0786:                        threadsSelectionCombo.setModel(comboModel);
0787:                        threadsSelectionCombo.setSelectedItem(selectedItem);
0788:                        internalChange = false;
0789:                    }
0790:
0791:                    table.clearSelection();
0792:                    dataChanged();
0793:                } else if (e.getSource() == showOnlySelectedThreads) {
0794:                    for (int i = filteredDataToDataIndex.size() - 1; i >= 0; i--) {
0795:                        if (!table.isRowSelected(i)) {
0796:                            filteredDataToDataIndex.remove(i);
0797:                        }
0798:                    }
0799:
0800:                    threadsSelectionCombo.setModel(comboModelWithSelection);
0801:                    threadsSelectionCombo
0802:                            .setSelectedItem(VIEW_THREADS_SELECTION);
0803:                    table.clearSelection();
0804:                } else if (e.getSource() == showThreadsDetails) {
0805:                    performDefaultAction();
0806:                }
0807:            }
0808:
0809:            // --- Save Current View action support --------------------------------------
0810:            public void addSaveViewAction(AbstractAction saveViewAction) {
0811:                JButton actionButton = buttonsToolBar.add(saveViewAction);
0812:                buttonsToolBar.remove(actionButton);
0813:
0814:                buttonsToolBar.add(actionButton, 0);
0815:                buttonsToolBar.add(new JToolBar.Separator(), 1);
0816:            }
0817:
0818:            // ---------------------------------------------------------------------------------------
0819:            // Handling profiling started & finished and threads monitoring enabled & disabled
0820:            public void addThreadsMonitoringActionListener(
0821:                    ActionListener listener) {
0822:                enableThreadsMonitoringButton.addActionListener(listener);
0823:            }
0824:
0825:            // ---------------------------------------------------------------------------------------
0826:            // Listeners
0827:
0828:            /**
0829:             * Invoked when the scrollbar is moved.
0830:             */
0831:            public void adjustmentValueChanged(AdjustmentEvent e) {
0832:                // we know we are in zoom mode (in scaleToFit, the scrollbar is disabled)
0833:                if (!internalScrollbarChange) {
0834:                    if ((scrollBar.getValue() + scrollBar.getVisibleAmount()) == scrollBar
0835:                            .getMaximum()) {
0836:                        trackingEnd = true;
0837:                    } else {
0838:                        trackingEnd = false;
0839:                        viewStart = manager.getStartTime()
0840:                                + scrollBar.getValue();
0841:                        viewEnd = viewStart
0842:                                + (long) (zoomResolutionPerPixel * table
0843:                                        .getTableHeader().getHeaderRect(
0844:                                                DISPLAY_COLUMN_INDEX).width);
0845:                        ThreadsPanel.this .repaint();
0846:                    }
0847:                }
0848:            }
0849:
0850:            public void columnAdded(TableColumnModelEvent e) {
0851:            } // Ignored
0852:
0853:            /**
0854:             * Tells listeners that a column was moved due to a margin change.
0855:             */
0856:            public void columnMarginChanged(ChangeEvent e) {
0857:                refreshViewData();
0858:                updateScrollbar();
0859:                updateZoomButtonsEnabledState();
0860:
0861:                if (viewPort != null) {
0862:                    viewPort.repaint();
0863:                }
0864:
0865:                scrollBar.invalidate();
0866:                ThreadsPanel.this .revalidate();
0867:            }
0868:
0869:            public void columnMoved(TableColumnModelEvent e) {
0870:            } // Ignored
0871:
0872:            public void columnRemoved(TableColumnModelEvent e) {
0873:            } // Ignored
0874:
0875:            public void columnSelectionChanged(ListSelectionEvent e) {
0876:            } // Ignored
0877:
0878:            /** Called when data in manager change */
0879:            public void dataChanged() {
0880:                UIUtils.runInEventDispatchThread(new Runnable() {
0881:                    public void run() {
0882:                        refreshUI();
0883:                    }
0884:                });
0885:            }
0886:
0887:            public void dataReset() {
0888:                filteredDataToDataIndex.clear();
0889:                UIUtils.runInEventDispatchThread(new Runnable() {
0890:                    public void run() {
0891:                        refreshUI();
0892:                        updateSupportsSleepingState(manager
0893:                                .supportsSleepingStateMonitoring());
0894:                    }
0895:                });
0896:            }
0897:
0898:            public boolean fitsVisibleArea() {
0899:                return !tableScroll.getVerticalScrollBar().isVisible();
0900:            }
0901:
0902:            public boolean hasView() {
0903:                return !notificationPanel.isShowing();
0904:            }
0905:
0906:            public void profilingSessionFinished() {
0907:                enableThreadsMonitoringButton.setEnabled(false);
0908:                enableThreadsMonitoringLabel1.setVisible(false);
0909:                enableThreadsMonitoringLabel2.setVisible(false);
0910:                enableThreadsMonitoringButton.setVisible(false);
0911:                enableThreadsMonitoringLabel3.setVisible(true);
0912:            }
0913:
0914:            public void profilingSessionStarted() {
0915:                enableThreadsMonitoringButton.setEnabled(true);
0916:                enableThreadsMonitoringLabel1.setVisible(true);
0917:                enableThreadsMonitoringLabel2.setVisible(true);
0918:                enableThreadsMonitoringButton.setVisible(true);
0919:                enableThreadsMonitoringLabel3.setVisible(false);
0920:            }
0921:
0922:            public void removeThreadsMonitoringActionListener(
0923:                    ActionListener listener) {
0924:                enableThreadsMonitoringButton.removeActionListener(listener);
0925:            }
0926:
0927:            public void requestFocus() {
0928:                SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component
0929:                            public void run() {
0930:                                if (table != null) {
0931:                                    table.requestFocus();
0932:                                }
0933:                            }
0934:                        });
0935:            }
0936:
0937:            public void threadsMonitoringDisabled() {
0938:                threadsMonitoringEnabled = false;
0939:                ((CardLayout) (contentPanel.getLayout())).show(contentPanel,
0940:                        ENABLE_THREADS_PROFILING);
0941:                updateZoomButtonsEnabledState();
0942:                threadsSelectionCombo.setEnabled(false);
0943:            }
0944:
0945:            public void threadsMonitoringEnabled() {
0946:                threadsMonitoringEnabled = true;
0947:                ((CardLayout) (contentPanel.getLayout())).show(contentPanel,
0948:                        THREADS_TABLE);
0949:                updateZoomButtonsEnabledState();
0950:                threadsSelectionCombo.setEnabled(true);
0951:            }
0952:
0953:            boolean supportsSleepingState() {
0954:                return supportsSleepingState;
0955:            }
0956:
0957:            private JTable createViewTable() {
0958:                return new JExtendedTable(new ThreadsTableModel()) {
0959:                    public void mouseMoved(MouseEvent event) {
0960:                        // Identify table row and column at cursor
0961:                        int row = rowAtPoint(event.getPoint());
0962:                        int column = columnAtPoint(event.getPoint());
0963:
0964:                        // Only celltip for thread name is supported
0965:                        if (getColumnClass(column) != ThreadNameCellRenderer.class) {
0966:                            CellTipManager.sharedInstance().setEnabled(false);
0967:
0968:                            return;
0969:                        }
0970:
0971:                        // Return if table cell is the same as in previous event
0972:                        if ((row == lastRow) && (column == lastColumn)) {
0973:                            return;
0974:                        }
0975:
0976:                        lastRow = row;
0977:                        lastColumn = column;
0978:
0979:                        if ((row < 0) || (column < 0)) {
0980:                            CellTipManager.sharedInstance().setEnabled(false);
0981:
0982:                            return;
0983:                        }
0984:
0985:                        Component cellRenderer = ((ThreadNameCellRenderer) (getCellRenderer(
0986:                                row, column)))
0987:                                .getTableCellRendererComponentPersistent(this ,
0988:                                        getValueAt(row, column), false, false,
0989:                                        row, column);
0990:                        Rectangle cellRect = getCellRect(row, column, false);
0991:
0992:                        // Return if celltip is not supported for the cell
0993:                        if (cellRenderer == null) {
0994:                            CellTipManager.sharedInstance().setEnabled(false);
0995:
0996:                            return;
0997:                        }
0998:
0999:                        int horizontalAlignment = ((ThreadNameCellRenderer) cellRenderer)
1000:                                .getHorizontalAlignment();
1001:
1002:                        if ((horizontalAlignment == SwingConstants.TRAILING)
1003:                                || (horizontalAlignment == SwingConstants.RIGHT)) {
1004:                            rendererRect = new Rectangle(
1005:                                    (cellRect.x + cellRect.width)
1006:                                            - cellRenderer.getPreferredSize().width,
1007:                                    cellRect.y,
1008:                                    cellRenderer.getPreferredSize().width,
1009:                                    cellRenderer.getPreferredSize().height);
1010:                        } else {
1011:                            rendererRect = new Rectangle(cellRect.x,
1012:                                    cellRect.y,
1013:                                    cellRenderer.getPreferredSize().width,
1014:                                    cellRenderer.getPreferredSize().height);
1015:                        }
1016:
1017:                        // Return if cell contents is fully visible
1018:                        if ((rendererRect.x >= cellRect.x)
1019:                                && ((rendererRect.x + rendererRect.width) <= (cellRect.x + cellRect.width))) {
1020:                            CellTipManager.sharedInstance().setEnabled(false);
1021:
1022:                            return;
1023:                        }
1024:
1025:                        while (cellTip.getComponentCount() > 0) {
1026:                            cellTip.remove(0);
1027:                        }
1028:
1029:                        cellTip.add(cellRenderer, BorderLayout.CENTER);
1030:                        cellTip.setPreferredSize(new Dimension(
1031:                                rendererRect.width + 2, getRowHeight(row) + 2));
1032:
1033:                        CellTipManager.sharedInstance().setEnabled(true);
1034:                    }
1035:                };
1036:            }
1037:
1038:            private JPopupMenu initPopupMenu() {
1039:                JPopupMenu popup = new JPopupMenu();
1040:
1041:                showOnlySelectedThreads = new JMenuItem(SELECTED_THREADS_ITEM);
1042:
1043:                if (detailsCallback != null) {
1044:                    Font boldfont = popup.getFont().deriveFont(Font.BOLD);
1045:                    showThreadsDetails = new JMenuItem(THREAD_DETAILS_ITEM);
1046:                    showThreadsDetails.setFont(boldfont);
1047:                    popup.add(showThreadsDetails);
1048:                    popup.add(new JSeparator());
1049:                }
1050:
1051:                popup.add(showOnlySelectedThreads);
1052:
1053:                return popup;
1054:            }
1055:
1056:            private void performDefaultAction() {
1057:                int[] array = table.getSelectedRows();
1058:
1059:                for (int i = 0; i < array.length; i++) {
1060:                    array[i] = ((Integer) filteredDataToDataIndex.get(array[i]))
1061:                            .intValue();
1062:                }
1063:
1064:                ThreadsPanel.this .detailsCallback.showDetails(array);
1065:            }
1066:
1067:            // @AWTBound
1068:            private void refreshUI() {
1069:                if (!isShowing()) {
1070:                    return;
1071:                }
1072:
1073:                updateFilteredData();
1074:                refreshViewData();
1075:                updateScrollbar();
1076:                updateZoomButtonsEnabledState();
1077:                table.invalidate();
1078:                ThreadsPanel.this .revalidate(); // needed to reflect table height increase when new threads appear
1079:                ThreadsPanel.this .repaint(); // needed to paint the table even if no relayout happens
1080:            }
1081:
1082:            /** Updates internal view-related data based on changed conditions (new data, change in layout),
1083:             *  to maintain the view in expected condition after the change.
1084:             */
1085:            private void refreshViewData() {
1086:                if (scaleToFit) {
1087:                    long dataLen = manager.getEndTime()
1088:                            - manager.getStartTime();
1089:                    int viewLen = table.getTableHeader().getHeaderRect(
1090:                            DISPLAY_COLUMN_INDEX).width;
1091:                    float currentResolution = (float) dataLen
1092:                            / Math.max(viewLen - RIGHT_DISPLAY_MARGIN
1093:                                    - LEFT_DISPLAY_MARGIN, 1);
1094:                    viewStart = manager.getStartTime()
1095:                            - (long) (currentResolution * LEFT_DISPLAY_MARGIN);
1096:                    viewEnd = manager.getEndTime()
1097:                            + (long) (currentResolution * RIGHT_DISPLAY_MARGIN);
1098:                } else {
1099:                    long rightMarginInTime = (long) (zoomResolutionPerPixel * RIGHT_DISPLAY_MARGIN);
1100:                    long leftMarginInTime = (long) (zoomResolutionPerPixel * LEFT_DISPLAY_MARGIN);
1101:                    long widthInTime = (long) (zoomResolutionPerPixel * table
1102:                            .getTableHeader().getHeaderRect(
1103:                                    DISPLAY_COLUMN_INDEX).width);
1104:
1105:                    if (viewStart == -1) { // the first data came
1106:                        viewStart = manager.getStartTime() - leftMarginInTime;
1107:                        viewEnd = viewStart + widthInTime;
1108:                    }
1109:
1110:                    if (trackingEnd) {
1111:                        viewEnd = manager.getEndTime() + rightMarginInTime;
1112:                        viewStart = viewEnd - widthInTime;
1113:
1114:                        if (viewStart < (manager.getStartTime() - leftMarginInTime)) { // data do not fill display yet
1115:                            viewStart = manager.getStartTime()
1116:                                    - leftMarginInTime;
1117:                            viewEnd = viewStart + widthInTime;
1118:                        }
1119:                    } else {
1120:                        if (viewStart < manager.getStartTime()) {
1121:                            viewStart = manager.getStartTime()
1122:                                    - rightMarginInTime;
1123:                        }
1124:
1125:                        viewEnd = viewStart + widthInTime;
1126:                    }
1127:                }
1128:            }
1129:
1130:            /** Creates new filteredDataToDataIndex according to the current filter criterion */
1131:            private void updateFilteredData() {
1132:                if (threadsSelectionCombo.getSelectedItem() == VIEW_THREADS_SELECTION) {
1133:                    return; // do nothing, data already filtered
1134:                }
1135:
1136:                filteredDataToDataIndex.clear();
1137:
1138:                for (int i = 0; i < manager.getThreadsCount(); i++) {
1139:                    // view all threads
1140:                    if (threadsSelectionCombo.getSelectedItem().equals(
1141:                            VIEW_THREADS_ALL)) {
1142:                        filteredDataToDataIndex.add(new Integer(i));
1143:
1144:                        continue;
1145:                    }
1146:
1147:                    // view live threads
1148:                    if (threadsSelectionCombo.getSelectedItem().equals(
1149:                            VIEW_THREADS_LIVE)) {
1150:                        ThreadData threadData = manager.getThreadData(i);
1151:
1152:                        if (threadData.size() > 0) {
1153:                            byte state = threadData.getLastState();
1154:
1155:                            if (state != CommonConstants.THREAD_STATUS_ZOMBIE) {
1156:                                filteredDataToDataIndex.add(new Integer(i));
1157:                            }
1158:                        }
1159:
1160:                        continue;
1161:                    }
1162:
1163:                    // view finished threads
1164:                    if (threadsSelectionCombo.getSelectedItem().equals(
1165:                            VIEW_THREADS_FINISHED)) {
1166:                        ThreadData threadData = manager.getThreadData(i);
1167:
1168:                        if (threadData.size() > 0) {
1169:                            byte state = threadData.getLastState();
1170:
1171:                            if (state == CommonConstants.THREAD_STATUS_ZOMBIE) {
1172:                                filteredDataToDataIndex.add(new Integer(i));
1173:                            }
1174:                        } else {
1175:                            // No state defined -> THREAD_STATUS_ZOMBIE assumed (thread could finish when monitoring was disabled)
1176:                            filteredDataToDataIndex.add(new Integer(i));
1177:                        }
1178:
1179:                        continue;
1180:                    }
1181:                }
1182:            }
1183:
1184:            private void updateScrollbar() {
1185:                internalScrollbarChange = true;
1186:
1187:                if (scrollBar.isVisible() == scaleToFit) {
1188:                    scrollBar.setVisible(!scaleToFit);
1189:                }
1190:
1191:                if (!scaleToFit) {
1192:                    int rightMarginInTime = (int) (zoomResolutionPerPixel * RIGHT_DISPLAY_MARGIN);
1193:                    int leftMarginInTime = (int) (zoomResolutionPerPixel * RIGHT_DISPLAY_MARGIN);
1194:
1195:                    int value = (int) (viewStart - manager.getStartTime())
1196:                            + leftMarginInTime;
1197:                    int extent = (int) (viewEnd - viewStart);
1198:                    int intMax = (int) (manager.getEndTime() - manager
1199:                            .getStartTime())
1200:                            + rightMarginInTime;
1201:
1202:                    //      System.out.println("max: "+intMax);
1203:                    //      System.out.println("value: "+value);
1204:                    //      System.out.println("extent: "+extent);
1205:                    boolean shouldBeVisible = true;
1206:
1207:                    if ((value == 0) && ((intMax - (value + extent)) <= 0)) {
1208:                        shouldBeVisible = false;
1209:                    }
1210:
1211:                    if (scrollBar.isVisible() != shouldBeVisible) {
1212:                        scrollBar.setVisible(shouldBeVisible);
1213:                    }
1214:
1215:                    if (shouldBeVisible) {
1216:                        scrollBar.setValues(value, extent, -leftMarginInTime,
1217:                                intMax);
1218:                        scrollBar.setBlockIncrement((int) (extent * 0.95f));
1219:                        scrollBar.setUnitIncrement(Math.max(
1220:                                (int) (zoomResolutionPerPixel * 5), 1)); // at least 1
1221:                    }
1222:                }
1223:
1224:                internalScrollbarChange = false;
1225:            }
1226:
1227:            // ---------------------------------------------------------------------------------------
1228:            // Sleeping state support
1229:            private void updateSupportsSleepingState(
1230:                    boolean supportsSleepingState) {
1231:                if (this .supportsSleepingState != supportsSleepingState) {
1232:                    this .supportsSleepingState = supportsSleepingState;
1233:                    sleepingLegend.setVisible(supportsSleepingState);
1234:                }
1235:            }
1236:
1237:            /*  public static void main(String[] args) {
1238:               JFrame frame = new JFrame("Threads view test");
1239:               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
1240:               frame.getContentPane().setLayout(new BorderLayout());
1241:               ThreadsDataManager threadsManager = new ThreadsDataManager();
1242:               frame.getContentPane().add(new ThreadsPanel(threadsManager, null, true), BorderLayout.CENTER);
1243:               frame.setSize(800, 600);
1244:               frame.show();
1245:               }
1246:             */
1247:
1248:            // ---------------------------------------------------------------------------------------
1249:            // Private methods
1250:            private void updateZoomButtonsEnabledState() {
1251:                if (!threadsMonitoringEnabled) {
1252:                    zoomInButton.setEnabled(false);
1253:                    zoomOutButton.setEnabled(false);
1254:                    scaleToFitButton.setEnabled(false);
1255:                } else {
1256:                    if (scaleToFit) {
1257:                        zoomInButton.setEnabled(false);
1258:                        zoomOutButton.setEnabled(false);
1259:                    } else {
1260:                        zoomInButton.setEnabled(zoomResolutionPerPixel > 0.1);
1261:
1262:                        // zoom out is enabled up until the actual data only cover 1/4 of the display area
1263:                        int viewWidth = table.getTableHeader().getHeaderRect(
1264:                                DISPLAY_COLUMN_INDEX).width;
1265:                        zoomOutButton
1266:                                .setEnabled((zoomResolutionPerPixel * viewWidth) < (2f * (manager
1267:                                        .getEndTime() - manager.getStartTime())));
1268:                    }
1269:
1270:                    scaleToFitButton.setEnabled(true);
1271:                    scaleToFitButton
1272:                            .setToolTipText(scaleToFit ? FIXED_SCALE_TOOLTIP
1273:                                    : SCALE_TO_FIT_TOOLTIP);
1274:                }
1275:            }
1276:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.