/*
* 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.jmx.impl;
import com.sun.tools.visualvm.core.properties.PropertiesPanel;
import com.sun.tools.visualvm.core.ui.components.ScrollableContainer;
import com.sun.tools.visualvm.jmx.JmxConnectionCustomizer;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.awt.Mnemonics;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
/**
*
* @author Jiri Sedlacek
*/
class JmxConnectionConfigurator extends JPanel {
static Result getResult() {
JmxConnectionConfigurator configurator = instance();
configurator.warmup();
final DialogDescriptor dd = new DialogDescriptor(configurator,
NbBundle.getMessage(JmxConnectionConfigurator.class, "Title_Add_JMX_Connection"), // NOI18N
true, new Object[] { configurator.okButton, DialogDescriptor.CANCEL_OPTION},
configurator.okButton, 0, null, null);
dd.setAdditionalOptions(new Object[] { configurator.hintLabel });
final Dialog d = DialogDisplayer.getDefault().createDialog(dd);
configurator.updateWindowTitle(d);
d.pack();
d.setVisible(true);
Result result = configurator.get(dd.getValue() == configurator.okButton);
configurator.cleanup();
return result;
}
public static synchronized JmxConnectionConfigurator instance() {
if (INSTANCE == null) INSTANCE = new JmxConnectionConfigurator();
return INSTANCE;
}
public void warmup() {
// Resolve customizers
customizers.addAll(JmxConnectionSupportImpl.getCustomizers());
singleCustomizer = customizers.size() == 1;
// Populate list, initialize panels
JmxConnectionCustomizer itemToSelect = null;
for (JmxConnectionCustomizer customizer : customizers) {
connectionTypeListModel.addElement(customizer);
customizerPanels.add(customizer.createPanel(null));
if (customizer.toString().equals(lastSelectedItem))
itemToSelect = customizer;
}
// Update selector visibility
boolean selectorVisible = customizers.size() > 1;
connectionTypeLabel.setVisible(selectorVisible);
connectionTypeScroll.setVisible(selectorVisible);
customizerPanelScroll.setBorder(selectorVisible ?
BorderFactory.createEmptyBorder(5, 8, 0, 5) :
BorderFactory.createEmptyBorder(15, 5, 0, 5));
// Register selection listener
connectionTypeList.addListSelectionListener(selectionListener);
// Restore previously selected item
if (itemToSelect == null) connectionTypeList.setSelectedIndex(0);
else connectionTypeList.setSelectedValue(itemToSelect, true);
// Update OK button state
updateOkButton();
// Restore previous dialog size
if (lastSize != null) customizerPanelScroll.setPreferredSize(lastSize);
else initializePreferredSize();
}
public Result get(boolean accepted) {
JmxConnectionCustomizer.Setup setup = null;
if (accepted && selectedCustomizer != null && displayedPanel != null)
setup = selectedCustomizer.getConnectionSetup(displayedPanel);
return new Result(setup, selectedCustomizer, customizers, customizerPanels);
}
public void cleanup() {
// Save last selected item
Object selectedItem = connectionTypeList.getSelectedValue();
lastSelectedItem = selectedItem == null ? null : selectedItem.toString();
// Unregister selection listener
connectionTypeList.clearSelection();
connectionTypeList.removeListSelectionListener(selectionListener);
// Save dialog size
lastSize = customizerPanelScroll.getSize();
// Clear state
customizers.clear();
customizerPanels.clear();
customizerPanel.removeAll();
connectionTypeListModel.clear();
selectedCustomizer = null;
}
public void updateWindowTitle(Window w) {
if (singleCustomizer) return;
String title = NbBundle.getMessage(JmxConnectionConfigurator.class,
"Title_Add_JMX_Connection") + " - " + // NOI18N
selectedCustomizer.getPropertiesName();
if (w instanceof Dialog) ((Dialog)w).setTitle(title);
else if (w instanceof Frame) ((Frame)w).setTitle(title);
}
private void updateSelectedCustomizer() {
selectedCustomizer =
(JmxConnectionCustomizer)connectionTypeList.getSelectedValue();
if (displayedPanel != null) {
displayedPanel.removeChangeListener(validityListener);
customizerPanel.removeAll();
}
if (selectedCustomizer != null) {
displayedPanel = customizerPanels.get(connectionTypeListModel.
indexOf(selectedCustomizer));
updateWindowTitle(SwingUtilities.getWindowAncestor(this));
}
if (displayedPanel != null) {
displayedPanel.addChangeListener(validityListener);
customizerPanel.add(displayedPanel, BorderLayout.CENTER);
customizerPanel.revalidate();
customizerPanel.repaint();
updateOkButton();
}
}
private void updateOkButton() {
okButton.setEnabled(displayedPanel != null &&
displayedPanel.settingsValid() ? true : false);
}
private void updateHint() {
String hintText = selectedCustomizer == null ? null :
selectedCustomizer.getPropertiesDescription();
if (hintText != null && !singleCustomizer) {
hintLabel.setIcon(INFO_ICON);
hintLabel.setText(hintText);
} else {
hintLabel.setIcon(null);
hintLabel.setText(""); // NOI18N
}
}
private void initializePreferredSize() {
Dimension preferredSize = new Dimension();
for (PropertiesPanel panel : customizerPanels) {
Dimension panelPref = panel.getPreferredSize();
preferredSize.width = Math.max(preferredSize.width, panelPref.width);
preferredSize.height = Math.max(preferredSize.height, panelPref.height);
}
Insets insets = customizerPanelScroll.getInsets();
preferredSize.width += insets.left + insets.right;
preferredSize.height += insets.top + insets.bottom;
if (!singleCustomizer) preferredSize.height += 40; // Extra bottom space
customizerPanelScroll.setPreferredSize(preferredSize);
}
private JmxConnectionCustomizer getCustomizer(Point location) {
int index = connectionTypeList.locationToIndex(location);
if (index == -1) return null;
if (!connectionTypeList.getCellBounds(index, index).contains(location))
return null;
return (JmxConnectionCustomizer)connectionTypeListModel.
getElementAt(index);
}
private class SelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
updateSelectedCustomizer();
updateHint();
}
}
}
private class ValidityListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
updateOkButton();
}
}
private void initComponents() {
okButton = new JButton(NbBundle.getMessage(JmxConnectionConfigurator.class, "LBL_OK")); // NOI18N
hintLabel = new JLabel("") { // NOI18N
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = Math.max(d.height, okButton.getPreferredSize().height);
return d;
}
};
hintLabel.setForeground(UIManager.getColor("Label.disabledForeground")); // NOI18N
setLayout(new BorderLayout());
connectionTypeLabel = new JLabel();
Mnemonics.setLocalizedText(connectionTypeLabel,
NbBundle.getMessage(JmxConnectionConfigurator.class, "LBL_Connection_type")); // NOI18N
createBorder(connectionTypeLabel, BorderFactory.createEmptyBorder(15, 10, 0, 10));
add(connectionTypeLabel, BorderLayout.NORTH);
connectionTypeListModel = new DefaultListModel();
connectionTypeList = new JList(connectionTypeListModel) {
public String getToolTipText(MouseEvent evt) {
JmxConnectionCustomizer cust = getCustomizer(evt.getPoint());
return cust == null ? null : cust.getPropertiesDescription();
}
};
connectionTypeLabel.setLabelFor(connectionTypeList);
connectionTypeList.setSelectionModel(new DefaultListSelectionModel() {
public void removeSelectionInterval(int i1, int i2) {}
});
connectionTypeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final ListCellRenderer defaultRenderer = connectionTypeList.getCellRenderer();
Component c = defaultRenderer.getListCellRendererComponent(connectionTypeList, "X", 0, false, false); // NOI18N
connectionTypeList.setFixedCellHeight(c.getPreferredSize().height + 2);
connectionTypeList.setCellRenderer(new ListCellRenderer() {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
return defaultRenderer.getListCellRendererComponent(list, " " + value + " ", index, isSelected, cellHasFocus); // NOI18N
}
});
connectionTypeScroll = new JScrollPane(connectionTypeList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
preferredSize.width = Math.min(preferredSize.width, 300);
preferredSize.width = Math.max(preferredSize.width, 120);
return preferredSize;
}
};
createBorder(connectionTypeScroll, BorderFactory.createEmptyBorder(5, 10, 0, 0));
add(connectionTypeScroll, BorderLayout.WEST);
customizerPanel = new JPanel(new BorderLayout());
customizerPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
customizerPanelScroll = new ScrollableContainer(customizerPanel,
ScrollableContainer.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollableContainer.HORIZONTAL_SCROLLBAR_NEVER);
customizerPanelScroll.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));
add(customizerPanelScroll, BorderLayout.CENTER);
}
private static void createBorder(JComponent component, Border border) {
Border cBorder = component.getBorder();
if (cBorder == null) component.setBorder(border);
else component.setBorder(BorderFactory.createCompoundBorder(border, cBorder));
}
private JmxConnectionConfigurator() {
initComponents();
}
private static final Icon INFO_ICON =
ImageUtilities.loadImageIcon("com/sun/tools/visualvm/jmx/resources/infoIcon.png", // NOI18N
false);
private boolean singleCustomizer;
private JmxConnectionCustomizer selectedCustomizer;
private PropertiesPanel displayedPanel;
private List<JmxConnectionCustomizer> customizers = new ArrayList();
private List<PropertiesPanel> customizerPanels = new ArrayList();
private SelectionListener selectionListener = new SelectionListener();
private ValidityListener validityListener = new ValidityListener();
private String lastSelectedItem;
private Dimension lastSize;
private DefaultListModel connectionTypeListModel;
private JButton okButton;
private JLabel hintLabel;
private JLabel connectionTypeLabel;
private JList connectionTypeList;
private JScrollPane connectionTypeScroll;
private JPanel customizerPanel;
private ScrollableContainer customizerPanelScroll;
private static JmxConnectionConfigurator INSTANCE;
public static final class Result {
private final JmxConnectionCustomizer.Setup setup;
private final JmxConnectionCustomizer selectedCustomizer;
private final List<JmxConnectionCustomizer> customizers = new ArrayList();
private final List<PropertiesPanel> customizerPanels = new ArrayList();
public Result(JmxConnectionCustomizer.Setup setup,
JmxConnectionCustomizer selectedCustomizer,
List<JmxConnectionCustomizer> customizers,
List<PropertiesPanel> customizerPanels) {
this.setup = setup;
this.selectedCustomizer = selectedCustomizer;
this.customizers.addAll(customizers);
this.customizerPanels.addAll(customizerPanels);
}
public JmxConnectionCustomizer.Setup getSetup() { return setup; }
public void accepted(JmxApplication application) {
for (int i = 0; i < customizers.size(); i++) {
JmxConnectionCustomizer c = customizers.get(i);
if (c == selectedCustomizer) {
JmxPropertiesProvider.setCustomizer(application, selectedCustomizer);
c.propertiesDefined(customizerPanels.get(i), application);
} else {
customizers.get(i).propertiesCancelled(customizerPanels.get(i), null);
}
}
}
public void cancelled() {
for (int i = 0; i < customizers.size(); i++)
customizers.get(i).propertiesCancelled(customizerPanels.get(i), null);
}
}
}