/*
* 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.profiling.presets;
import com.sun.tools.visualvm.core.ui.components.Spacer;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.lib.profiler.common.ProfilingSettings;
import org.netbeans.lib.profiler.common.ProfilingSettingsPresets;
import org.netbeans.lib.profiler.common.filters.FilterUtils;
import org.netbeans.lib.profiler.common.filters.SimpleFilter;
import org.netbeans.lib.profiler.global.CommonConstants;
import org.openide.awt.Mnemonics;
import org.openide.util.NbBundle;
/**
*
* @author Jiri Sedlacek
*/
public abstract class SamplerCPUPanel extends JPanel {
private JRadioButton inclFilterRadioButton;
private JRadioButton exclFilterRadioButton;
private TextAreaComponent filtersArea;
private JLabel sampleRateLabel;
private JComboBox sampleRateCombo;
private JLabel sampleRateUnitsLabel;
private JLabel refreshRateLabel;
private JLabel refreshUnitsLabel;
private JComboBox refreshRateCombo;
private final Runnable validator;
private boolean filtersValid = true;
private boolean internalChange;
public SamplerCPUPanel() {
this(null, false);
}
SamplerCPUPanel(Runnable validator, boolean mnemonics) {
this.validator = validator;
initComponents(mnemonics);
}
public ProfilingSettings getSettings() {
ProfilingSettings settings = ProfilingSettingsPresets.createCPUPreset();
settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);
String instrFilterString = getFilterValue();
SimpleFilter instrFilter = (instrFilterString.length() == 0 ||
"*".equals(instrFilterString)) ? SimpleFilter.NO_FILTER : // NOI18N
new SimpleFilter(instrFilterString, inclFilterRadioButton.isSelected() ?
SimpleFilter.SIMPLE_FILTER_INCLUSIVE : SimpleFilter.SIMPLE_FILTER_EXCLUSIVE,
instrFilterString);
settings.setSelectedInstrumentationFilter(instrFilter);
return settings;
}
public int getSamplingRate() {
return (Integer)sampleRateCombo.getSelectedItem();
}
public int getRefreshRate() {
return (Integer)refreshRateCombo.getSelectedItem();
}
public boolean settingsValid() { return filtersValid; }
public void loadFromPreset(ProfilerPreset preset) {
if (preset == null) return;
internalChange = true;
inclFilterRadioButton.setSelected(!preset.getFilterModeS());
exclFilterRadioButton.setSelected(preset.getFilterModeS());
filtersArea.getTextArea().setText(preset.getFilterS());
sampleRateCombo.setSelectedItem(preset.getSamplingRateS());
refreshRateCombo.setSelectedItem(preset.getRefreshRateS());
internalChange = false;
}
public void saveToPreset(ProfilerPreset preset) {
if (preset == null) return;
preset.setFilterModeS(exclFilterRadioButton.isSelected());
preset.setFilterS(filtersArea.getTextArea().getText());
preset.setSamplingRateS((Integer)sampleRateCombo.getSelectedItem());
preset.setRefreshRateS((Integer)refreshRateCombo.getSelectedItem());
}
public abstract void settingsChanged();
private void syncUI() {
if (internalChange) return;
settingsChanged();
}
private void checkFilterValidity() {
filtersValid = isFilterValueValid();
filtersArea.getTextArea().setForeground(filtersValid ?
UIManager.getColor("TextArea.foreground") : Color.RED); // NOI18N
if (validator != null) validator.run();
}
public boolean isFilterValueValid() {
String[] filterParts = FilterUtils.getSeparateFilters(getFilterValue());
for (int i = 0; i < filterParts.length; i++)
if (!FilterUtils.isValidProfilerFilter(filterParts[i])) return false;
return true;
}
private String getFilterValue() {
StringBuilder convertedValue = new StringBuilder();
String[] filterValues = getFilterValues();
for (int i = 0; i < filterValues.length; i++) {
String filterValue = filterValues[i].trim();
if ((i != (filterValues.length - 1)) && !filterValue.endsWith(",")) { // NOI18N
filterValue = filterValue + ", "; // NOI18N
}
convertedValue.append(filterValue);
}
return convertedValue.toString();
}
private String[] getFilterValues() {
return filtersArea.getTextArea().getText().split("\\n"); // NOI18N
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for (Component c : getComponents()) c.setEnabled(enabled);
}
private void initComponents(boolean mnemonics) {
setOpaque(false);
setLayout(new GridBagLayout());
ButtonGroup filterRadiosGroup = new ButtonGroup();
GridBagConstraints constraints;
JLabel referenceLabel = new JLabel("X"); // NOI18N
JPanel radiosPanel = new JPanel(new GridBagLayout()) {
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for (Component c : getComponents())
c.setEnabled(enabled);
}
};
radiosPanel.setOpaque(false);
constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 4;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(0, 0, 0, 0);
add(radiosPanel, constraints);
inclFilterRadioButton = new JRadioButton() {
protected void fireActionPerformed(ActionEvent e) { syncUI(); }
};
setText(inclFilterRadioButton, NbBundle.getMessage(SamplerCPUPanel.class,
"LBL_Profile_Incl_S"), mnemonics); // NOI18N
inclFilterRadioButton.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Inclusive_Filter_S")); // NOI18N
inclFilterRadioButton.setOpaque(false);
inclFilterRadioButton.setBorder(referenceLabel.getBorder());
Dimension d1 = inclFilterRadioButton.getPreferredSize();
d1.height = Math.max(d1.height, referenceLabel.getPreferredSize().height);
inclFilterRadioButton.setPreferredSize(d1);
filterRadiosGroup.add(inclFilterRadioButton);
constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(10, 10, 5, 5);
radiosPanel.add(inclFilterRadioButton, constraints);
exclFilterRadioButton = new JRadioButton() {
protected void fireActionPerformed(ActionEvent e) { syncUI(); }
};
setText(exclFilterRadioButton, NbBundle.getMessage(SamplerCPUPanel.class,
"LBL_Profile_Excl_S"), mnemonics); // NOI18N
exclFilterRadioButton.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Exclusive_Filter_S")); // NOI18N
exclFilterRadioButton.setOpaque(false);
exclFilterRadioButton.setBorder(referenceLabel.getBorder());
Dimension d2 = exclFilterRadioButton.getPreferredSize();
d2.height = Math.max(d2.height, referenceLabel.getPreferredSize().height);
exclFilterRadioButton.setPreferredSize(d2);
filterRadiosGroup.add(exclFilterRadioButton);
constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = 0;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(10, 5, 5, 10);
radiosPanel.add(exclFilterRadioButton, constraints);
constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = 0;
constraints.weightx = 1;
constraints.weighty = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets = new Insets(10, 0, 5, 0);
radiosPanel.add(Spacer.create(), constraints);
filtersArea = createTextArea(2);
filtersArea.getTextArea().setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Instrumentation_Filter")); // NOI18N
filtersArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }
public void removeUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }
public void changedUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }
});
constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 5;
constraints.weightx = 1;
constraints.weighty = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.NORTHWEST;
constraints.fill = GridBagConstraints.BOTH;
constraints.insets = new Insets(0, 10, 10, 10);
add(filtersArea, constraints);
sampleRateLabel = new JLabel();
setText(sampleRateLabel, NbBundle.getMessage(SamplerCPUPanel.class,
"LBL_Sampling_rate"), mnemonics); // NOI18N
sampleRateLabel.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Sampling_rate")); // NOI18N
constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 6;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(5, 10, 5, 5);
add(sampleRateLabel, constraints);
Integer[] samplingRates =
new Integer[] { 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000 };
sampleRateCombo = new JComboBox(samplingRates) {
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getMaximumSize() { return getPreferredSize(); }
};
sampleRateLabel.setLabelFor(sampleRateCombo);
sampleRateCombo.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Sampling_rate")); // NOI18N
sampleRateCombo.setEditable(false);
sampleRateCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { syncUI(); }
});
sampleRateCombo.setRenderer(new ComboRenderer(sampleRateCombo));
constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = 6;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(5, 0, 5, 5);
add(sampleRateCombo, constraints);
sampleRateUnitsLabel = new JLabel(NbBundle.getMessage(
SamplerCPUPanel.class, "LBL_units_ms")); // NOI18N
sampleRateUnitsLabel.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Sampling_rate")); // NOI18N
constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = 6;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(5, 0, 5, 5);
add(sampleRateUnitsLabel, constraints);
constraints = new GridBagConstraints();
constraints.gridx = 3;
constraints.gridy = 6;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets = new Insets(5, 0, 5, 0);
add(Spacer.create(), constraints);
refreshRateLabel = new JLabel();
setText(refreshRateLabel, NbBundle.getMessage(SamplerCPUPanel.class,
"LBL_Refresh_rate"), mnemonics); // NOI18N
refreshRateLabel.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Refresh_rate")); // NOI18N
constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 7;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(1, 10, 10, 5);
add(refreshRateLabel, constraints);
Integer[] refreshRates = new Integer[] { 100, 200, 500, 1000, 2000, 5000, 10000 };
refreshRateCombo = new JComboBox(refreshRates) {
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getMaximumSize() { return getPreferredSize(); }
};
refreshRateLabel.setLabelFor(refreshRateCombo);
refreshRateCombo.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Refresh_rate")); // NOI18N
refreshRateCombo.setEditable(false);
refreshRateCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { syncUI(); }
});
refreshRateCombo.setRenderer(new ComboRenderer(refreshRateCombo));
constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = 7;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(1, 0, 10, 5);
add(refreshRateCombo, constraints);
refreshUnitsLabel = new JLabel(NbBundle.getMessage(
SamplerCPUPanel.class, "LBL_units_ms")); // NOI18N
refreshUnitsLabel.setToolTipText(NbBundle.getMessage(
SamplerCPUPanel.class, "TOOLTIP_Refresh_rate")); // NOI18N
constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = 7;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(1, 0, 10, 5);
add(refreshUnitsLabel, constraints);
constraints = new GridBagConstraints();
constraints.gridx = 3;
constraints.gridy = 7;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets = new Insets(1, 0, 10, 0);
add(Spacer.create(), constraints);
}
private static void setText(JLabel l, String text, boolean mnemonics) {
if (mnemonics) Mnemonics.setLocalizedText(l, text);
else l.setText(text.replace("&", "")); // NOI18N
}
private static void setText(AbstractButton b, String text, boolean mnemonics) {
if (mnemonics) Mnemonics.setLocalizedText(b, text);
else b.setText(text.replace("&", "")); // NOI18N
}
private static TextAreaComponent createTextArea(int rows) {
final JTextArea rootsArea = new JTextArea();
rootsArea.setFont(new Font("Monospaced", Font.PLAIN, // NOI18N
UIManager.getFont("Label.font").getSize())); // NOI18N
TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {
public Dimension getMinimumSize() {
return getPreferredSize();
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
rootsArea.setEnabled(enabled);
}
};
rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));
JTextArea referenceArea = new JTextArea("X"); // NOI18N
referenceArea.setFont(rootsArea.getFont());
referenceArea.setRows(rows);
Insets insets = rootsAreaScrollPane.getInsets();
rootsAreaScrollPane.setPreferredSize(new Dimension(1,
referenceArea.getPreferredSize().height + (insets != null ?
insets.top + insets.bottom : 0)));
return rootsAreaScrollPane;
}
private static class TextAreaComponent extends JScrollPane {
public TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) {
super(textArea, vPolicy, hPolicy);
}
public JTextArea getTextArea() {
return (JTextArea)getViewport().getView();
}
}
private static class ComboRenderer implements ListCellRenderer {
private ListCellRenderer renderer;
ComboRenderer(JComboBox combo) {
renderer = combo.getRenderer();
if (renderer instanceof JLabel)
((JLabel)renderer).setHorizontalAlignment(JLabel.TRAILING);
}
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
return renderer.getListCellRendererComponent(list, NumberFormat.
getInstance().format(value), index, isSelected, cellHasFocus);
}
}
}