/*
* Copyright (c) 2007, 2013, 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.profiler.startup;
import com.sun.tools.visualvm.core.ui.DesktopUtils;
import com.sun.tools.visualvm.core.ui.components.SectionSeparator;
import com.sun.tools.visualvm.profiler.CPUSettingsSupport;
import com.sun.tools.visualvm.profiler.MemorySettingsSupport;
import com.sun.tools.visualvm.profiler.ProfilerSupport;
import com.sun.tools.visualvm.profiling.presets.PresetSelector;
import com.sun.tools.visualvm.profiling.presets.ProfilerPresets;
import com.sun.tools.visualvm.uisupport.HorizontalLayout;
import com.sun.tools.visualvm.uisupport.SeparatorLine;
import com.sun.tools.visualvm.uisupport.UISupport;
import com.sun.tools.visualvm.uisupport.VerticalLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.net.URI;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.Caret;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
/**
*
* @author Jiri Sedlacek
*/
@NbBundle.Messages({
"HINT_ProfileStartup=Profile manually started local application from its startup. Follow these steps to start the profiling session.",
"STEP_1=1. Specify application configuration:",
"STEP_2=2. Define profiler settings:",
"STEP_3=3. Setup profiled application:",
"CAP_InvalidSettings=Invalid Profiler Settings",
"MSG_InvalidCPUSettings=Provided CPU settings are invalid.",
"MSG_InvalidMemorySettings=Provided memory settings are invalid.",
"LBL_Continue=Continue >>>",
"LBL_Platform=Platform:",
"LBL_Architecture=Architecture:",
"LBL_Port=Port:",
"BTN_Profile=Profile",
"LBL_Profile=Profile:",
"LBL_CPU=CPU",
"LBL_Memory=Memory",
"BTN_Clipboard=Copy to clipboard",
"CAP_Clipboard=Copy to Clipboard",
"MSG_Clipboard=Profiler parameter copied to clipboard",
"HINT_ConfigureApp=Configure the application to run using {0} {1} and add the following parameter to its JVM arguments:",
"STR_User=user {0}",
"STR_CurrentUser=the current user",
"HINT_StartApp=Click the Profile button to submit this dialog and then start the application as {0}.",
"CAP_OnlineHelp=Online Help",
"LBL_OnlineHelp=Online help",
"MSG_OnlineHelp=Please open the following address in your browser:"
})
final class StartupConfigurator {
private static final String HELP = "https://visualvm.github.io/startupprofiler.html"; // NOI18N
private static final String CPU_ICON_PATH = "com/sun/tools/visualvm/profiler/startup/resources/cpu.png"; // NOI18N
private static final String MEM_ICON_PATH = "com/sun/tools/visualvm/profiler/startup/resources/memory.png"; // NOI18N
private static final String HELP_ICON_PATH = "com/sun/tools/visualvm/profiler/startup/resources/help.png"; // NOI18N
private static final Icon CPU_ICON = ImageUtilities.loadImageIcon(CPU_ICON_PATH, false);
private static final Icon MEM_ICON = ImageUtilities.loadImageIcon(MEM_ICON_PATH, false);
private static final Icon HELP_ICON = ImageUtilities.loadImageIcon(HELP_ICON_PATH, false);
private CPUSettingsSupport cpuSettings;
private MemorySettingsSupport memorySettings;
private PresetSelector refSelector;
private JComponent ui;
private boolean accepted;
private JButton submit;
private JTextArea start1;
private JTextArea start2;
private JTextArea param;
private JPanel panel;
private Dimension cpuSize;
private Dimension memorySize;
private JRadioButton cpuSelector;
private JRadioButton memorySelector;
private JComboBox java;
private JComboBox arch;
private JSpinner port;
private String[] javaPlatforms;
private String[] architectures;
StartupConfigurator() {
cpuSettings = new CPUSettingsSupport() {
public boolean presetValid() {
return cpuSettings.settingsValid() &&
memorySettings.settingsValid();
}
public PresetSelector createSelector(Runnable presetSynchronizer) {
return StartupConfigurator.this.createSelector(presetSynchronizer);
}
};
memorySettings = new MemorySettingsSupport() {
public boolean presetValid() {
return cpuSettings.settingsValid() &&
memorySettings.settingsValid();
}
public PresetSelector createSelector(Runnable presetSynchronizer) {
return StartupConfigurator.this.createSelector(presetSynchronizer);
}
};
// Warmup, the implementation expects both panels to be created
cpuSettings.getComponent();
memorySettings.getComponent();
}
private PresetSelector createSelector(Runnable presetSynchronizer) {
PresetSelector selector = ProfilerPresets.getInstance().createSelector(
refSelector, presetSynchronizer);
if (refSelector == null) refSelector = selector; else refSelector = null;
return selector;
}
JComponent getUI() {
accepted = false;
if (ui == null) ui = createUI();
SwingUtilities.invokeLater(new Runnable() {
public void run() { if (submit.isShowing()) submit.requestFocusInWindow(); }
});
return ui;
}
boolean accepted() {
return accepted;
}
CPUSettingsSupport getCPUSettings() {
return cpuSettings;
}
MemorySettingsSupport getMemorySettings() {
return memorySettings;
}
boolean isCPUProfiling() {
return cpuSelector.isSelected();
}
String getJavaPlatform() {
return javaPlatforms[java.getSelectedIndex()];
}
int getArchitecture() {
return Integer.parseInt(architectures[arch.getSelectedIndex()]);
}
int getPort() {
return (Integer)port.getValue();
}
private JComponent createUI() {
JPanel header = new JPanel(new VerticalLayout(false));
header.setOpaque(true);
JTextArea hint = new JTextArea(Bundle.HINT_ProfileStartup());
hint.setLineWrap(true);
hint.setWrapStyleWord(true);
hint.setEditable(false);
hint.setFocusable(false);
hint.setOpaque(false);
if (UISupport.isNimbusLookAndFeel()) hint.setBackground(new Color(0, 0, 0, 0));
hint.setCaret(new NullCaret());
hint.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
header.add(hint);
header.add(new SeparatorLine());
JPanel content = new JPanel(new VerticalLayout(false));
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
content.setOpaque(false);
content.add(new SectionSeparator(Bundle.STEP_1()));
content.add(createAttachPanel());
final JPanel show2 = new JPanel(new BorderLayout());
show2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3));
show2.setOpaque(false);
show2.setVisible(false);
content.add(show2);
final JComponent separator2 = new SectionSeparator(Bundle.STEP_2());
final JComponent profilerP = createProfilePanel();
content.add(separator2);
content.add(profilerP);
final JPanel show3 = new JPanel(new BorderLayout());
show3.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3));
show3.setOpaque(false);
show3.setVisible(false);
content.add(show3);
final JComponent separator3 = new SectionSeparator(Bundle.STEP_3());
final JComponent stepsP = createStepsPanel();
content.add(separator3);
content.add(stepsP);
final JPanel footer = new JPanel(new VerticalLayout(false));
footer.setOpaque(true);
footer.add(new SeparatorLine(), BorderLayout.NORTH);
footer.add(createVerticalSpace(10));
JPanel buttons = new JPanel(new BorderLayout(0, 0));
JPanel buttonsL = new JPanel(new HorizontalLayout(false));
JButton help = new JButton(HELP_ICON) {
protected void fireActionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() { showHelp(null); } // NOI18N
});
}
public Dimension getPreferredSize() {
Dimension d = submit.getPreferredSize();
d.width = d.height;
return d;
}
};
help.setToolTipText(Bundle.LBL_OnlineHelp());
buttonsL.add(createHorizontalSpace(10));
buttonsL.add(help);
JPanel buttonsR = new JPanel(new HorizontalLayout(false));
submit = new JButton(Bundle.BTN_Profile(), new ImageIcon(StartupProfilerAction.ICON)) {
protected void fireActionPerformed(ActionEvent e) {
boolean isCPU = isCPUProfiling();
boolean valid = isCPU ? cpuSettings.settingsValid() :
memorySettings.settingsValid();
if (!valid) {
String msg = isCPU ? Bundle.MSG_InvalidCPUSettings() :
Bundle.MSG_InvalidMemorySettings();
Dialogs.show(Dialogs.error(Bundle.CAP_InvalidSettings(), msg));
} else {
accepted = true;
Window w = SwingUtilities.getWindowAncestor(this);
if (w != null) w.setVisible(false);
}
}
};
buttonsR.add(submit);
// buttonsC.add(createHorizontalSpace(5));
// buttonsC.add(new JButton("Cancel") {
// protected void fireActionPerformed(ActionEvent e) {
// Window w = SwingUtilities.getWindowAncestor(this);
// if (w != null) w.setVisible(false);
// }
// });
buttonsR.add(createHorizontalSpace(10));
buttons.add(buttonsL, BorderLayout.WEST);
buttons.add(buttonsR, BorderLayout.EAST);
footer.add(buttons);
footer.add(createVerticalSpace(10));
// ---
panel = new JPanel(new VerticalLayout(false));
panel.setBackground(UISupport.getDefaultBackground());
panel.setOpaque(true);
panel.add(header);
panel.add(content);
panel.add(footer);
// ---
// Read the preferred dialog width to initialize textareas
int width = panel.getPreferredSize().width;
// Correctly layout multiline textareas
hint.setSize(width - widthInsetsInContainer(hint, panel), Integer.MAX_VALUE);
start1.setSize(width - widthInsetsInContainer(start1, panel), Integer.MAX_VALUE);
start2.setSize(width - widthInsetsInContainer(start2, panel), Integer.MAX_VALUE);
// Setup dialog size
cpuSize = panel.getPreferredSize();
memorySize = new Dimension(cpuSize);
memorySize.height -= cpuSettings.getComponent().getPreferredSize().height - memorySettings.getComponent().getPreferredSize().height;
panel.setPreferredSize(cpuSize);
separator2.setVisible(false);
profilerP.setVisible(false);
separator3.setVisible(false);
stepsP.setVisible(false);
footer.setVisible(false);
show2.setVisible(true);
JButton show2A = new JButton(HELP_ICON) {
protected void fireActionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() { showHelp("appconfig"); } // NOI18N
});
}
};
show2A.setToolTipText(Bundle.LBL_OnlineHelp());
show2A.setContentAreaFilled(false);
show2A.setOpaque(false);
show2A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
show2A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3));
JButton show2B = new JButton("<html><a href='#'>" + Bundle.LBL_Continue() + "</a></html>") { // NOI18N
protected void fireActionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
separator2.setVisible(true);
profilerP.setVisible(true);
show3.setVisible(true);
show2.setVisible(false);
}
});
}
};
show2B.setContentAreaFilled(false);
show2B.setOpaque(false);
show2B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
show2B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
JPanel show2P = new JPanel(new HorizontalLayout(false));
show2P.setOpaque(false);
show2P.add(show2A);
show2P.add(createHorizontalSpace(1));
show2P.add(show2B);
show2.add(show2P, BorderLayout.EAST);
JButton show3A = new JButton(HELP_ICON) {
protected void fireActionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() { showHelp("profsettings"); } // NOI18N
});
}
};
show3A.setToolTipText(Bundle.LBL_OnlineHelp());
show3A.setContentAreaFilled(false);
show3A.setOpaque(false);
show3A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
show3A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3));
JButton show3B = new JButton("<html><a href='#'>" + Bundle.LBL_Continue() + "</a></html>") { // NOI18N
protected void fireActionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
separator3.setVisible(true);
stepsP.setVisible(true);
footer.setVisible(true);
show3.setVisible(false);
}
});
}
};
show3B.setContentAreaFilled(false);
show3B.setOpaque(false);
show3B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
show3B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
JPanel show3P = new JPanel(new HorizontalLayout(false));
show3P.setOpaque(false);
show3P.add(show3A);
show3P.add(createHorizontalSpace(1));
show3P.add(show3B);
show3.add(show3P, BorderLayout.EAST);
return panel;
}
private JPanel createAttachPanel() {
JPanel attach = new JPanel(new HorizontalLayout(false, 5));
attach.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));
attach.setOpaque(false);
attach.add(new JLabel(Bundle.LBL_Platform()));
String[][] platforms = ProfilerSupport.getInstance().getSupportedJavaPlatforms();
javaPlatforms = platforms[1];
java = new JComboBox(platforms[0]) {
public Dimension getPreferredSize() { // Workaround for Nimbus LaF
Dimension d = super.getPreferredSize();
if (UISupport.isNimbusLookAndFeel()) d.width += 5;
return d;
}
protected void selectedItemChanged() {
super.selectedItemChanged();
if (arch != null) {
String[][] archs = ProfilerSupport.getInstance().getSupportedArchitectures(getJavaPlatform());
architectures = archs[1];
Object sel = arch.getSelectedItem();
arch.setModel(new DefaultComboBoxModel(archs[0]));
if (sel == null) sel = archs[2][0];
if (sel != null) arch.setSelectedItem(sel);
arch.setEnabled(arch.getItemCount() > 1);
}
updateParam();
}
};
java.setEnabled(java.getItemCount() > 1);
attach.add(java);
attach.add(createHorizontalSpace(2));
attach.add(new JLabel(Bundle.LBL_Architecture()));
arch = new JComboBox() {
public Dimension getPreferredSize() { // Workaround for Nimbus LaF
Dimension d = super.getPreferredSize();
if (UISupport.isNimbusLookAndFeel()) d.width += 5;
return d;
}
protected void selectedItemChanged() {
super.selectedItemChanged();
updateParam();
}
};
java.setSelectedItem(platforms[2][0]);
attach.add(arch);
attach.add(createHorizontalSpace(2));
attach.add(new JLabel(Bundle.LBL_Port()));
int portv = ProfilerSupport.getInstance().getDefaultPort();
port = new JSpinner(new SpinnerNumberModel(portv, 1, 65535, 1));
port.getModel().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) { updateParam(); }
});
attach.add(port);
return attach;
}
private JPanel createProfilePanel() {
final JComponent cpu = cpuSettings.getComponent();
((JComponent)cpu.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10));
((JComponent)cpu.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
final JComponent memory = memorySettings.getComponent();
((JComponent)memory.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10));
((JComponent)memory.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
memory.setVisible(false);
final JPanel profile = new JPanel(new VerticalLayout(false));
profile.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));
profile.setOpaque(false);
JPanel mode = new JPanel(new HorizontalLayout(false, 5));
mode.setOpaque(false);
mode.add(new JLabel(Bundle.LBL_Profile()));
final ButtonGroup bg = new ButtonGroup();
cpuSelector = new IconRadioButton(Bundle.LBL_CPU(), CPU_ICON, true) {
boolean firstEvent = true;
{ bg.add(this); }
protected void fireItemStateChanged(ItemEvent e) {
super.fireItemStateChanged(e);
if (e.getStateChange() == ItemEvent.SELECTED) {
cpu.setVisible(true);
memory.setVisible(false);
if (panel != null) {
panel.setPreferredSize(cpuSize);
SwingUtilities.getWindowAncestor(profile).pack();
}
}
}
};
mode.add(cpuSelector);
memorySelector = new IconRadioButton(Bundle.LBL_Memory(), MEM_ICON, false) {
{ bg.add(this); }
protected void fireItemStateChanged(ItemEvent e) {
super.fireItemStateChanged(e);
if (e.getStateChange() == ItemEvent.SELECTED) {
cpu.setVisible(false);
memory.setVisible(true);
if (panel != null) {
panel.setPreferredSize(memorySize);
SwingUtilities.getWindowAncestor(profile).pack();
}
}
}
};
mode.add(memorySelector);
profile.add(mode);
profile.add(cpu);
profile.add(memory);
return profile;
}
private JPanel createStepsPanel() {
JPanel steps = new JPanel(new VerticalLayout(false));
steps.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));
steps.setOpaque(false);
start1 = new JTextArea();
start1.setLineWrap(true);
start1.setWrapStyleWord(true);
start1.setEditable(false);
start1.setFocusable(false);
start1.setOpaque(false);
if (UISupport.isNimbusLookAndFeel()) start1.setBackground(new Color(0, 0, 0, 0));
start1.setCaret(new NullCaret());
start1.setBorder(BorderFactory.createEmptyBorder());
steps.add(start1);
final JPanel arg = new JPanel(new BorderLayout(5, 0));
arg.setOpaque(false);
TextAreaComponent paramA = createTextArea(1);
param = paramA.getTextArea();
updateParam();
arg.add(paramA, BorderLayout.CENTER);
JButton link = new JButton(Bundle.BTN_Clipboard()) {
protected void fireActionPerformed(ActionEvent e) {
RequestProcessor.getDefault().post(new Runnable() {
public void run() {
StringSelection s = new StringSelection(param.getText());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);
Dialogs.show(Dialogs.info(Bundle.CAP_Clipboard(), Bundle.MSG_Clipboard()));
}
});
}
};
arg.add(link, BorderLayout.EAST);
steps.add(createVerticalSpace(8));
steps.add(arg);
steps.add(createVerticalSpace(8));
String user = System.getProperty("user.name"); // NOI18N
if (user != null) user = Bundle.STR_User(user);
else user = Bundle.STR_CurrentUser();
start2 = new JTextArea(Bundle.HINT_StartApp(user));
start2.setLineWrap(true);
start2.setWrapStyleWord(true);
start2.setEditable(false);
start2.setFocusable(false);
start2.setOpaque(false);
if (UISupport.isNimbusLookAndFeel()) start2.setBackground(new Color(0, 0, 0, 0));
start2.setCaret(new NullCaret());
start2.setBorder(BorderFactory.createEmptyBorder());
steps.add(start2);
return steps;
}
private void updateParam() {
if (param == null) return;
start1.setText(Bundle.HINT_ConfigureApp(java.getSelectedItem().toString(),
arch.getSelectedItem().toString()));
int caret = param.getCaretPosition();
param.setText(ProfilerSupport.getInstance().getStartupParameter(
getJavaPlatform(), getArchitecture(), getPort()));
try {
param.setCaretPosition(caret);
} catch (IllegalArgumentException e) {
param.setCaretPosition(0);
}
if (param.isShowing()) {
final JComponent c = (JComponent)param.getParent().getParent();
c.setBorder(BorderFactory.createLineBorder(Color.RED));
RequestProcessor.getDefault().post(new Runnable() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JComponent c = (JComponent)param.getParent().getParent();
c.setBorder(BorderFactory.createLineBorder(Color.GRAY));
}
});
}
}, 180);
}
}
private static void showHelp(String section) {
final String addr = (section == null) ? HELP : HELP + "#" + section; // NOI18N
if (DesktopUtils.isBrowseAvailable()) {
RequestProcessor.getDefault().post(new Runnable() {
public void run() {
try {
URI uri = new URI(addr);
DesktopUtils.browse(uri);
} catch (Exception e) { showHelpDialog(addr); }
}
});
} else {
showHelpDialog(addr);
}
}
private static void showHelpDialog(final String addr) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Dialogs.show(Dialogs.info(Bundle.CAP_OnlineHelp(),
Bundle.MSG_OnlineHelp() + "\n" + addr)); // NOI18N
}
});
}
private static int widthInsetsInContainer(Container c, Container p) {
int w = 0;
while (c != null && p != null && c != p) {
c = c.getParent();
Insets i = c.getInsets();
w += i.left + i.right;
}
return w;
}
private static JComponent createHorizontalSpace(final int width) {
JPanel space = new JPanel(null) {
public Dimension getPreferredSize() { return new Dimension(width, 0); }
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getMaximumSize() { return getPreferredSize(); }
};
space.setOpaque(false);
return space;
}
private static JComponent createVerticalSpace(final int height) {
JPanel space = new JPanel(null) {
public Dimension getPreferredSize() { return new Dimension(0, height); }
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getMaximumSize() { return getPreferredSize(); }
};
space.setOpaque(false);
return space;
}
private static TextAreaComponent createTextArea(int rows) {
final JTextArea rootsArea = new JTextArea();
rootsArea.setEditable(false);
rootsArea.setFont(new Font("Monospaced", Font.PLAIN, UIManager.getFont("Label.font").getSize())); // NOI18N
TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {
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 IconRadioButton extends JRadioButton {
private static final int CHECKBOX_OFFSET = getCheckBoxOffset();
private final JRadioButton renderer;
public IconRadioButton(String text, Icon icon, boolean selected) {
renderer = new JRadioButton(text, icon) {
public boolean hasFocus() {
return IconRadioButton.this.hasFocus();
}
};
renderer.setOpaque(false);
renderer.setBorderPainted(false);
setSelected(selected);
setBorderPainted(false);
setOpaque(false);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.translate(renderer.getX(), renderer.getY());
renderer.paint(g);
g.translate(-renderer.getX(), -renderer.getY());
}
public void setBounds(int x, int y, int width, int height) {
Dimension d = super.getPreferredSize();
renderer.setBounds(d.width - CHECKBOX_OFFSET, 0,
width - d.width + CHECKBOX_OFFSET, height);
super.setBounds(x, y, width, height);
}
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width += renderer.getPreferredSize().width - CHECKBOX_OFFSET;
return d;
}
private static int getCheckBoxOffset() {
if (UISupport.isWindowsLookAndFeel()) return 3;
else if (UISupport.isNimbusLookAndFeel()) return -3;
else if (UISupport.isMetalLookAndFeel()) return 3;
else if (UISupport.isAquaLookAndFeel()) return 6;
else return 0;
}
}
private static final class NullCaret implements Caret {
public void install(javax.swing.text.JTextComponent c) {}
public void deinstall(javax.swing.text.JTextComponent c) {}
public void paint(Graphics g) {}
public void addChangeListener(ChangeListener l) {}
public void removeChangeListener(ChangeListener l) {}
public boolean isVisible() { return false; }
public void setVisible(boolean v) {}
public boolean isSelectionVisible() { return false; }
public void setSelectionVisible(boolean v) {}
public void setMagicCaretPosition(Point p) {}
public Point getMagicCaretPosition() { return new Point(0, 0); }
public void setBlinkRate(int rate) {}
public int getBlinkRate() { return 0; }
public int getDot() { return 0; }
public int getMark() { return 0; }
public void setDot(int dot) {}
public void moveDot(int dot) {}
}
}