/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.visualvm.modules.tracer.impl.timeline; import com.sun.tools.visualvm.modules.tracer.TracerProbe; import com.sun.tools.visualvm.modules.tracer.impl.probes.ProbePresenter; import com.sun.tools.visualvm.modules.tracer.impl.swing.HeaderButton; import com.sun.tools.visualvm.modules.tracer.impl.swing.HeaderLabel; import com.sun.tools.visualvm.modules.tracer.impl.swing.ScrollBar; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.LayoutManager; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollBar; import javax.swing.JViewport; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import org.netbeans.lib.profiler.charts.ChartConfigurationListener; import org.netbeans.lib.profiler.charts.swing.Utils; import org.openide.util.ImageUtilities; /** * * @author Jiri Sedlacek */ final class ProbesPanel extends JPanel { private static final String INCREMENT_IMAGE_PATH = "com/sun/tools/visualvm/modules/tracer/impl/resources/increment.png"; // NOI18N private static final String DECREMENT_IMAGE_PATH = "com/sun/tools/visualvm/modules/tracer/impl/resources/decrement.png"; // NOI18N private static final String RESET_IMAGE_PATH = "com/sun/tools/visualvm/modules/tracer/impl/resources/reset.png"; // NOI18N private final ListPanel listPanel; private final JViewport viewport; private final HeaderButton increaseB; private final HeaderButton decreaseB; private final HeaderButton resetB; ProbesPanel(final TimelineSupport support) { final TimelineChart chart = support.getChart(); listPanel = new ListPanel(new VerticalTimelineLayout(chart)) { public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.height = Utils.checkedInt(chart.getChartContext().getViewHeight()); return d; } protected void updateSelection() { int count = getComponentCount(); for (int i = 0; i < count; i++) ((ProbePresenter)getComponent(i)).setSelected( chart.isRowSelected(chart.getRow(i))); } }; viewport = new JViewport() { public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); p.y += getViewPosition().y; return listPanel.getToolTipText(p); } }; ToolTipManager.sharedInstance().registerComponent(viewport); viewport.setOpaque(true); viewport.setBackground(new Color(247, 247, 247)); viewport.setView(listPanel); viewport.setViewPosition(new Point(0, 0)); final ViewportUpdater updater = new ViewportUpdater(viewport); chart.addConfigurationListener(new ChartConfigurationListener.Adapter() { public void contentsWillBeUpdated(long offsetX, final long offsetY, double scaleX, double scaleY, long lastOffsetX, final long lastOffsetY, double lastScaleX, double lastScaleY) { if (lastOffsetY != offsetY) SwingUtilities.invokeLater(updater.forPoint(new Point( 0, Utils.checkedInt(offsetY)))); } }); final JPanel bottomPanel = new JPanel(new GridLayout(1, 3)); bottomPanel.setPreferredSize(new Dimension(100, new ScrollBar(JScrollBar. HORIZONTAL).getPreferredSize().height)); bottomPanel.setOpaque(false); increaseB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage( INCREMENT_IMAGE_PATH))) { protected void performAction(ActionEvent e) { chart.increaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit(). getMenuShortcutKeyMask()) == 0); } }; increaseB.setToolTipText("Increase rows height"); bottomPanel.add(increaseB); decreaseB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage( DECREMENT_IMAGE_PATH))) { protected void performAction(ActionEvent e) { chart.decreaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit(). getMenuShortcutKeyMask()) == 0); } }; decreaseB.setToolTipText("Decrease rows height"); bottomPanel.add(decreaseB); resetB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage( RESET_IMAGE_PATH))) { protected void performAction(ActionEvent e) { chart.resetRowHeights(); } }; resetB.setToolTipText("Reset rows height"); bottomPanel.add(resetB); setOpaque(false); setLayout(new BorderLayout()); add(new HeaderLabel("Probes"), BorderLayout.NORTH); add(viewport, BorderLayout.CENTER); add(bottomPanel, BorderLayout.SOUTH); chart.addRowListener(new TimelineChart.RowListener() { public void rowsAdded(List<TimelineChart.Row> rows) { for (TimelineChart.Row row : rows) { TracerProbe probe = support.getProbe(row); listPanel.add(new ProbePresenter(probe, support. getDescriptor(probe)), row.getIndex()); } listPanel.sync(); revalidate(); repaint(); refreshButtons(true); } public void rowsRemoved(List<TimelineChart.Row> rows) { for (TimelineChart.Row row : rows) listPanel.remove(row.getIndex()); listPanel.sync(); revalidate(); repaint(); refreshButtons(chart.hasRows()); } public void rowsResized(List<TimelineChart.Row> rows) { listPanel.sync(); revalidate(); repaint(); } }); refreshButtons(chart.hasRows()); } public void setCursor(Cursor cursor) { viewport.setCursor(cursor); } Component getMouseTarget() { return viewport; } void updateSelection() { listPanel.updateSelection(); } private void refreshButtons(boolean enabled) { increaseB.setEnabled(enabled); decreaseB.setEnabled(enabled); resetB.setEnabled(enabled); } private static class ViewportUpdater implements Runnable { private final JViewport viewport; private Point point; ViewportUpdater(JViewport viewport) { this.viewport = viewport; } Runnable forPoint(Point point) { this.point = point; return this; } public void run() { viewport.setViewPosition(point); } } private static class ListPanel extends JPanel { ListPanel(LayoutManager layout) { super(layout); setOpaque(false); } protected void updateSelection() { } String getToolTipText(Point p) { String tooltip = null; Component c = getComponentAt(p); if (c instanceof JComponent) tooltip = (String)((JComponent)c).getClientProperty("ToolTipHelper"); // NOI18N return tooltip; } private void sync() { doLayout(); repaint(); } } }