feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
197
jdkSrc/jdk8/sun/tools/jconsole/AboutDialog.java
Normal file
197
jdkSrc/jdk8/sun/tools/jconsole/AboutDialog.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import static sun.misc.Version.jdkMinorVersion;
|
||||
|
||||
import static java.awt.BorderLayout.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AboutDialog extends InternalDialog {
|
||||
|
||||
private static final Color textColor = new Color(87, 88, 89);
|
||||
private static final Color bgColor = new Color(232, 237, 241);
|
||||
private static final Color borderColor = Color.black;
|
||||
|
||||
private Icon mastheadIcon =
|
||||
new MastheadIcon(Messages.HELP_ABOUT_DIALOG_MASTHEAD_TITLE);
|
||||
|
||||
private static AboutDialog aboutDialog;
|
||||
|
||||
private JLabel statusBar;
|
||||
private Action closeAction;
|
||||
|
||||
public AboutDialog(JConsole jConsole) {
|
||||
super(jConsole, Messages.HELP_ABOUT_DIALOG_TITLE, false);
|
||||
|
||||
setAccessibleDescription(this, Messages.HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
JComponent cp = (JComponent)getContentPane();
|
||||
|
||||
createActions();
|
||||
|
||||
JLabel mastheadLabel = new JLabel(mastheadIcon);
|
||||
setAccessibleName(mastheadLabel,
|
||||
Messages.HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
|
||||
|
||||
JPanel mainPanel = new TPanel(0, 0);
|
||||
mainPanel.add(mastheadLabel, NORTH);
|
||||
|
||||
String jConsoleVersion = Version.getVersion();
|
||||
String vmName = System.getProperty("java.vm.name");
|
||||
String vmVersion = System.getProperty("java.vm.version");
|
||||
String urlStr = getOnlineDocUrl();
|
||||
if (isBrowseSupported()) {
|
||||
urlStr = "<a style='color:#35556b' href=\"" + urlStr + "\">" + urlStr + "</a>";
|
||||
}
|
||||
|
||||
JPanel infoAndLogoPanel = new JPanel(new BorderLayout(10, 10));
|
||||
infoAndLogoPanel.setBackground(bgColor);
|
||||
|
||||
String colorStr = String.format("%06x", textColor.getRGB() & 0xFFFFFF);
|
||||
JEditorPane helpLink = new JEditorPane("text/html",
|
||||
"<html><font color=#"+ colorStr + ">" +
|
||||
Resources.format(Messages.HELP_ABOUT_DIALOG_JCONSOLE_VERSION, jConsoleVersion) +
|
||||
"<p>" + Resources.format(Messages.HELP_ABOUT_DIALOG_JAVA_VERSION, (vmName +", "+ vmVersion)) +
|
||||
"<p>" + urlStr + "</html>");
|
||||
helpLink.setOpaque(false);
|
||||
helpLink.setEditable(false);
|
||||
helpLink.setForeground(textColor);
|
||||
mainPanel.setBorder(BorderFactory.createLineBorder(borderColor));
|
||||
infoAndLogoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
helpLink.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
browse(e.getDescription());
|
||||
}
|
||||
}
|
||||
});
|
||||
infoAndLogoPanel.add(helpLink, NORTH);
|
||||
|
||||
ImageIcon brandLogoIcon = new ImageIcon(getClass().getResource("resources/brandlogo.png"));
|
||||
JLabel brandLogo = new JLabel(brandLogoIcon, JLabel.LEADING);
|
||||
|
||||
JButton closeButton = new JButton(closeAction);
|
||||
|
||||
JPanel bottomPanel = new TPanel(0, 0);
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
|
||||
buttonPanel.setOpaque(false);
|
||||
|
||||
mainPanel.add(infoAndLogoPanel, CENTER);
|
||||
cp.add(bottomPanel, SOUTH);
|
||||
|
||||
infoAndLogoPanel.add(brandLogo, SOUTH);
|
||||
|
||||
buttonPanel.setBorder(new EmptyBorder(2, 12, 2, 12));
|
||||
buttonPanel.add(closeButton);
|
||||
bottomPanel.add(buttonPanel, NORTH);
|
||||
|
||||
statusBar = new JLabel(" ");
|
||||
bottomPanel.add(statusBar, SOUTH);
|
||||
|
||||
cp.add(mainPanel, NORTH);
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
Utilities.updateTransparency(this);
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
statusBar.setText(" ");
|
||||
setVisible(true);
|
||||
try {
|
||||
// Bring to front of other dialogs
|
||||
setSelected(true);
|
||||
} catch (PropertyVetoException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static AboutDialog getAboutDialog(JConsole jConsole) {
|
||||
if (aboutDialog == null) {
|
||||
aboutDialog = new AboutDialog(jConsole);
|
||||
}
|
||||
return aboutDialog;
|
||||
}
|
||||
|
||||
static void showAboutDialog(JConsole jConsole) {
|
||||
getAboutDialog(jConsole).showDialog();
|
||||
}
|
||||
|
||||
static void browseUserGuide(JConsole jConsole) {
|
||||
getAboutDialog(jConsole).browse(getOnlineDocUrl());
|
||||
}
|
||||
|
||||
static boolean isBrowseSupported() {
|
||||
return (Desktop.isDesktopSupported() &&
|
||||
Desktop.getDesktop().isSupported(Desktop.Action.BROWSE));
|
||||
}
|
||||
|
||||
void browse(String urlStr) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI(urlStr));
|
||||
} catch (Exception ex) {
|
||||
showDialog();
|
||||
statusBar.setText(ex.getLocalizedMessage());
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
closeAction = new AbstractAction(Messages.CLOSE) {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String getOnlineDocUrl() {
|
||||
String version = Integer.toString(jdkMinorVersion());
|
||||
return Resources.format(Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL,
|
||||
version);
|
||||
}
|
||||
|
||||
private static class TPanel extends JPanel {
|
||||
TPanel(int hgap, int vgap) {
|
||||
super(new BorderLayout(hgap, vgap));
|
||||
setOpaque(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
564
jdkSrc/jdk8/sun/tools/jconsole/BorderedComponent.java
Normal file
564
jdkSrc/jdk8/sun/tools/jconsole/BorderedComponent.java
Normal file
@@ -0,0 +1,564 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicGraphicsUtils;
|
||||
|
||||
|
||||
import static javax.swing.SwingConstants.*;
|
||||
|
||||
import static sun.tools.jconsole.JConsole.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BorderedComponent extends JPanel implements ActionListener {
|
||||
JButton moreOrLessButton;
|
||||
String valueLabelStr;
|
||||
JLabel label;
|
||||
JComponent comp;
|
||||
boolean collapsed = false;
|
||||
|
||||
private Icon collapseIcon;
|
||||
private Icon expandIcon;
|
||||
|
||||
private static Image getImage(String name) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
name = "resources/" + name + ".png";
|
||||
return tk.getImage(BorderedComponent.class.getResource(name));
|
||||
}
|
||||
|
||||
public BorderedComponent(String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
public BorderedComponent(String text, JComponent comp) {
|
||||
this(text, comp, false);
|
||||
}
|
||||
|
||||
public BorderedComponent(String text, JComponent comp, boolean collapsible) {
|
||||
super(null);
|
||||
|
||||
this.comp = comp;
|
||||
|
||||
// Only add border if text is not null
|
||||
if (text != null) {
|
||||
TitledBorder border;
|
||||
if (collapsible) {
|
||||
final JLabel textLabel = new JLabel(text);
|
||||
JPanel borderLabel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)) {
|
||||
public int getBaseline(int w, int h) {
|
||||
Dimension dim = textLabel.getPreferredSize();
|
||||
return textLabel.getBaseline(dim.width, dim.height) + textLabel.getY();
|
||||
}
|
||||
};
|
||||
borderLabel.add(textLabel);
|
||||
border = new LabeledBorder(borderLabel);
|
||||
textLabel.setForeground(border.getTitleColor());
|
||||
|
||||
if (IS_WIN) {
|
||||
collapseIcon = new ImageIcon(getImage("collapse-winlf"));
|
||||
expandIcon = new ImageIcon(getImage("expand-winlf"));
|
||||
} else {
|
||||
collapseIcon = new ArrowIcon(SOUTH, textLabel);
|
||||
expandIcon = new ArrowIcon(EAST, textLabel);
|
||||
}
|
||||
|
||||
moreOrLessButton = new JButton(collapseIcon);
|
||||
moreOrLessButton.setContentAreaFilled(false);
|
||||
moreOrLessButton.setBorderPainted(false);
|
||||
moreOrLessButton.setMargin(new Insets(0, 0, 0, 0));
|
||||
moreOrLessButton.addActionListener(this);
|
||||
String toolTip =
|
||||
Messages.BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
|
||||
moreOrLessButton.setToolTipText(toolTip);
|
||||
borderLabel.add(moreOrLessButton);
|
||||
borderLabel.setSize(borderLabel.getPreferredSize());
|
||||
add(borderLabel);
|
||||
} else {
|
||||
border = new TitledBorder(text);
|
||||
}
|
||||
setBorder(new CompoundBorder(new FocusBorder(this), border));
|
||||
} else {
|
||||
setBorder(new FocusBorder(this));
|
||||
}
|
||||
if (comp != null) {
|
||||
add(comp);
|
||||
}
|
||||
}
|
||||
|
||||
public void setComponent(JComponent comp) {
|
||||
if (this.comp != null) {
|
||||
remove(this.comp);
|
||||
}
|
||||
this.comp = comp;
|
||||
if (!collapsed) {
|
||||
LayoutManager lm = getLayout();
|
||||
if (lm instanceof BorderLayout) {
|
||||
add(comp, BorderLayout.CENTER);
|
||||
} else {
|
||||
add(comp);
|
||||
}
|
||||
}
|
||||
revalidate();
|
||||
}
|
||||
|
||||
public void setValueLabel(String str) {
|
||||
this.valueLabelStr = str;
|
||||
if (label != null) {
|
||||
label.setText(Resources.format(Messages.CURRENT_VALUE,
|
||||
valueLabelStr));
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
if (collapsed) {
|
||||
if (label != null) {
|
||||
remove(label);
|
||||
}
|
||||
add(comp);
|
||||
moreOrLessButton.setIcon(collapseIcon);
|
||||
} else {
|
||||
remove(comp);
|
||||
if (valueLabelStr != null) {
|
||||
if (label == null) {
|
||||
label = new JLabel(Resources.format(Messages.CURRENT_VALUE,
|
||||
valueLabelStr));
|
||||
}
|
||||
add(label);
|
||||
}
|
||||
moreOrLessButton.setIcon(expandIcon);
|
||||
}
|
||||
collapsed = !collapsed;
|
||||
|
||||
JComponent container = (JComponent)getParent();
|
||||
if (container != null &&
|
||||
container.getLayout() instanceof VariableGridLayout) {
|
||||
|
||||
((VariableGridLayout)container.getLayout()).setFillRow(this, !collapsed);
|
||||
container.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
if (getLayout() != null) {
|
||||
// A layout manager has been set, so delegate to it
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
|
||||
if (moreOrLessButton != null) {
|
||||
Dimension d = moreOrLessButton.getMinimumSize();
|
||||
Insets i = getInsets();
|
||||
d.width += i.left + i.right;
|
||||
d.height += i.top + i.bottom;
|
||||
return d;
|
||||
} else {
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void doLayout() {
|
||||
if (getLayout() != null) {
|
||||
// A layout manager has been set, so delegate to it
|
||||
super.doLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
Dimension d = getSize();
|
||||
Insets i = getInsets();
|
||||
|
||||
if (collapsed) {
|
||||
if (label != null) {
|
||||
Dimension p = label.getPreferredSize();
|
||||
label.setBounds(i.left,
|
||||
i.top + (d.height - i.top - i.bottom - p.height) / 2,
|
||||
p.width,
|
||||
p.height);
|
||||
}
|
||||
} else {
|
||||
if (comp != null) {
|
||||
comp.setBounds(i.left,
|
||||
i.top,
|
||||
d.width - i.left - i.right,
|
||||
d.height - i.top - i.bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrowIcon implements Icon {
|
||||
private int direction;
|
||||
private JLabel textLabel;
|
||||
|
||||
public ArrowIcon(int direction, JLabel textLabel) {
|
||||
this.direction = direction;
|
||||
this.textLabel = textLabel;
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
int w = getIconWidth();
|
||||
int h = w;
|
||||
Polygon p = new Polygon();
|
||||
switch (direction) {
|
||||
case EAST:
|
||||
p.addPoint(x + 2, y);
|
||||
p.addPoint(x + w - 2, y + h / 2);
|
||||
p.addPoint(x + 2, y + h - 1);
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
p.addPoint(x, y + 2);
|
||||
p.addPoint(x + w / 2, y + h - 2);
|
||||
p.addPoint(x + w - 1, y + 2);
|
||||
break;
|
||||
}
|
||||
g.fillPolygon(p);
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return getIconHeight();
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
Graphics g = textLabel.getGraphics();
|
||||
if (g != null) {
|
||||
int h = g.getFontMetrics(textLabel.getFont()).getAscent() * 6/10;
|
||||
if (h % 2 == 0) {
|
||||
h += 1; // Make it odd
|
||||
}
|
||||
return h;
|
||||
} else {
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A subclass of <code>TitledBorder</code> which implements an arbitrary border
|
||||
* with the addition of a JComponent (JLabel, JPanel, etc) in the
|
||||
* default position.
|
||||
* <p>
|
||||
* If the border property value is not
|
||||
* specified in the constructor or by invoking the appropriate
|
||||
* set method, the property value will be defined by the current
|
||||
* look and feel, using the following property name in the
|
||||
* Defaults Table:
|
||||
* <ul>
|
||||
* <li>"TitledBorder.border"
|
||||
* </ul>
|
||||
*/
|
||||
protected static class LabeledBorder extends TitledBorder {
|
||||
protected JComponent label;
|
||||
|
||||
private Point compLoc = new Point();
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance.
|
||||
*
|
||||
* @param label the label the border should display
|
||||
*/
|
||||
public LabeledBorder(JComponent label) {
|
||||
this(null, label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance with the specified border
|
||||
* and an empty label.
|
||||
*
|
||||
* @param border the border
|
||||
*/
|
||||
public LabeledBorder(Border border) {
|
||||
this(border, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance with the specified border and
|
||||
* label.
|
||||
*
|
||||
* @param border the border
|
||||
* @param label the label the border should display
|
||||
*/
|
||||
public LabeledBorder(Border border, JComponent label) {
|
||||
super(border);
|
||||
|
||||
this.label = label;
|
||||
|
||||
if (label instanceof JLabel &&
|
||||
label.getForeground() instanceof ColorUIResource) {
|
||||
|
||||
label.setForeground(getTitleColor());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the border for the specified component with the
|
||||
* specified position and size.
|
||||
* @param c the component for which this border is being painted
|
||||
* @param g the paint graphics
|
||||
* @param x the x position of the painted border
|
||||
* @param y the y position of the painted border
|
||||
* @param width the width of the painted border
|
||||
* @param height the height of the painted border
|
||||
*/
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
|
||||
Border border = getBorder();
|
||||
|
||||
if (label == null) {
|
||||
if (border != null) {
|
||||
border.paintBorder(c, g, x, y, width, height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
|
||||
width - (EDGE_SPACING * 2),
|
||||
height - (EDGE_SPACING * 2));
|
||||
|
||||
Dimension labelDim = label.getPreferredSize();
|
||||
int baseline = label.getBaseline(labelDim.width, labelDim.height);
|
||||
int ascent = Math.max(0, baseline);
|
||||
int descent = labelDim.height - ascent;
|
||||
int diff;
|
||||
Insets insets;
|
||||
|
||||
if (border != null) {
|
||||
insets = border.getBorderInsets(c);
|
||||
} else {
|
||||
insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
diff = Math.max(0, ascent/2 + TEXT_SPACING - EDGE_SPACING);
|
||||
grooveRect.y += diff;
|
||||
grooveRect.height -= diff;
|
||||
compLoc.y = grooveRect.y + insets.top/2 - (ascent + descent) / 2 - 1;
|
||||
|
||||
int justification;
|
||||
if (c.getComponentOrientation().isLeftToRight()) {
|
||||
justification = LEFT;
|
||||
} else {
|
||||
justification = RIGHT;
|
||||
}
|
||||
|
||||
switch (justification) {
|
||||
case LEFT:
|
||||
compLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;
|
||||
break;
|
||||
case RIGHT:
|
||||
compLoc.x = (grooveRect.x + grooveRect.width
|
||||
- (labelDim.width + TEXT_INSET_H + insets.right));
|
||||
break;
|
||||
}
|
||||
|
||||
// If title is positioned in middle of border AND its fontsize
|
||||
// is greater than the border's thickness, we'll need to paint
|
||||
// the border in sections to leave space for the component's background
|
||||
// to show through the title.
|
||||
//
|
||||
if (border != null) {
|
||||
if (grooveRect.y > compLoc.y - ascent) {
|
||||
Rectangle clipRect = new Rectangle();
|
||||
|
||||
// save original clip
|
||||
Rectangle saveClip = g.getClipBounds();
|
||||
|
||||
// paint strip left of text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect, x, y, compLoc.x-1-x, height)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// paint strip right of text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect, compLoc.x+ labelDim.width +1, y,
|
||||
x+width-(compLoc.x+ labelDim.width +1), height)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// paint strip below text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect,
|
||||
compLoc.x - 1, compLoc.y + ascent + descent,
|
||||
labelDim.width + 2,
|
||||
y + height - compLoc.y - ascent - descent)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// restore clip
|
||||
g.setClip(saveClip);
|
||||
|
||||
} else {
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
label.setLocation(compLoc);
|
||||
label.setSize(labelDim);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialize the insets parameter with this Border's current Insets.
|
||||
* @param c the component for which this border insets value applies
|
||||
* @param insets the object to be reinitialized
|
||||
*/
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
Border border = getBorder();
|
||||
if (border != null) {
|
||||
if (border instanceof AbstractBorder) {
|
||||
((AbstractBorder)border).getBorderInsets(c, insets);
|
||||
} else {
|
||||
// Can't reuse border insets because the Border interface
|
||||
// can't be enhanced.
|
||||
Insets i = border.getBorderInsets(c);
|
||||
insets.top = i.top;
|
||||
insets.right = i.right;
|
||||
insets.bottom = i.bottom;
|
||||
insets.left = i.left;
|
||||
}
|
||||
} else {
|
||||
insets.left = insets.top = insets.right = insets.bottom = 0;
|
||||
}
|
||||
|
||||
insets.left += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.right += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.top += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.bottom += EDGE_SPACING + TEXT_SPACING;
|
||||
|
||||
if (c == null || label == null) {
|
||||
return insets;
|
||||
}
|
||||
|
||||
insets.top += label.getHeight();
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label of the labeled border.
|
||||
*/
|
||||
public JComponent getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the title of the titled border.
|
||||
* param title the title for the border
|
||||
*/
|
||||
public void setLabel(JComponent label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the minimum dimensions this border requires
|
||||
* in order to fully display the border and title.
|
||||
* @param c the component where this border will be drawn
|
||||
*/
|
||||
public Dimension getMinimumSize(Component c) {
|
||||
Insets insets = getBorderInsets(c);
|
||||
Dimension minSize = new Dimension(insets.right + insets.left,
|
||||
insets.top + insets.bottom);
|
||||
minSize.width += label.getWidth();
|
||||
|
||||
return minSize;
|
||||
}
|
||||
|
||||
|
||||
private static boolean computeIntersection(Rectangle dest,
|
||||
int rx, int ry, int rw, int rh) {
|
||||
int x1 = Math.max(rx, dest.x);
|
||||
int x2 = Math.min(rx + rw, dest.x + dest.width);
|
||||
int y1 = Math.max(ry, dest.y);
|
||||
int y2 = Math.min(ry + rh, dest.y + dest.height);
|
||||
dest.x = x1;
|
||||
dest.y = y1;
|
||||
dest.width = x2 - x1;
|
||||
dest.height = y2 - y1;
|
||||
|
||||
if (dest.width <= 0 || dest.height <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class FocusBorder extends AbstractBorder implements FocusListener {
|
||||
private Component comp;
|
||||
private Color focusColor;
|
||||
private boolean focusLostTemporarily = false;
|
||||
|
||||
public FocusBorder(Component comp) {
|
||||
this.comp = comp;
|
||||
|
||||
comp.addFocusListener(this);
|
||||
|
||||
// This is the best guess for a L&F specific color
|
||||
focusColor = UIManager.getColor("TabbedPane.focus");
|
||||
}
|
||||
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
if (comp.hasFocus() || focusLostTemporarily) {
|
||||
Color color = g.getColor();
|
||||
g.setColor(focusColor);
|
||||
BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
|
||||
g.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
insets.set(2, 2, 2, 2);
|
||||
return insets;
|
||||
}
|
||||
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
comp.repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
// We will still paint focus even if lost temporarily
|
||||
focusLostTemporarily = e.isTemporary();
|
||||
if (!focusLostTemporarily) {
|
||||
comp.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
248
jdkSrc/jdk8/sun/tools/jconsole/ClassTab.java
Normal file
248
jdkSrc/jdk8/sun/tools/jconsole/ClassTab.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static sun.tools.jconsole.Formatter.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class ClassTab extends Tab implements ActionListener {
|
||||
PlotterPanel loadedClassesMeter;
|
||||
TimeComboBox timeComboBox;
|
||||
private JCheckBox verboseCheckBox;
|
||||
private HTMLPane details;
|
||||
private ClassOverviewPanel overviewPanel;
|
||||
private boolean plotterListening = false;
|
||||
|
||||
private static final String loadedPlotterKey = "loaded";
|
||||
private static final String totalLoadedPlotterKey = "totalLoaded";
|
||||
private static final Color loadedPlotterColor = Plotter.defaultColor;
|
||||
private static final Color totalLoadedPlotterColor = Color.red;
|
||||
|
||||
/*
|
||||
Hierarchy of panels and layouts for this tab:
|
||||
|
||||
ClassTab (BorderLayout)
|
||||
|
||||
North: topPanel (BorderLayout)
|
||||
|
||||
Center: controlPanel (FlowLayout)
|
||||
timeComboBox
|
||||
|
||||
East: topRightPanel (FlowLayout)
|
||||
verboseCheckBox
|
||||
|
||||
Center: plotterPanel (BorderLayout)
|
||||
|
||||
Center: plotter
|
||||
|
||||
South: bottomPanel (BorderLayout)
|
||||
|
||||
Center: details
|
||||
*/
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.CLASSES;
|
||||
}
|
||||
|
||||
public ClassTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
JPanel plotterPanel = new JPanel(new BorderLayout());
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
add(plotterPanel, BorderLayout.CENTER);
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
verboseCheckBox = new JCheckBox(Messages.VERBOSE_OUTPUT);
|
||||
verboseCheckBox.addActionListener(this);
|
||||
verboseCheckBox.setToolTipText(Messages.VERBOSE_OUTPUT_TOOLTIP);
|
||||
JPanel topRightPanel = new JPanel();
|
||||
topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
|
||||
topRightPanel.add(verboseCheckBox);
|
||||
topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
|
||||
|
||||
loadedClassesMeter = new PlotterPanel(Messages.NUMBER_OF_LOADED_CLASSES,
|
||||
Plotter.Unit.NONE, false);
|
||||
loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
|
||||
Messages.LOADED,
|
||||
loadedPlotterColor,
|
||||
true);
|
||||
loadedClassesMeter.plotter.createSequence(totalLoadedPlotterKey,
|
||||
Messages.TOTAL_LOADED,
|
||||
totalLoadedPlotterColor,
|
||||
true);
|
||||
setAccessibleName(loadedClassesMeter.plotter,
|
||||
Messages.CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME);
|
||||
plotterPanel.add(loadedClassesMeter);
|
||||
|
||||
timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
|
||||
controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox));
|
||||
|
||||
LabeledComponent.layout(plotterPanel);
|
||||
|
||||
bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
|
||||
new EmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
details = new HTMLPane();
|
||||
setAccessibleName(details, Messages.DETAILS);
|
||||
JScrollPane scrollPane = new JScrollPane(details);
|
||||
scrollPane.setPreferredSize(new Dimension(0, 150));
|
||||
bottomPanel.add(scrollPane, BorderLayout.SOUTH);
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
final boolean b = verboseCheckBox.isSelected();
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
try {
|
||||
proxyClient.getClassLoadingMXBean().setVerbose(b);
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
final ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
if (!plotterListening) {
|
||||
proxyClient.addWeakPropertyChangeListener(loadedClassesMeter.plotter);
|
||||
plotterListening = true;
|
||||
}
|
||||
|
||||
return new SwingWorker<Boolean, Object>() {
|
||||
private long clCount, cuCount, ctCount;
|
||||
private boolean isVerbose;
|
||||
private String detailsStr;
|
||||
private long timeStamp;
|
||||
|
||||
public Boolean doInBackground() {
|
||||
try {
|
||||
ClassLoadingMXBean classLoadingMBean = proxyClient.getClassLoadingMXBean();
|
||||
|
||||
clCount = classLoadingMBean.getLoadedClassCount();
|
||||
cuCount = classLoadingMBean.getUnloadedClassCount();
|
||||
ctCount = classLoadingMBean.getTotalLoadedClassCount();
|
||||
isVerbose = classLoadingMBean.isVerbose();
|
||||
detailsStr = formatDetails();
|
||||
timeStamp = System.currentTimeMillis();
|
||||
|
||||
return true;
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
if (get()) {
|
||||
loadedClassesMeter.plotter.addValues(timeStamp, clCount, ctCount);
|
||||
|
||||
if (overviewPanel != null) {
|
||||
overviewPanel.updateClassInfo(ctCount, clCount);
|
||||
overviewPanel.getPlotter().addValues(timeStamp, clCount);
|
||||
}
|
||||
|
||||
loadedClassesMeter.setValueLabel(clCount + "");
|
||||
verboseCheckBox.setSelected(isVerbose);
|
||||
details.setText(detailsStr);
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDetails() {
|
||||
String text = "<table cellspacing=0 cellpadding=0>";
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
String timeStamp = formatDateTime(time);
|
||||
text += newRow(Messages.TIME, timeStamp);
|
||||
text += newRow(Messages.CURRENT_CLASSES_LOADED, justify(clCount, 5));
|
||||
text += newRow(Messages.TOTAL_CLASSES_LOADED, justify(ctCount, 5));
|
||||
text += newRow(Messages.TOTAL_CLASSES_UNLOADED, justify(cuCount, 5));
|
||||
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new ClassOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
private static class ClassOverviewPanel extends OverviewPanel {
|
||||
ClassOverviewPanel() {
|
||||
super(Messages.CLASSES, loadedPlotterKey, Messages.LOADED, null);
|
||||
}
|
||||
|
||||
private void updateClassInfo(long total, long loaded) {
|
||||
long unloaded = (total - loaded);
|
||||
getInfoLabel().setText(Resources.format(Messages.CLASS_TAB_INFO_LABEL_FORMAT,
|
||||
loaded, unloaded, total));
|
||||
}
|
||||
}
|
||||
}
|
||||
768
jdkSrc/jdk8/sun/tools/jconsole/ConnectDialog.java
Normal file
768
jdkSrc/jdk8/sun/tools/jconsole/ConnectDialog.java
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.List;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.basic.BasicRadioButtonUI;
|
||||
import javax.swing.table.*;
|
||||
|
||||
|
||||
|
||||
import static java.awt.BorderLayout.*;
|
||||
import static javax.swing.ListSelectionModel.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ConnectDialog extends InternalDialog
|
||||
implements DocumentListener, FocusListener,
|
||||
ItemListener, ListSelectionListener, KeyListener {
|
||||
|
||||
private static final int COL_NAME = 0;
|
||||
private static final int COL_PID = 1;
|
||||
|
||||
|
||||
JConsole jConsole;
|
||||
JTextField userNameTF, passwordTF;
|
||||
JRadioButton localRadioButton, remoteRadioButton;
|
||||
JLabel localMessageLabel, remoteMessageLabel;
|
||||
JTextField remoteTF;
|
||||
JButton connectButton, cancelButton;
|
||||
JPanel radioButtonPanel;
|
||||
|
||||
private Icon mastheadIcon =
|
||||
new MastheadIcon(Messages.CONNECT_DIALOG_MASTHEAD_TITLE);
|
||||
private Color hintTextColor, disabledTableCellColor;
|
||||
|
||||
// The table of managed VM (local process)
|
||||
JTable vmTable;
|
||||
ManagedVmTableModel vmModel = null;
|
||||
|
||||
JScrollPane localTableScrollPane = null;
|
||||
|
||||
private Action connectAction, cancelAction;
|
||||
|
||||
|
||||
public ConnectDialog(JConsole jConsole) {
|
||||
super(jConsole, Messages.CONNECT_DIALOG_TITLE, true);
|
||||
|
||||
this.jConsole = jConsole;
|
||||
setAccessibleDescription(this,
|
||||
Messages.CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
Container cp = (JComponent)getContentPane();
|
||||
|
||||
radioButtonPanel = new JPanel(new BorderLayout(0, 12));
|
||||
radioButtonPanel.setBorder(new EmptyBorder(6, 12, 12, 12));
|
||||
ButtonGroup radioButtonGroup = new ButtonGroup();
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
statusBar = new JLabel(" ", JLabel.CENTER);
|
||||
setAccessibleName(statusBar,
|
||||
Messages.CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME);
|
||||
|
||||
Font normalLabelFont = statusBar.getFont();
|
||||
Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD);
|
||||
Font smallLabelFont = normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1);
|
||||
|
||||
JLabel mastheadLabel = new JLabel(mastheadIcon);
|
||||
setAccessibleName(mastheadLabel,
|
||||
Messages.CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
|
||||
|
||||
cp.add(mastheadLabel, NORTH);
|
||||
cp.add(radioButtonPanel, CENTER);
|
||||
cp.add(bottomPanel, SOUTH);
|
||||
|
||||
createActions();
|
||||
|
||||
remoteTF = new JTextField();
|
||||
remoteTF.addActionListener(connectAction);
|
||||
remoteTF.getDocument().addDocumentListener(this);
|
||||
remoteTF.addFocusListener(this);
|
||||
remoteTF.setPreferredSize(remoteTF.getPreferredSize());
|
||||
setAccessibleName(remoteTF,
|
||||
Messages.REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME);
|
||||
|
||||
//
|
||||
// If the VM supports the local attach mechanism (is: Sun
|
||||
// implementation) then the Local Process panel is created.
|
||||
//
|
||||
if (JConsole.isLocalAttachAvailable()) {
|
||||
vmModel = new ManagedVmTableModel();
|
||||
vmTable = new LocalTabJTable(vmModel);
|
||||
vmTable.setSelectionMode(SINGLE_SELECTION);
|
||||
vmTable.setPreferredScrollableViewportSize(new Dimension(400, 250));
|
||||
vmTable.setColumnSelectionAllowed(false);
|
||||
vmTable.addFocusListener(this);
|
||||
vmTable.getSelectionModel().addListSelectionListener(this);
|
||||
|
||||
TableColumnModel columnModel = vmTable.getColumnModel();
|
||||
|
||||
TableColumn pidColumn = columnModel.getColumn(COL_PID);
|
||||
pidColumn.setMaxWidth(getLabelWidth("9999999"));
|
||||
pidColumn.setResizable(false);
|
||||
|
||||
TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME);
|
||||
cmdLineColumn.setResizable(false);
|
||||
|
||||
localRadioButton = new JRadioButton(Messages.LOCAL_PROCESS_COLON);
|
||||
localRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.LOCAL_PROCESS_COLON));
|
||||
localRadioButton.setFont(boldLabelFont);
|
||||
localRadioButton.addItemListener(this);
|
||||
radioButtonGroup.add(localRadioButton);
|
||||
|
||||
JPanel localPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel localTablePanel = new JPanel(new BorderLayout());
|
||||
|
||||
radioButtonPanel.add(localPanel, NORTH);
|
||||
|
||||
localPanel.add(localRadioButton, NORTH);
|
||||
localPanel.add(new Padder(localRadioButton), LINE_START);
|
||||
localPanel.add(localTablePanel, CENTER);
|
||||
|
||||
localTableScrollPane = new JScrollPane(vmTable);
|
||||
|
||||
localTablePanel.add(localTableScrollPane, NORTH);
|
||||
|
||||
localMessageLabel = new JLabel(" ");
|
||||
localMessageLabel.setFont(smallLabelFont);
|
||||
localMessageLabel.setForeground(hintTextColor);
|
||||
localTablePanel.add(localMessageLabel, SOUTH);
|
||||
}
|
||||
|
||||
remoteRadioButton = new JRadioButton(Messages.REMOTE_PROCESS_COLON);
|
||||
remoteRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.REMOTE_PROCESS_COLON));
|
||||
remoteRadioButton.setFont(boldLabelFont);
|
||||
radioButtonGroup.add(remoteRadioButton);
|
||||
|
||||
JPanel remotePanel = new JPanel(new BorderLayout());
|
||||
if (localRadioButton != null) {
|
||||
remotePanel.add(remoteRadioButton, NORTH);
|
||||
remotePanel.add(new Padder(remoteRadioButton), LINE_START);
|
||||
|
||||
Action nextRadioButtonAction =
|
||||
new AbstractAction("nextRadioButton") {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
JRadioButton rb =
|
||||
(ev.getSource() == localRadioButton) ? remoteRadioButton
|
||||
: localRadioButton;
|
||||
rb.doClick();
|
||||
rb.requestFocus();
|
||||
}
|
||||
};
|
||||
|
||||
localRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
|
||||
remoteRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
|
||||
|
||||
localRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
|
||||
"nextRadioButton");
|
||||
remoteRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
|
||||
"nextRadioButton");
|
||||
} else {
|
||||
JLabel remoteLabel = new JLabel(remoteRadioButton.getText());
|
||||
remoteLabel.setFont(boldLabelFont);
|
||||
remotePanel.add(remoteLabel, NORTH);
|
||||
}
|
||||
radioButtonPanel.add(remotePanel, SOUTH);
|
||||
|
||||
JPanel remoteTFPanel = new JPanel(new BorderLayout());
|
||||
remotePanel.add(remoteTFPanel, CENTER);
|
||||
|
||||
remoteTFPanel.add(remoteTF, NORTH);
|
||||
|
||||
remoteMessageLabel = new JLabel("<html>" + Messages.REMOTE_TF_USAGE + "</html>");
|
||||
remoteMessageLabel.setFont(smallLabelFont);
|
||||
remoteMessageLabel.setForeground(hintTextColor);
|
||||
remoteTFPanel.add(remoteMessageLabel, CENTER);
|
||||
|
||||
JPanel userPwdPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
|
||||
userPwdPanel.setBorder(new EmptyBorder(12, 0, 0, 0)); // top padding
|
||||
|
||||
int tfWidth = JConsole.IS_WIN ? 12 : 8;
|
||||
|
||||
userNameTF = new JTextField(tfWidth);
|
||||
userNameTF.addActionListener(connectAction);
|
||||
userNameTF.getDocument().addDocumentListener(this);
|
||||
userNameTF.addFocusListener(this);
|
||||
setAccessibleName(userNameTF,
|
||||
Messages.USERNAME_ACCESSIBLE_NAME);
|
||||
LabeledComponent lc;
|
||||
lc = new LabeledComponent(Messages.USERNAME_COLON_,
|
||||
Resources.getMnemonicInt(Messages.USERNAME_COLON_),
|
||||
userNameTF);
|
||||
lc.label.setFont(boldLabelFont);
|
||||
userPwdPanel.add(lc);
|
||||
|
||||
passwordTF = new JPasswordField(tfWidth);
|
||||
// Heights differ, so fix here
|
||||
passwordTF.setPreferredSize(userNameTF.getPreferredSize());
|
||||
passwordTF.addActionListener(connectAction);
|
||||
passwordTF.getDocument().addDocumentListener(this);
|
||||
passwordTF.addFocusListener(this);
|
||||
setAccessibleName(passwordTF,
|
||||
Messages.PASSWORD_ACCESSIBLE_NAME);
|
||||
|
||||
lc = new LabeledComponent(Messages.PASSWORD_COLON_,
|
||||
Resources.getMnemonicInt(Messages.PASSWORD_COLON_),
|
||||
passwordTF);
|
||||
lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding
|
||||
lc.label.setFont(boldLabelFont);
|
||||
userPwdPanel.add(lc);
|
||||
|
||||
remoteTFPanel.add(userPwdPanel, SOUTH);
|
||||
|
||||
String connectButtonToolTipText =
|
||||
Messages.CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
|
||||
connectButton = new JButton(connectAction);
|
||||
connectButton.setToolTipText(connectButtonToolTipText);
|
||||
|
||||
cancelButton = new JButton(cancelAction);
|
||||
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
|
||||
buttonPanel.setBorder(new EmptyBorder(12, 12, 2, 12));
|
||||
if (JConsole.IS_GTK) {
|
||||
buttonPanel.add(cancelButton);
|
||||
buttonPanel.add(connectButton);
|
||||
} else {
|
||||
buttonPanel.add(connectButton);
|
||||
buttonPanel.add(cancelButton);
|
||||
}
|
||||
bottomPanel.add(buttonPanel, NORTH);
|
||||
|
||||
bottomPanel.add(statusBar, SOUTH);
|
||||
|
||||
updateButtonStates();
|
||||
Utilities.updateTransparency(this);
|
||||
}
|
||||
|
||||
public void revalidate() {
|
||||
// Adjust some colors
|
||||
Color disabledForeground = UIManager.getColor("Label.disabledForeground");
|
||||
if (disabledForeground == null) {
|
||||
// fall back for Nimbus that doesn't support 'Label.disabledForeground'
|
||||
disabledForeground = UIManager.getColor("Label.disabledText");
|
||||
}
|
||||
hintTextColor =
|
||||
ensureContrast(disabledForeground,
|
||||
UIManager.getColor("Panel.background"));
|
||||
disabledTableCellColor =
|
||||
ensureContrast(new Color(0x808080),
|
||||
UIManager.getColor("Table.background"));
|
||||
|
||||
if (remoteMessageLabel != null) {
|
||||
remoteMessageLabel.setForeground(hintTextColor);
|
||||
// Update html color setting
|
||||
String colorStr =
|
||||
String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
|
||||
remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" +
|
||||
Messages.REMOTE_TF_USAGE);
|
||||
}
|
||||
if (localMessageLabel != null) {
|
||||
localMessageLabel.setForeground(hintTextColor);
|
||||
// Update html color setting
|
||||
valueChanged(null);
|
||||
}
|
||||
|
||||
super.revalidate();
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
connectAction = new AbstractAction(Messages.CONNECT) {
|
||||
/* init */ {
|
||||
putValue(Action.MNEMONIC_KEY, Resources.getMnemonicInt(Messages.CONNECT));
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
if (!isEnabled() || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
String txt = remoteTF.getText().trim();
|
||||
String userName = userNameTF.getText().trim();
|
||||
userName = userName.equals("") ? null : userName;
|
||||
String password = passwordTF.getText();
|
||||
password = password.equals("") ? null : password;
|
||||
try {
|
||||
if (txt.startsWith(JConsole.ROOT_URL)) {
|
||||
String url = txt;
|
||||
jConsole.addUrl(url, userName, password, false);
|
||||
remoteTF.setText(JConsole.ROOT_URL);
|
||||
return;
|
||||
} else {
|
||||
String host = remoteTF.getText().trim();
|
||||
String port = "0";
|
||||
int index = host.lastIndexOf(":");
|
||||
if (index >= 0) {
|
||||
port = host.substring(index + 1);
|
||||
host = host.substring(0, index);
|
||||
}
|
||||
if (host.length() > 0 && port.length() > 0) {
|
||||
int p = Integer.parseInt(port.trim());
|
||||
jConsole.addHost(host, p, userName, password);
|
||||
remoteTF.setText("");
|
||||
userNameTF.setText("");
|
||||
passwordTF.setText("");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
statusBar.setText(ex.toString());
|
||||
}
|
||||
setVisible(true);
|
||||
} else if (localRadioButton != null && localRadioButton.isSelected()) {
|
||||
// Try to connect to selected VM. If a connection
|
||||
// cannot be established for some reason (the process has
|
||||
// terminated for example) then keep the dialog open showing
|
||||
// the connect error.
|
||||
//
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
jConsole.addVmid(vmModel.vmAt(row));
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cancelAction = new AbstractAction(Messages.CANCEL) {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// a label used solely for calculating the width
|
||||
private static JLabel tmpLabel = new JLabel();
|
||||
public static int getLabelWidth(String text) {
|
||||
tmpLabel.setText(text);
|
||||
return (int) tmpLabel.getPreferredSize().getWidth() + 1;
|
||||
}
|
||||
|
||||
private class LocalTabJTable extends JTable {
|
||||
ManagedVmTableModel vmModel;
|
||||
Border rendererBorder = new EmptyBorder(0, 6, 0, 6);
|
||||
|
||||
public LocalTabJTable(ManagedVmTableModel model) {
|
||||
super(model);
|
||||
this.vmModel = model;
|
||||
|
||||
// Remove vertical lines, expect for GTK L&F.
|
||||
// (because GTK doesn't show header dividers)
|
||||
if (!JConsole.IS_GTK) {
|
||||
setShowVerticalLines(false);
|
||||
setIntercellSpacing(new Dimension(0, 1));
|
||||
}
|
||||
|
||||
// Double-click handler
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent evt) {
|
||||
if (evt.getClickCount() == 2) {
|
||||
connectButton.doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Enter should call default action
|
||||
getActionMap().put("connect", connectAction);
|
||||
InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "connect");
|
||||
}
|
||||
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
String tip = null;
|
||||
java.awt.Point p = e.getPoint();
|
||||
int rowIndex = rowAtPoint(p);
|
||||
int colIndex = columnAtPoint(p);
|
||||
int realColumnIndex = convertColumnIndexToModel(colIndex);
|
||||
|
||||
if (realColumnIndex == COL_NAME) {
|
||||
LocalVirtualMachine vmd = vmModel.vmAt(rowIndex);
|
||||
tip = vmd.toString();
|
||||
}
|
||||
return tip;
|
||||
}
|
||||
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
return new DefaultTableCellRenderer() {
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
boolean hasFocus,
|
||||
int row,
|
||||
int column) {
|
||||
Component comp =
|
||||
super.getTableCellRendererComponent(table, value, isSelected,
|
||||
hasFocus, row, column);
|
||||
|
||||
if (!isSelected) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
if (!lvm.isManageable() && !lvm.isAttachable()) {
|
||||
comp.setForeground(disabledTableCellColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (comp instanceof JLabel) {
|
||||
JLabel label = (JLabel)comp;
|
||||
label.setBorder(rendererBorder);
|
||||
|
||||
if (value instanceof Integer) {
|
||||
label.setHorizontalAlignment(JLabel.RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void setConnectionParameters(String url,
|
||||
String host,
|
||||
int port,
|
||||
String userName,
|
||||
String password,
|
||||
String msg) {
|
||||
if ((url != null && url.length() > 0) ||
|
||||
(host != null && host.length() > 0 && port > 0)) {
|
||||
|
||||
remoteRadioButton.setSelected(true);
|
||||
if (url != null && url.length() > 0) {
|
||||
remoteTF.setText(url);
|
||||
} else {
|
||||
remoteTF.setText(host+":"+port);
|
||||
}
|
||||
userNameTF.setText((userName != null) ? userName : "");
|
||||
passwordTF.setText((password != null) ? password : "");
|
||||
|
||||
statusBar.setText((msg != null) ? msg : "");
|
||||
if (getPreferredSize().width > getWidth()) {
|
||||
pack();
|
||||
}
|
||||
remoteTF.requestFocus();
|
||||
remoteTF.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void itemStateChanged(ItemEvent ev) {
|
||||
if (!localRadioButton.isSelected()) {
|
||||
vmTable.getSelectionModel().clearSelection();
|
||||
}
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
private void updateButtonStates() {
|
||||
boolean connectEnabled = false;
|
||||
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
connectEnabled = JConsole.isValidRemoteString(remoteTF.getText());
|
||||
} else if (localRadioButton != null && localRadioButton.isSelected()) {
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
connectEnabled = (lvm.isManageable() || lvm.isAttachable());
|
||||
}
|
||||
}
|
||||
|
||||
connectAction.setEnabled(connectEnabled);
|
||||
}
|
||||
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
Object source = e.getSource();
|
||||
Component opposite = e.getOppositeComponent();
|
||||
|
||||
if (!e.isTemporary() &&
|
||||
source instanceof JTextField &&
|
||||
opposite instanceof JComponent &&
|
||||
SwingUtilities.getRootPane(opposite) == getRootPane()) {
|
||||
|
||||
((JTextField)source).selectAll();
|
||||
}
|
||||
|
||||
if (source == remoteTF) {
|
||||
remoteRadioButton.setSelected(true);
|
||||
} else if (source == vmTable) {
|
||||
localRadioButton.setSelected(true);
|
||||
if (vmModel.getRowCount() == 1) {
|
||||
// if there's only one process then select the row
|
||||
vmTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) {
|
||||
char c = e.getKeyChar();
|
||||
if (c == KeyEvent.VK_ESCAPE) {
|
||||
setVisible(false);
|
||||
} else if (!(Character.isDigit(c) ||
|
||||
c == KeyEvent.VK_BACK_SPACE ||
|
||||
c == KeyEvent.VK_DELETE)) {
|
||||
getToolkit().beep();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean b) {
|
||||
boolean wasVisible = isVisible();
|
||||
super.setVisible(b);
|
||||
if (b && !wasVisible) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
remoteTF.requestFocus();
|
||||
remoteTF.selectAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
|
||||
// ListSelectionListener interface
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateButtonStates();
|
||||
String labelText = " "; // Non-empty to reserve vertical space
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
if (!lvm.isManageable()) {
|
||||
if (lvm.isAttachable()) {
|
||||
labelText = Messages.MANAGEMENT_WILL_BE_ENABLED;
|
||||
} else {
|
||||
labelText = Messages.MANAGEMENT_NOT_ENABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
String colorStr =
|
||||
String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
|
||||
localMessageLabel.setText("<html><font color=#" + colorStr + ">" + labelText);
|
||||
}
|
||||
// ----
|
||||
|
||||
|
||||
// Refresh the list of managed VMs
|
||||
public void refresh() {
|
||||
if (vmModel != null) {
|
||||
// Remember selection
|
||||
LocalVirtualMachine selected = null;
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
selected = vmModel.vmAt(row);
|
||||
}
|
||||
|
||||
vmModel.refresh();
|
||||
|
||||
int selectRow = -1;
|
||||
int n = vmModel.getRowCount();
|
||||
if (selected != null) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(i);
|
||||
if (selected.vmid() == lvm.vmid() &&
|
||||
selected.toString().equals(lvm.toString())) {
|
||||
|
||||
selectRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectRow > -1) {
|
||||
vmTable.setRowSelectionInterval(selectRow, selectRow);
|
||||
} else {
|
||||
vmTable.getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
Dimension dim = vmTable.getPreferredSize();
|
||||
|
||||
// Tricky. Reduce height by one to avoid double line at bottom,
|
||||
// but that causes a scroll bar to appear, so remove it.
|
||||
dim.height = Math.min(dim.height-1, 100);
|
||||
localTableScrollPane.setVerticalScrollBarPolicy((dim.height < 100)
|
||||
? JScrollPane.VERTICAL_SCROLLBAR_NEVER
|
||||
: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
localTableScrollPane.getViewport().setMinimumSize(dim);
|
||||
localTableScrollPane.getViewport().setPreferredSize(dim);
|
||||
}
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
}
|
||||
|
||||
// Represents the list of managed VMs as a tabular data model.
|
||||
private static class ManagedVmTableModel extends AbstractTableModel {
|
||||
private static String[] columnNames = {
|
||||
Messages.COLUMN_NAME,
|
||||
Messages.COLUMN_PID,
|
||||
};
|
||||
|
||||
private List<LocalVirtualMachine> vmList;
|
||||
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
public String getColumnName(int col) {
|
||||
return columnNames[col];
|
||||
}
|
||||
|
||||
public synchronized int getRowCount() {
|
||||
return vmList.size();
|
||||
}
|
||||
|
||||
public synchronized Object getValueAt(int row, int col) {
|
||||
assert col >= 0 && col <= columnNames.length;
|
||||
LocalVirtualMachine vm = vmList.get(row);
|
||||
switch (col) {
|
||||
case COL_NAME: return vm.displayName();
|
||||
case COL_PID: return vm.vmid();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getColumnClass(int column) {
|
||||
switch (column) {
|
||||
case COL_NAME: return String.class;
|
||||
case COL_PID: return Integer.class;
|
||||
default: return super.getColumnClass(column);
|
||||
}
|
||||
}
|
||||
|
||||
public ManagedVmTableModel() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
public synchronized LocalVirtualMachine vmAt(int pos) {
|
||||
return vmList.get(pos);
|
||||
}
|
||||
|
||||
public synchronized void refresh() {
|
||||
Map<Integer, LocalVirtualMachine> map =
|
||||
LocalVirtualMachine.getAllVirtualMachines();
|
||||
vmList = new ArrayList<LocalVirtualMachine>();
|
||||
vmList.addAll(map.values());
|
||||
|
||||
// data has changed
|
||||
fireTableDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// A blank component that takes up as much space as the
|
||||
// button part of a JRadioButton.
|
||||
private static class Padder extends JPanel {
|
||||
JRadioButton radioButton;
|
||||
|
||||
Padder(JRadioButton radioButton) {
|
||||
this.radioButton = radioButton;
|
||||
|
||||
setAccessibleName(this, Messages.BLANK);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
Rectangle r = getTextRectangle(radioButton);
|
||||
int w = (r != null && r.x > 8) ? r.x : 22;
|
||||
|
||||
return new Dimension(w, 0);
|
||||
}
|
||||
|
||||
private static Rectangle getTextRectangle(AbstractButton button) {
|
||||
String text = button.getText();
|
||||
Icon icon = (button.isEnabled()) ? button.getIcon() : button.getDisabledIcon();
|
||||
|
||||
if (icon == null && button.getUI() instanceof BasicRadioButtonUI) {
|
||||
icon = ((BasicRadioButtonUI)button.getUI()).getDefaultIcon();
|
||||
}
|
||||
|
||||
if ((icon == null) && (text == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle paintIconR = new Rectangle();
|
||||
Rectangle paintTextR = new Rectangle();
|
||||
Rectangle paintViewR = new Rectangle();
|
||||
Insets paintViewInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
paintViewInsets = button.getInsets(paintViewInsets);
|
||||
paintViewR.x = paintViewInsets.left;
|
||||
paintViewR.y = paintViewInsets.top;
|
||||
paintViewR.width = button.getWidth() - (paintViewInsets.left + paintViewInsets.right);
|
||||
paintViewR.height = button.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
|
||||
|
||||
Graphics g = button.getGraphics();
|
||||
if (g == null) {
|
||||
return null;
|
||||
}
|
||||
SwingUtilities.layoutCompoundLabel(button,
|
||||
g.getFontMetrics(),
|
||||
text,
|
||||
icon,
|
||||
button.getVerticalAlignment(),
|
||||
button.getHorizontalAlignment(),
|
||||
button.getVerticalTextPosition(),
|
||||
button.getHorizontalTextPosition(),
|
||||
paintViewR,
|
||||
paintIconR,
|
||||
paintTextR,
|
||||
button.getIconTextGap());
|
||||
|
||||
return paintTextR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
197
jdkSrc/jdk8/sun/tools/jconsole/CreateMBeanDialog.java
Normal file
197
jdkSrc/jdk8/sun/tools/jconsole/CreateMBeanDialog.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CreateMBeanDialog extends InternalDialog
|
||||
implements ActionListener {
|
||||
JConsole jConsole;
|
||||
JComboBox<ProxyClient> connections;
|
||||
JButton createMBeanButton, unregisterMBeanButton, cancelButton;
|
||||
|
||||
private static final String HOTSPOT_MBEAN =
|
||||
"sun.management.HotspotInternal";
|
||||
private static final String HOTSPOT_MBEAN_OBJECTNAME =
|
||||
"sun.management:type=HotspotInternal";
|
||||
public CreateMBeanDialog(JConsole jConsole) {
|
||||
super(jConsole, "JConsole: Hotspot MBeans", true);
|
||||
|
||||
this.jConsole = jConsole;
|
||||
setAccessibleDescription(this,
|
||||
Messages.HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
Container cp = getContentPane();
|
||||
((JComponent)cp).setBorder(new EmptyBorder(10, 10, 4, 10));
|
||||
|
||||
JPanel centerPanel = new JPanel(new VariableGridLayout(0,
|
||||
1,
|
||||
4,
|
||||
4,
|
||||
false,
|
||||
true));
|
||||
cp.add(centerPanel, BorderLayout.CENTER);
|
||||
connections = new JComboBox<ProxyClient>();
|
||||
updateConnections();
|
||||
|
||||
centerPanel.add(new LabeledComponent(Resources.format(Messages.MANAGE_HOTSPOT_MBEANS_IN_COLON_),
|
||||
connections));
|
||||
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
cp.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
bottomPanel.add(buttonPanel, BorderLayout.NORTH);
|
||||
buttonPanel.add(createMBeanButton =
|
||||
new JButton(Messages.CREATE));
|
||||
buttonPanel.add(unregisterMBeanButton =
|
||||
new JButton(Messages.UNREGISTER));
|
||||
buttonPanel.add(cancelButton =
|
||||
new JButton(Messages.CANCEL));
|
||||
|
||||
statusBar = new JLabel(" ", JLabel.CENTER);
|
||||
bottomPanel.add(statusBar, BorderLayout.SOUTH);
|
||||
|
||||
createMBeanButton.addActionListener(this);
|
||||
unregisterMBeanButton.addActionListener(this);
|
||||
cancelButton.addActionListener(this);
|
||||
|
||||
LabeledComponent.layout(centerPanel);
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
}
|
||||
|
||||
private void updateConnections() {
|
||||
List<VMInternalFrame> frames = jConsole.getInternalFrames();
|
||||
TreeSet<ProxyClient> data =
|
||||
new TreeSet<ProxyClient>(new Comparator<ProxyClient>() {
|
||||
public int compare(ProxyClient o1, ProxyClient o2) {
|
||||
// TODO: Need to understand how this method being used?
|
||||
return o1.connectionName().compareTo(o2.connectionName());
|
||||
}
|
||||
});
|
||||
|
||||
if (frames.size() == 0) {
|
||||
JComponent cp = (JComponent)jConsole.getContentPane();
|
||||
Component comp = ((BorderLayout)cp.getLayout()).
|
||||
getLayoutComponent(BorderLayout.CENTER);
|
||||
if (comp instanceof VMPanel) {
|
||||
VMPanel vmpanel = (VMPanel) comp;
|
||||
ProxyClient client = vmpanel.getProxyClient(false);
|
||||
if (client != null && client.hasPlatformMXBeans()) {
|
||||
data.add(client);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (VMInternalFrame f : frames) {
|
||||
ProxyClient client = f.getVMPanel().getProxyClient(false);
|
||||
if (client != null && client.hasPlatformMXBeans()) {
|
||||
data.add(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
connections.invalidate();
|
||||
connections.setModel(new DefaultComboBoxModel<ProxyClient>
|
||||
(data.toArray(new ProxyClient[data.size()])));
|
||||
connections.validate();
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
if (ev.getSource() != cancelButton) {
|
||||
new Thread("CreateMBeanDialog.actionPerformed") {
|
||||
public void run() {
|
||||
try {
|
||||
Object c = connections.getSelectedItem();
|
||||
if(c == null) return;
|
||||
if(ev.getSource() == createMBeanButton) {
|
||||
MBeanServerConnection connection =
|
||||
((ProxyClient) c).
|
||||
getMBeanServerConnection();
|
||||
connection.createMBean(HOTSPOT_MBEAN, null);
|
||||
} else {
|
||||
if(ev.getSource() == unregisterMBeanButton) {
|
||||
MBeanServerConnection connection =
|
||||
((ProxyClient) c).
|
||||
getMBeanServerConnection();
|
||||
connection.unregisterMBean(new
|
||||
ObjectName(HOTSPOT_MBEAN_OBJECTNAME));
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch(InstanceAlreadyExistsException e) {
|
||||
statusBar.setText(Messages.ERROR_COLON_MBEANS_ALREADY_EXIST);
|
||||
} catch(InstanceNotFoundException e) {
|
||||
statusBar.setText(Messages.ERROR_COLON_MBEANS_DO_NOT_EXIST);
|
||||
} catch(Exception e) {
|
||||
statusBar.setText(e.toString());
|
||||
}
|
||||
setVisible(true);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean b) {
|
||||
boolean wasVisible = isVisible();
|
||||
|
||||
if(b) {
|
||||
setLocationRelativeTo(jConsole);
|
||||
invalidate();
|
||||
updateConnections();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
super.setVisible(b);
|
||||
|
||||
|
||||
if (b && !wasVisible) {
|
||||
// Need to delay this to make focus stick
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
connections.requestFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
126
jdkSrc/jdk8/sun/tools/jconsole/ExceptionSafePlugin.java
Normal file
126
jdkSrc/jdk8/sun/tools/jconsole/ExceptionSafePlugin.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import com.sun.tools.jconsole.JConsolePlugin;
|
||||
|
||||
/**
|
||||
* Proxy that shields GUI from plug-in exceptions.
|
||||
*
|
||||
*/
|
||||
final class ExceptionSafePlugin extends JConsolePlugin {
|
||||
|
||||
private static boolean ignoreExceptions;
|
||||
private final JConsolePlugin plugin;
|
||||
|
||||
public ExceptionSafePlugin(JConsolePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, JPanel> getTabs() {
|
||||
try {
|
||||
return plugin.getTabs();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
try {
|
||||
return plugin.newSwingWorker();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
plugin.dispose();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void executeSwingWorker(SwingWorker<?, ?> sw) {
|
||||
try {
|
||||
sw.execute();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Plug-in exception:");
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
if (!ignoreExceptions) {
|
||||
showExceptionDialog(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showExceptionDialog(Exception e) {
|
||||
Object[] buttonTexts = {
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_OK,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE
|
||||
};
|
||||
|
||||
String message = String.format(
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_MESSAGE,
|
||||
plugin.getClass().getSimpleName(),
|
||||
String.valueOf(e.getMessage())
|
||||
);
|
||||
|
||||
int buttonIndex = JOptionPane.showOptionDialog(
|
||||
null,
|
||||
message,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_TITLE,
|
||||
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||
JOptionPane.ERROR_MESSAGE,
|
||||
null,
|
||||
buttonTexts,
|
||||
buttonTexts[0]
|
||||
);
|
||||
|
||||
if (buttonIndex == 1) {
|
||||
System.exit(0);
|
||||
}
|
||||
ignoreExceptions = buttonIndex == 2;
|
||||
}
|
||||
}
|
||||
272
jdkSrc/jdk8/sun/tools/jconsole/Formatter.java
Normal file
272
jdkSrc/jdk8/sun/tools/jconsole/Formatter.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
class Formatter {
|
||||
final static long SECOND = 1000;
|
||||
final static long MINUTE = 60 * SECOND;
|
||||
final static long HOUR = 60 * MINUTE;
|
||||
final static long DAY = 24 * HOUR;
|
||||
|
||||
final static String cr = System.getProperty("line.separator");
|
||||
|
||||
final static DateFormat timeDF = new SimpleDateFormat("HH:mm");
|
||||
private final static DateFormat timeWithSecondsDF = new SimpleDateFormat("HH:mm:ss");
|
||||
private final static DateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private final static String decimalZero =
|
||||
new DecimalFormatSymbols().getDecimalSeparator() + "0";
|
||||
|
||||
static String formatTime(long t) {
|
||||
String str;
|
||||
if (t < 1 * MINUTE) {
|
||||
String seconds = String.format("%.3f", t / (double)SECOND);
|
||||
str = Resources.format(Messages.DURATION_SECONDS, seconds);
|
||||
} else {
|
||||
long remaining = t;
|
||||
long days = remaining / DAY;
|
||||
remaining %= 1 * DAY;
|
||||
long hours = remaining / HOUR;
|
||||
remaining %= 1 * HOUR;
|
||||
long minutes = remaining / MINUTE;
|
||||
|
||||
if (t >= 1 * DAY) {
|
||||
str = Resources.format(Messages.DURATION_DAYS_HOURS_MINUTES,
|
||||
days, hours, minutes);
|
||||
} else if (t >= 1 * HOUR) {
|
||||
str = Resources.format(Messages.DURATION_HOURS_MINUTES,
|
||||
hours, minutes);
|
||||
} else {
|
||||
str = Resources.format(Messages.DURATION_MINUTES, minutes);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static String formatNanoTime(long t) {
|
||||
long ms = t / 1000000;
|
||||
return formatTime(ms);
|
||||
}
|
||||
|
||||
|
||||
static String formatClockTime(long time) {
|
||||
return timeDF.format(time);
|
||||
}
|
||||
|
||||
static String formatDate(long time) {
|
||||
return dateDF.format(time);
|
||||
}
|
||||
|
||||
static String formatDateTime(long time) {
|
||||
return dateDF.format(time) + " " + timeWithSecondsDF.format(time);
|
||||
}
|
||||
|
||||
static DateFormat getDateTimeFormat(String dtfStr) {
|
||||
int dateStyle = -1;
|
||||
int timeStyle = -1;
|
||||
|
||||
if (dtfStr.startsWith("SHORT")) {
|
||||
dateStyle = DateFormat.SHORT;
|
||||
} else if (dtfStr.startsWith("MEDIUM")) {
|
||||
dateStyle = DateFormat.MEDIUM;
|
||||
} else if (dtfStr.startsWith("LONG")) {
|
||||
dateStyle = DateFormat.LONG;
|
||||
} else if (dtfStr.startsWith("FULL")) {
|
||||
dateStyle = DateFormat.FULL;
|
||||
}
|
||||
|
||||
if (dtfStr.endsWith("SHORT")) {
|
||||
timeStyle = DateFormat.SHORT;
|
||||
} else if (dtfStr.endsWith("MEDIUM")) {
|
||||
timeStyle = DateFormat.MEDIUM;
|
||||
} else if (dtfStr.endsWith("LONG")) {
|
||||
timeStyle = DateFormat.LONG;
|
||||
} else if (dtfStr.endsWith("FULL")) {
|
||||
timeStyle = DateFormat.FULL;
|
||||
}
|
||||
|
||||
if (dateStyle != -1 && timeStyle != -1) {
|
||||
return DateFormat.getDateTimeInstance(dateStyle, timeStyle);
|
||||
} else if (dtfStr.length() > 0) {
|
||||
return new SimpleDateFormat(dtfStr);
|
||||
} else {
|
||||
return DateFormat.getDateTimeInstance();
|
||||
}
|
||||
}
|
||||
|
||||
static double toExcelTime(long time) {
|
||||
// Excel is bug compatible with Lotus 1-2-3 and pretends
|
||||
// that 1900 was a leap year, so count from 1899-12-30.
|
||||
// Note that the month index is zero-based in Calendar.
|
||||
Calendar cal = new GregorianCalendar(1899, 11, 30);
|
||||
|
||||
// Adjust for the fact that now may be DST but then wasn't
|
||||
Calendar tmpCal = new GregorianCalendar();
|
||||
tmpCal.setTimeInMillis(time);
|
||||
int dst = tmpCal.get(Calendar.DST_OFFSET);
|
||||
if (dst > 0) {
|
||||
cal.set(Calendar.DST_OFFSET, dst);
|
||||
}
|
||||
|
||||
long millisSince1900 = time - cal.getTimeInMillis();
|
||||
double value = (double)millisSince1900 / (24 * 60 * 60 * 1000);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static String[] formatKByteStrings(long... bytes) {
|
||||
int n = bytes.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (bytes[i] > 0) {
|
||||
bytes[i] /= 1024;
|
||||
}
|
||||
}
|
||||
String[] strings = formatLongs(bytes);
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = Resources.format(Messages.KBYTES, strings[i]);
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
static String formatKBytes(long bytes) {
|
||||
if (bytes == -1) {
|
||||
return Resources.format(Messages.KBYTES, "-1");
|
||||
}
|
||||
|
||||
long kb = bytes / 1024;
|
||||
return Resources.format(Messages.KBYTES, justify(kb, 10));
|
||||
}
|
||||
|
||||
|
||||
static String formatBytes(long v, boolean html) {
|
||||
return formatBytes(v, v, html);
|
||||
}
|
||||
|
||||
static String formatBytes(long v, long vMax) {
|
||||
return formatBytes(v, vMax, false);
|
||||
}
|
||||
|
||||
static String formatBytes(long v, long vMax, boolean html) {
|
||||
String s;
|
||||
|
||||
int exp = (int)Math.log10((double)vMax);
|
||||
|
||||
if (exp < 3) {
|
||||
s = Resources.format(Messages.SIZE_BYTES, v);
|
||||
} else if (exp < 6) {
|
||||
s = Resources.format(Messages.SIZE_KB, trimDouble(v / Math.pow(10.0, 3)));
|
||||
} else if (exp < 9) {
|
||||
s = Resources.format(Messages.SIZE_MB, trimDouble(v / Math.pow(10.0, 6)));
|
||||
} else {
|
||||
s = Resources.format(Messages.SIZE_GB, trimDouble(v / Math.pow(10.0, 9)));
|
||||
}
|
||||
if (html) {
|
||||
s = s.replace(" ", " ");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the input value rounded to one decimal place. If after
|
||||
* rounding the string ends in the (locale-specific) decimal point
|
||||
* followed by a zero then trim that off as well.
|
||||
*/
|
||||
private static String trimDouble(double d) {
|
||||
String s = String.format("%.1f", d);
|
||||
if (s.length() > 3 && s.endsWith(decimalZero)) {
|
||||
s = s.substring(0, s.length()-2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static String formatLong(long value) {
|
||||
return String.format("%,d", value);
|
||||
}
|
||||
|
||||
static String[] formatLongs(long... longs) {
|
||||
int n = longs.length;
|
||||
int size = 0;
|
||||
String[] strings = new String[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = formatLong(longs[i]);
|
||||
size = Math.max(size, strings[i].length());
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = justify(strings[i], size);
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
|
||||
// A poor attempt at right-justifying for numerical data
|
||||
static String justify(long value, int size) {
|
||||
return justify(formatLong(value), size);
|
||||
}
|
||||
|
||||
static String justify(String str, int size) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<TT>");
|
||||
int n = size - str.length();
|
||||
for (int i = 0; i < n; i++) {
|
||||
buf.append(" ");
|
||||
}
|
||||
buf.append(str);
|
||||
buf.append("</TT>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static String newRow(String label, String value) {
|
||||
return newRow(label, value, 2);
|
||||
}
|
||||
|
||||
static String newRow(String label, String value, int columnPerRow) {
|
||||
if (label == null) {
|
||||
label = "";
|
||||
} else {
|
||||
label += ": ";
|
||||
}
|
||||
label = "<th nowrap align=right valign=top>" + label;
|
||||
value = "<td colspan=" + (columnPerRow-1) + "> <font size =-1>" + value;
|
||||
|
||||
return "<tr>" + label + value + "</tr>";
|
||||
}
|
||||
|
||||
static String newRow(String label1, String value1,
|
||||
String label2, String value2) {
|
||||
label1 = "<th nowrap align=right valign=top>" + label1 + ": ";
|
||||
value1 = "<td><font size =-1>" + value1;
|
||||
label2 = "<th nowrap align=right valign=top>" + label2 + ": ";
|
||||
value2 = "<td><font size =-1>" + value2;
|
||||
|
||||
return "<tr>" + label1 + value1 + label2 + value2 + "</tr>";
|
||||
}
|
||||
|
||||
}
|
||||
65
jdkSrc/jdk8/sun/tools/jconsole/HTMLPane.java
Normal file
65
jdkSrc/jdk8/sun/tools/jconsole/HTMLPane.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class HTMLPane extends JEditorPane {
|
||||
private boolean hasSelection = false;
|
||||
|
||||
public HTMLPane() {
|
||||
setContentType("text/html");
|
||||
setEditable(false);
|
||||
((DefaultCaret)getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
|
||||
addCaretListener(new CaretListener() {
|
||||
// Listen for selection changes
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
setHasSelection(e.getDot() != e.getMark());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void setHasSelection(boolean b) {
|
||||
hasSelection = b;
|
||||
}
|
||||
|
||||
public synchronized boolean getHasSelection() {
|
||||
return hasSelection;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
// Apply update only if a selection is not active
|
||||
if (!getHasSelection()) {
|
||||
// JEditorPane does not automatically pick up fg color
|
||||
String textColor =
|
||||
String.format("%06x", getForeground().getRGB() & 0xFFFFFF);
|
||||
super.setText("<html><body text=#"+textColor+">" + text + "</body></html>");
|
||||
}
|
||||
}
|
||||
}
|
||||
127
jdkSrc/jdk8/sun/tools/jconsole/InternalDialog.java
Normal file
127
jdkSrc/jdk8/sun/tools/jconsole/InternalDialog.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
import static javax.swing.JLayeredPane.*;
|
||||
|
||||
/**
|
||||
* Used instead of JDialog in a JDesktopPane/JInternalFrame environment.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InternalDialog extends JInternalFrame {
|
||||
protected JLabel statusBar;
|
||||
|
||||
public InternalDialog(JConsole jConsole, String title, boolean modal) {
|
||||
super(title, true, true, false, false);
|
||||
|
||||
setLayer(PALETTE_LAYER);
|
||||
putClientProperty("JInternalFrame.frameType", "optionDialog");
|
||||
|
||||
jConsole.getDesktopPane().add(this);
|
||||
|
||||
|
||||
getActionMap().put("cancel", new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
setVisible(false);
|
||||
if (statusBar != null) {
|
||||
statusBar.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
|
||||
}
|
||||
|
||||
public void setLocationRelativeTo(Component c) {
|
||||
setLocation((c.getWidth() - getWidth()) / 2,
|
||||
(c.getHeight() - getHeight()) / 2);
|
||||
}
|
||||
|
||||
protected class MastheadIcon implements Icon {
|
||||
// Important: Assume image background is white!
|
||||
private ImageIcon leftIcon =
|
||||
new ImageIcon(InternalDialog.class.getResource("resources/masthead-left.png"));
|
||||
private ImageIcon rightIcon =
|
||||
new ImageIcon(InternalDialog.class.getResource("resources/masthead-right.png"));
|
||||
|
||||
private Font font = Font.decode(Messages.MASTHEAD_FONT);
|
||||
private int gap = 10;
|
||||
private String title;
|
||||
|
||||
public MastheadIcon(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
// Clone the Graphics object
|
||||
g = g.create();
|
||||
|
||||
// Ignore x to make sure we fill entire component width
|
||||
x = 0;
|
||||
int width = c.getWidth();
|
||||
int lWidth = leftIcon.getIconWidth();
|
||||
int rWidth = rightIcon.getIconWidth();
|
||||
int height = getIconHeight();
|
||||
int textHeight = g.getFontMetrics(font).getAscent();
|
||||
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(x, y, width, height);
|
||||
|
||||
leftIcon.paintIcon(c, g, x, y);
|
||||
rightIcon.paintIcon(c, g, width - rWidth, y);
|
||||
|
||||
g.setFont(font);
|
||||
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.setColor(new Color(0x35556b));
|
||||
g.drawString(title, lWidth + gap, height/2 + textHeight/2);
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
int textWidth = 0;
|
||||
Graphics g = getGraphics();
|
||||
if (g != null) {
|
||||
FontMetrics fm = g.getFontMetrics(font);
|
||||
if (fm != null) {
|
||||
textWidth = fm.stringWidth(title);
|
||||
}
|
||||
}
|
||||
return (leftIcon.getIconWidth() + gap + textWidth +
|
||||
gap + rightIcon.getIconWidth());
|
||||
}
|
||||
|
||||
|
||||
public int getIconHeight() {
|
||||
return leftIcon.getIconHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
1112
jdkSrc/jdk8/sun/tools/jconsole/JConsole.java
Normal file
1112
jdkSrc/jdk8/sun/tools/jconsole/JConsole.java
Normal file
File diff suppressed because it is too large
Load Diff
103
jdkSrc/jdk8/sun/tools/jconsole/LabeledComponent.java
Normal file
103
jdkSrc/jdk8/sun/tools/jconsole/LabeledComponent.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class LabeledComponent extends JPanel {
|
||||
JPanel rightPanel;
|
||||
String labelStr, valueLabelStr, compoundStr;
|
||||
JLabel label;
|
||||
JComponent comp;
|
||||
|
||||
public LabeledComponent(String text, JComponent comp) {
|
||||
this(text, 0, comp);
|
||||
}
|
||||
|
||||
public LabeledComponent(String text, int mnemonic, JComponent comp) {
|
||||
super(new BorderLayout(6, 6));
|
||||
|
||||
this.labelStr = text;
|
||||
this.label = new JLabel(text, JLabel.RIGHT);
|
||||
this.comp = comp;
|
||||
|
||||
label.setLabelFor(comp);
|
||||
if (mnemonic > 0) {
|
||||
label.setDisplayedMnemonic(mnemonic);
|
||||
}
|
||||
|
||||
add(label, BorderLayout.WEST);
|
||||
add(comp, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setLabel(String str) {
|
||||
this.labelStr = str;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
public void setValueLabel(String str) {
|
||||
this.valueLabelStr = str;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
private void updateLabel() {
|
||||
String str = labelStr;
|
||||
label.setText(str);
|
||||
this.compoundStr = str;
|
||||
JComponent container = (JComponent)getParent();
|
||||
LabeledComponent.layout(container);
|
||||
}
|
||||
|
||||
public static void layout(Container container) {
|
||||
int wMax = 0;
|
||||
|
||||
for (Component c : container.getComponents()) {
|
||||
if (c instanceof LabeledComponent) {
|
||||
LabeledComponent lc = (LabeledComponent)c;
|
||||
lc.label.setPreferredSize(null);
|
||||
// int w = lc.label.getMinimumSize().width;
|
||||
int w = lc.label.getPreferredSize().width;
|
||||
if (w > wMax) {
|
||||
wMax = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Component c : container.getComponents()) {
|
||||
if (c instanceof LabeledComponent) {
|
||||
LabeledComponent lc = (LabeledComponent)c;
|
||||
JLabel label = lc.label;
|
||||
int h = label.getPreferredSize().height;
|
||||
|
||||
label.setPreferredSize(new Dimension(wMax, h));
|
||||
label.setHorizontalAlignment(JLabel.RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
247
jdkSrc/jdk8/sun/tools/jconsole/LocalVirtualMachine.java
Normal file
247
jdkSrc/jdk8/sun/tools/jconsole/LocalVirtualMachine.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
// Sun specific
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
|
||||
// Sun private
|
||||
import sun.management.ConnectorAddressLink;
|
||||
import sun.jvmstat.monitor.HostIdentifier;
|
||||
import sun.jvmstat.monitor.MonitoredHost;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.MonitoredVmUtil;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
|
||||
public class LocalVirtualMachine {
|
||||
private String address;
|
||||
private String commandLine;
|
||||
private String displayName;
|
||||
private int vmid;
|
||||
private boolean isAttachSupported;
|
||||
|
||||
public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress) {
|
||||
this.vmid = vmid;
|
||||
this.commandLine = commandLine;
|
||||
this.address = connectorAddress;
|
||||
this.isAttachSupported = canAttach;
|
||||
this.displayName = getDisplayName(commandLine);
|
||||
}
|
||||
|
||||
private static String getDisplayName(String commandLine) {
|
||||
// trim the pathname of jar file if it's a jar
|
||||
String[] res = commandLine.split(" ", 2);
|
||||
if (res[0].endsWith(".jar")) {
|
||||
File jarfile = new File(res[0]);
|
||||
String displayName = jarfile.getName();
|
||||
if (res.length == 2) {
|
||||
displayName += " " + res[1];
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
public int vmid() {
|
||||
return vmid;
|
||||
}
|
||||
|
||||
public boolean isManageable() {
|
||||
return (address != null);
|
||||
}
|
||||
|
||||
public boolean isAttachable() {
|
||||
return isAttachSupported;
|
||||
}
|
||||
|
||||
public void startManagementAgent() throws IOException {
|
||||
if (address != null) {
|
||||
// already started
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAttachable()) {
|
||||
throw new IOException("This virtual machine \"" + vmid +
|
||||
"\" does not support dynamic attach.");
|
||||
}
|
||||
|
||||
loadManagementAgent();
|
||||
// fails to load or start the management agent
|
||||
if (address == null) {
|
||||
// should never reach here
|
||||
throw new IOException("Fails to find connector address");
|
||||
}
|
||||
}
|
||||
|
||||
public String connectorAddress() {
|
||||
// return null if not available or no JMX agent
|
||||
return address;
|
||||
}
|
||||
|
||||
public String displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
// This method returns the list of all virtual machines currently
|
||||
// running on the machine
|
||||
public static Map<Integer, LocalVirtualMachine> getAllVirtualMachines() {
|
||||
Map<Integer, LocalVirtualMachine> map =
|
||||
new HashMap<Integer, LocalVirtualMachine>();
|
||||
getMonitoredVMs(map);
|
||||
getAttachableVMs(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
|
||||
MonitoredHost host;
|
||||
Set<Integer> vms;
|
||||
try {
|
||||
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
|
||||
vms = host.activeVms();
|
||||
} catch (java.net.URISyntaxException | MonitorException x) {
|
||||
throw new InternalError(x.getMessage(), x);
|
||||
}
|
||||
for (Object vmid: vms) {
|
||||
if (vmid instanceof Integer) {
|
||||
int pid = ((Integer) vmid).intValue();
|
||||
String name = vmid.toString(); // default to pid if name not available
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
try {
|
||||
MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));
|
||||
// use the command line as the display name
|
||||
name = MonitoredVmUtil.commandLine(mvm);
|
||||
attachable = MonitoredVmUtil.isAttachable(mvm);
|
||||
address = ConnectorAddressLink.importFrom(pid);
|
||||
mvm.detach();
|
||||
} catch (Exception x) {
|
||||
// ignore
|
||||
}
|
||||
map.put((Integer) vmid,
|
||||
new LocalVirtualMachine(pid, name, attachable, address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
|
||||
"com.sun.management.jmxremote.localConnectorAddress";
|
||||
|
||||
private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {
|
||||
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
|
||||
for (VirtualMachineDescriptor vmd : vms) {
|
||||
try {
|
||||
Integer vmid = Integer.valueOf(vmd.id());
|
||||
if (!map.containsKey(vmid)) {
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(vmd);
|
||||
attachable = true;
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
vm.detach();
|
||||
} catch (AttachNotSupportedException x) {
|
||||
// not attachable
|
||||
} catch (IOException x) {
|
||||
// ignore
|
||||
}
|
||||
map.put(vmid, new LocalVirtualMachine(vmid.intValue(),
|
||||
vmd.displayName(),
|
||||
attachable,
|
||||
address));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// do not support vmid different than pid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalVirtualMachine getLocalVirtualMachine(int vmid) {
|
||||
Map<Integer, LocalVirtualMachine> map = getAllVirtualMachines();
|
||||
LocalVirtualMachine lvm = map.get(vmid);
|
||||
if (lvm == null) {
|
||||
// Check if the VM is attachable but not included in the list
|
||||
// if it's running with a different security context.
|
||||
// For example, Windows services running
|
||||
// local SYSTEM account are attachable if you have Adminstrator
|
||||
// privileges.
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
String name = String.valueOf(vmid); // default display name to pid
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(name);
|
||||
attachable = true;
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
vm.detach();
|
||||
lvm = new LocalVirtualMachine(vmid, name, attachable, address);
|
||||
} catch (AttachNotSupportedException x) {
|
||||
// not attachable
|
||||
if (JConsole.isDebug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
} catch (IOException x) {
|
||||
// ignore
|
||||
if (JConsole.isDebug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return lvm;
|
||||
}
|
||||
|
||||
// load the management agent into the target VM
|
||||
private void loadManagementAgent() throws IOException {
|
||||
VirtualMachine vm = null;
|
||||
String name = String.valueOf(vmid);
|
||||
try {
|
||||
vm = VirtualMachine.attach(name);
|
||||
} catch (AttachNotSupportedException x) {
|
||||
IOException ioe = new IOException(x.getMessage());
|
||||
ioe.initCause(x);
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
vm.startLocalManagementAgent();
|
||||
|
||||
// get the connector address
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
|
||||
vm.detach();
|
||||
}
|
||||
}
|
||||
281
jdkSrc/jdk8/sun/tools/jconsole/MBeansTab.java
Normal file
281
jdkSrc/jdk8/sun/tools/jconsole/MBeansTab.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.beans.*;
|
||||
import java.io.*;
|
||||
import java.util.Set;
|
||||
import javax.management.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.tree.*;
|
||||
import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection;
|
||||
import sun.tools.jconsole.inspector.*;
|
||||
|
||||
import com.sun.tools.jconsole.JConsoleContext;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MBeansTab extends Tab implements
|
||||
NotificationListener, PropertyChangeListener,
|
||||
TreeSelectionListener, TreeWillExpandListener {
|
||||
|
||||
private XTree tree;
|
||||
private XSheet sheet;
|
||||
private XDataViewer viewer;
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.MBEANS;
|
||||
}
|
||||
|
||||
public MBeansTab(final VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
addPropertyChangeListener(this);
|
||||
setupTab();
|
||||
}
|
||||
|
||||
public XDataViewer getDataViewer() {
|
||||
return viewer;
|
||||
}
|
||||
|
||||
public XTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public XSheet getSheet() {
|
||||
return sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
sheet.dispose();
|
||||
}
|
||||
|
||||
public int getUpdateInterval() {
|
||||
return vmPanel.getUpdateInterval();
|
||||
}
|
||||
|
||||
private void buildMBeanServerView() {
|
||||
new SwingWorker<Set<ObjectName>, Void>() {
|
||||
@Override
|
||||
public Set<ObjectName> doInBackground() {
|
||||
// Register listener for MBean registration/unregistration
|
||||
//
|
||||
try {
|
||||
getMBeanServerConnection().addNotificationListener(
|
||||
MBeanServerDelegate.DELEGATE_NAME,
|
||||
MBeansTab.this,
|
||||
null,
|
||||
null);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
// Should never happen because the MBeanServerDelegate
|
||||
// is always present in any standard MBeanServer
|
||||
//
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
return null;
|
||||
}
|
||||
// Retrieve MBeans from MBeanServer
|
||||
//
|
||||
Set<ObjectName> mbeans = null;
|
||||
try {
|
||||
mbeans = getMBeanServerConnection().queryNames(null, null);
|
||||
} catch (IOException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
return null;
|
||||
}
|
||||
return mbeans;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
// Wait for mbsc.queryNames() result
|
||||
Set<ObjectName> mbeans = get();
|
||||
// Do not display anything until the new tree has been built
|
||||
//
|
||||
tree.setVisible(false);
|
||||
// Cleanup current tree
|
||||
//
|
||||
tree.removeAll();
|
||||
// Add MBeans to tree
|
||||
//
|
||||
tree.addMBeansToView(mbeans);
|
||||
// Display the new tree
|
||||
//
|
||||
tree.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem at MBean tree construction");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
public MBeanServerConnection getMBeanServerConnection() {
|
||||
return vmPanel.getProxyClient().getMBeanServerConnection();
|
||||
}
|
||||
|
||||
public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() {
|
||||
return vmPanel.getProxyClient().getSnapshotMBeanServerConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// Ping the connection to see if it is still alive. At
|
||||
// some point the ProxyClient class should centralize
|
||||
// the connection aliveness monitoring and no longer
|
||||
// rely on the custom tabs to ping the connections.
|
||||
//
|
||||
try {
|
||||
getMBeanServerConnection().getDefaultDomain();
|
||||
} catch (IOException ex) {
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTab() {
|
||||
// set up the split pane with the MBean tree and MBean sheet panels
|
||||
setLayout(new BorderLayout());
|
||||
JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
mainSplit.setDividerLocation(160);
|
||||
mainSplit.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
// set up the MBean tree panel (left pane)
|
||||
tree = new XTree(this);
|
||||
tree.setCellRenderer(new XTreeRenderer());
|
||||
tree.getSelectionModel().setSelectionMode(
|
||||
TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
tree.addTreeSelectionListener(this);
|
||||
tree.addTreeWillExpandListener(this);
|
||||
tree.addMouseListener(ml);
|
||||
JScrollPane theScrollPane = new JScrollPane(
|
||||
tree,
|
||||
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
JPanel treePanel = new JPanel(new BorderLayout());
|
||||
treePanel.add(theScrollPane, BorderLayout.CENTER);
|
||||
mainSplit.add(treePanel, JSplitPane.LEFT, 0);
|
||||
|
||||
// set up the MBean sheet panel (right pane)
|
||||
viewer = new XDataViewer(this);
|
||||
sheet = new XSheet(this);
|
||||
mainSplit.add(sheet, JSplitPane.RIGHT, 0);
|
||||
|
||||
add(mainSplit);
|
||||
}
|
||||
|
||||
/* notification listener: handleNotification */
|
||||
public void handleNotification(
|
||||
final Notification notification, Object handback) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (notification instanceof MBeanServerNotification) {
|
||||
ObjectName mbean =
|
||||
((MBeanServerNotification) notification).getMBeanName();
|
||||
if (notification.getType().equals(
|
||||
MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
|
||||
tree.addMBeanToView(mbean);
|
||||
} else if (notification.getType().equals(
|
||||
MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
|
||||
tree.removeMBeanFromView(mbean);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* property change listener: propertyChange */
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
|
||||
boolean connected = (Boolean) evt.getNewValue();
|
||||
if (connected) {
|
||||
buildMBeanServerView();
|
||||
} else {
|
||||
sheet.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tree selection listener: valueChanged */
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
|
||||
sheet.displayNode(node);
|
||||
}
|
||||
/* tree mouse listener: mousePressed */
|
||||
private MouseListener ml = new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getClickCount() == 1) {
|
||||
int selRow = tree.getRowForLocation(e.getX(), e.getY());
|
||||
if (selRow != -1) {
|
||||
TreePath selPath =
|
||||
tree.getPathForLocation(e.getX(), e.getY());
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) selPath.getLastPathComponent();
|
||||
if (sheet.isMBeanNode(node)) {
|
||||
tree.expandPath(selPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* tree will expand listener: treeWillExpand */
|
||||
public void treeWillExpand(TreeExpansionEvent e)
|
||||
throws ExpandVetoException {
|
||||
TreePath path = e.getPath();
|
||||
if (!tree.hasBeenExpanded(path)) {
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) path.getLastPathComponent();
|
||||
if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) {
|
||||
tree.addMetadataNodes(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tree will expand listener: treeWillCollapse */
|
||||
public void treeWillCollapse(TreeExpansionEvent e)
|
||||
throws ExpandVetoException {
|
||||
}
|
||||
}
|
||||
345
jdkSrc/jdk8/sun/tools/jconsole/MaximizableInternalFrame.java
Normal file
345
jdkSrc/jdk8/sun/tools/jconsole/MaximizableInternalFrame.java
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a temporary workaround for bug 4834918:
|
||||
* Win L&F: JInternalFrame should merge with JMenuBar when maximized.
|
||||
* It is not a general solution, but intended for use within the
|
||||
* limited scope of JConsole when running with XP/Vista styles.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class MaximizableInternalFrame extends JInternalFrame {
|
||||
private boolean isXP;
|
||||
private JFrame mainFrame;
|
||||
private JMenuBar mainMenuBar;
|
||||
private String mainTitle;
|
||||
private JComponent titlePane;
|
||||
private Border normalBorder;
|
||||
private PropertyChangeListener pcl;
|
||||
|
||||
public MaximizableInternalFrame(String title, boolean resizable,
|
||||
boolean closable, boolean maximizable,
|
||||
boolean iconifiable) {
|
||||
super(title, resizable, closable, maximizable, iconifiable);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
normalBorder = getBorder();
|
||||
isXP = normalBorder.getClass().getName().endsWith("XPBorder");
|
||||
if (isXP) {
|
||||
setRootPaneCheckingEnabled(false);
|
||||
titlePane = ((BasicInternalFrameUI)getUI()).getNorthPane();
|
||||
|
||||
if (pcl == null) {
|
||||
pcl = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent ev) {
|
||||
String prop = ev.getPropertyName();
|
||||
if (prop.equals("icon") ||
|
||||
prop.equals("maximum") ||
|
||||
prop.equals("closed")) {
|
||||
|
||||
updateFrame();
|
||||
}
|
||||
}
|
||||
};
|
||||
addPropertyChangeListener(pcl);
|
||||
}
|
||||
} else if (pcl != null) {
|
||||
removePropertyChangeListener(pcl);
|
||||
pcl = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrame() {
|
||||
JFrame mainFrame;
|
||||
if (!isXP || (mainFrame = getMainFrame()) == null) {
|
||||
return;
|
||||
}
|
||||
JMenuBar menuBar = getMainMenuBar();
|
||||
BasicInternalFrameUI ui = (BasicInternalFrameUI)getUI();
|
||||
if (isMaximum() && !isIcon() && !isClosed()) {
|
||||
if (ui.getNorthPane() != null) {
|
||||
// Merge title bar into menu bar
|
||||
mainTitle = mainFrame.getTitle();
|
||||
mainFrame.setTitle(mainTitle + " - " + getTitle());
|
||||
if (menuBar != null) {
|
||||
// Move buttons to menu bar
|
||||
updateButtonStates();
|
||||
menuBar.add(Box.createGlue());
|
||||
for (Component c : titlePane.getComponents()) {
|
||||
if (c instanceof JButton) {
|
||||
menuBar.add(c);
|
||||
} else if (c instanceof JLabel) {
|
||||
// This is the system menu icon
|
||||
menuBar.add(Box.createHorizontalStrut(3), 0);
|
||||
menuBar.add(c, 1);
|
||||
menuBar.add(Box.createHorizontalStrut(3), 2);
|
||||
}
|
||||
}
|
||||
ui.setNorthPane(null);
|
||||
setBorder(null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ui.getNorthPane() == null) {
|
||||
// Restore title bar
|
||||
mainFrame.setTitle(mainTitle);
|
||||
if (menuBar != null) {
|
||||
// Move buttons back to title bar
|
||||
for (Component c : menuBar.getComponents()) {
|
||||
if (c instanceof JButton || c instanceof JLabel) {
|
||||
titlePane.add(c);
|
||||
} else if (c instanceof Box.Filler) {
|
||||
menuBar.remove(c);
|
||||
}
|
||||
}
|
||||
menuBar.repaint();
|
||||
updateButtonStates();
|
||||
ui.setNorthPane(titlePane);
|
||||
setBorder(normalBorder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUI() {
|
||||
boolean isMax = (isXP && getBorder() == null);
|
||||
if (isMax) {
|
||||
try {
|
||||
setMaximum(false);
|
||||
} catch (PropertyVetoException ex) { }
|
||||
}
|
||||
super.updateUI();
|
||||
init();
|
||||
if (isMax) {
|
||||
try {
|
||||
setMaximum(true);
|
||||
} catch (PropertyVetoException ex) { }
|
||||
}
|
||||
}
|
||||
|
||||
private JFrame getMainFrame() {
|
||||
if (mainFrame == null) {
|
||||
JDesktopPane desktop = getDesktopPane();
|
||||
if (desktop != null) {
|
||||
mainFrame = (JFrame)SwingUtilities.getWindowAncestor(desktop);
|
||||
}
|
||||
}
|
||||
return mainFrame;
|
||||
}
|
||||
|
||||
private JMenuBar getMainMenuBar() {
|
||||
if (mainMenuBar == null) {
|
||||
JFrame mainFrame = getMainFrame();
|
||||
if (mainFrame != null) {
|
||||
mainMenuBar = mainFrame.getJMenuBar();
|
||||
if (mainMenuBar != null &&
|
||||
!(mainMenuBar.getLayout() instanceof FixedMenuBarLayout)) {
|
||||
|
||||
mainMenuBar.setLayout(new FixedMenuBarLayout(mainMenuBar,
|
||||
BoxLayout.X_AXIS));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mainMenuBar;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
if (isXP && isMaximum()) {
|
||||
if (getMainFrame() != null) {
|
||||
getMainFrame().setTitle(mainTitle + " - " + title);
|
||||
}
|
||||
}
|
||||
super.setTitle(title);
|
||||
}
|
||||
|
||||
|
||||
private class FixedMenuBarLayout extends BoxLayout {
|
||||
public FixedMenuBarLayout(Container target, int axis) {
|
||||
super(target, axis);
|
||||
}
|
||||
|
||||
public void layoutContainer(Container target) {
|
||||
super.layoutContainer(target);
|
||||
|
||||
for (Component c : target.getComponents()) {
|
||||
if (c instanceof JButton) {
|
||||
int y = (target.getHeight() - c.getHeight()) / 2;
|
||||
c.setLocation(c.getX(), Math.max(2, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The rest of this class is messy and should not be relied upon. It
|
||||
// uses reflection to access private, undocumented, and unsupported
|
||||
// classes and fields.
|
||||
//
|
||||
// Install icon wrappers to display MDI icons when the buttons
|
||||
// are in the menubar.
|
||||
//
|
||||
// Please note that this will very likely fail in a future version
|
||||
// of Swing, but at least it should fail silently.
|
||||
//
|
||||
private static Object WP_MINBUTTON, WP_RESTOREBUTTON, WP_CLOSEBUTTON,
|
||||
WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON, WP_MDICLOSEBUTTON;
|
||||
static {
|
||||
if (JConsole.IS_WIN) {
|
||||
try {
|
||||
Class<?> Part =
|
||||
Class.forName("com.sun.java.swing.plaf.windows.TMSchema$Part");
|
||||
if (Part != null) {
|
||||
WP_MINBUTTON = Part.getField("WP_MINBUTTON").get(null);
|
||||
WP_RESTOREBUTTON = Part.getField("WP_RESTOREBUTTON").get(null);
|
||||
WP_CLOSEBUTTON = Part.getField("WP_CLOSEBUTTON").get(null);
|
||||
WP_MDIMINBUTTON = Part.getField("WP_MDIMINBUTTON").get(null);
|
||||
WP_MDIRESTOREBUTTON = Part.getField("WP_MDIRESTOREBUTTON").get(null);
|
||||
WP_MDICLOSEBUTTON = Part.getField("WP_MDICLOSEBUTTON").get(null);
|
||||
}
|
||||
|
||||
for (String str : new String[] { "maximize", "minimize",
|
||||
"iconify", "close" }) {
|
||||
String key = "InternalFrame." + str + "Icon";
|
||||
UIManager.put(key,
|
||||
new MDIButtonIcon(UIManager.getIcon(key)));
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (NoSuchFieldException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A wrapper class for the title pane button icons.
|
||||
// This code should really go in the WindowsIconsFactory class.
|
||||
private static class MDIButtonIcon implements Icon {
|
||||
Icon windowsIcon;
|
||||
Field part;
|
||||
|
||||
MDIButtonIcon(Icon icon) {
|
||||
windowsIcon = icon;
|
||||
|
||||
if (WP_MINBUTTON != null) {
|
||||
try {
|
||||
part = windowsIcon.getClass().getDeclaredField("part");
|
||||
part.setAccessible(true);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if (part != null) {
|
||||
try {
|
||||
Object v = part.get(windowsIcon);
|
||||
|
||||
if (c.getParent() instanceof JMenuBar) {
|
||||
// Use MDI icons
|
||||
if (v == WP_MINBUTTON) {
|
||||
part.set(windowsIcon, WP_MDIMINBUTTON);
|
||||
} else if (v == WP_RESTOREBUTTON) {
|
||||
part.set(windowsIcon, WP_MDIRESTOREBUTTON);
|
||||
} else if (v == WP_CLOSEBUTTON) {
|
||||
part.set(windowsIcon, WP_MDICLOSEBUTTON);
|
||||
}
|
||||
} else {
|
||||
// Use regular icons
|
||||
if (v == WP_MDIMINBUTTON) {
|
||||
part.set(windowsIcon, WP_MINBUTTON);
|
||||
} else if (v == WP_MDIRESTOREBUTTON) {
|
||||
part.set(windowsIcon, WP_RESTOREBUTTON);
|
||||
} else if (v == WP_MDICLOSEBUTTON) {
|
||||
part.set(windowsIcon, WP_CLOSEBUTTON);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
windowsIcon.paintIcon(c, g, x, y);
|
||||
}
|
||||
|
||||
public int getIconWidth(){
|
||||
return windowsIcon.getIconWidth();
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return windowsIcon.getIconHeight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use reflection to invoke protected methods in BasicInternalFrameTitlePane
|
||||
private Method setButtonIcons;
|
||||
private Method enableActions;
|
||||
|
||||
private void updateButtonStates() {
|
||||
try {
|
||||
if (setButtonIcons == null) {
|
||||
Class<? extends JComponent> cls = titlePane.getClass();
|
||||
Class<?> superCls = cls.getSuperclass();
|
||||
setButtonIcons = cls.getDeclaredMethod("setButtonIcons");
|
||||
enableActions = superCls.getDeclaredMethod("enableActions");
|
||||
setButtonIcons.setAccessible(true);
|
||||
enableActions.setAccessible(true);
|
||||
}
|
||||
setButtonIcons.invoke(titlePane);
|
||||
enableActions.invoke(titlePane);
|
||||
} catch (Exception ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolProxy.java
Normal file
125
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolProxy.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import com.sun.management.GarbageCollectorMXBean;
|
||||
import com.sun.management.GcInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.management.ManagementFactory.*;
|
||||
|
||||
public class MemoryPoolProxy {
|
||||
private String poolName;
|
||||
private ProxyClient client;
|
||||
private MemoryPoolMXBean pool;
|
||||
private Map<ObjectName,Long> gcMBeans;
|
||||
private GcInfo lastGcInfo;
|
||||
|
||||
public MemoryPoolProxy(ProxyClient client, ObjectName poolName) throws java.io.IOException {
|
||||
this.client = client;
|
||||
this.pool = client.getMXBean(poolName, MemoryPoolMXBean.class);
|
||||
this.poolName = this.pool.getName();
|
||||
this.gcMBeans = new HashMap<ObjectName,Long>();
|
||||
this.lastGcInfo = null;
|
||||
|
||||
String[] mgrNames = pool.getMemoryManagerNames();
|
||||
for (String name : mgrNames) {
|
||||
try {
|
||||
ObjectName mbeanName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
|
||||
",name=" + name);
|
||||
if (client.isRegistered(mbeanName)) {
|
||||
gcMBeans.put(mbeanName, new Long(0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
assert false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCollectedMemoryPool() {
|
||||
return (gcMBeans.size() != 0);
|
||||
}
|
||||
|
||||
public MemoryPoolStat getStat() throws java.io.IOException {
|
||||
long usageThreshold = (pool.isUsageThresholdSupported()
|
||||
? pool.getUsageThreshold()
|
||||
: -1);
|
||||
long collectThreshold = (pool.isCollectionUsageThresholdSupported()
|
||||
? pool.getCollectionUsageThreshold()
|
||||
: -1);
|
||||
long lastGcStartTime = 0;
|
||||
long lastGcEndTime = 0;
|
||||
MemoryUsage beforeGcUsage = null;
|
||||
MemoryUsage afterGcUsage = null;
|
||||
long gcId = 0;
|
||||
if (lastGcInfo != null) {
|
||||
gcId = lastGcInfo.getId();
|
||||
lastGcStartTime = lastGcInfo.getStartTime();
|
||||
lastGcEndTime = lastGcInfo.getEndTime();
|
||||
beforeGcUsage = lastGcInfo.getMemoryUsageBeforeGc().get(poolName);
|
||||
afterGcUsage = lastGcInfo.getMemoryUsageAfterGc().get(poolName);
|
||||
}
|
||||
|
||||
Set<Map.Entry<ObjectName,Long>> set = gcMBeans.entrySet();
|
||||
for (Map.Entry<ObjectName,Long> e : set) {
|
||||
GarbageCollectorMXBean gc =
|
||||
client.getMXBean(e.getKey(),
|
||||
com.sun.management.GarbageCollectorMXBean.class);
|
||||
Long gcCount = e.getValue();
|
||||
Long newCount = gc.getCollectionCount();
|
||||
if (newCount > gcCount) {
|
||||
gcMBeans.put(e.getKey(), new Long(newCount));
|
||||
lastGcInfo = gc.getLastGcInfo();
|
||||
if (lastGcInfo.getEndTime() > lastGcEndTime) {
|
||||
gcId = lastGcInfo.getId();
|
||||
lastGcStartTime = lastGcInfo.getStartTime();
|
||||
lastGcEndTime = lastGcInfo.getEndTime();
|
||||
beforeGcUsage = lastGcInfo.getMemoryUsageBeforeGc().get(poolName);
|
||||
afterGcUsage = lastGcInfo.getMemoryUsageAfterGc().get(poolName);
|
||||
assert(beforeGcUsage != null);
|
||||
assert(afterGcUsage != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemoryUsage usage = pool.getUsage();
|
||||
return new MemoryPoolStat(poolName,
|
||||
usageThreshold,
|
||||
usage,
|
||||
gcId,
|
||||
lastGcStartTime,
|
||||
lastGcEndTime,
|
||||
collectThreshold,
|
||||
beforeGcUsage,
|
||||
afterGcUsage);
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolStat.java
Normal file
134
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolStat.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.lang.management.MemoryUsage;
|
||||
|
||||
public class MemoryPoolStat {
|
||||
private String poolName;
|
||||
private long usageThreshold;
|
||||
private MemoryUsage usage;
|
||||
private long lastGcId;
|
||||
private long lastGcStartTime;
|
||||
private long lastGcEndTime;
|
||||
private long collectThreshold;
|
||||
private MemoryUsage beforeGcUsage;
|
||||
private MemoryUsage afterGcUsage;
|
||||
|
||||
MemoryPoolStat(String name,
|
||||
long usageThreshold,
|
||||
MemoryUsage usage,
|
||||
long lastGcId,
|
||||
long lastGcStartTime,
|
||||
long lastGcEndTime,
|
||||
long collectThreshold,
|
||||
MemoryUsage beforeGcUsage,
|
||||
MemoryUsage afterGcUsage) {
|
||||
this.poolName = name;
|
||||
this.usageThreshold = usageThreshold;
|
||||
this.usage = usage;
|
||||
this.lastGcId = lastGcId;
|
||||
this.lastGcStartTime = lastGcStartTime;
|
||||
this.lastGcEndTime = lastGcEndTime;
|
||||
this.collectThreshold = collectThreshold;
|
||||
this.beforeGcUsage = beforeGcUsage;
|
||||
this.afterGcUsage = afterGcUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory pool name.
|
||||
*/
|
||||
public String getPoolName() {
|
||||
return poolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current memory usage.
|
||||
*/
|
||||
public MemoryUsage getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current usage threshold.
|
||||
* -1 if not supported.
|
||||
*/
|
||||
public long getUsageThreshold() {
|
||||
return usageThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current collection usage threshold.
|
||||
* -1 if not supported.
|
||||
*/
|
||||
public long getCollectionUsageThreshold() {
|
||||
return collectThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Id of GC.
|
||||
*/
|
||||
public long getLastGcId() {
|
||||
return lastGcId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the start time of the most recent GC on
|
||||
* the memory pool for this statistics in milliseconds.
|
||||
*
|
||||
* Return 0 if no GC occurs.
|
||||
*/
|
||||
public long getLastGcStartTime() {
|
||||
return lastGcStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end time of the most recent GC on
|
||||
* the memory pool for this statistics in milliseconds.
|
||||
*
|
||||
* Return 0 if no GC occurs.
|
||||
*/
|
||||
public long getLastGcEndTime() {
|
||||
return lastGcEndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory usage before the most recent GC started.
|
||||
* null if no GC occurs.
|
||||
*/
|
||||
public MemoryUsage getBeforeGcUsage() {
|
||||
return beforeGcUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory usage after the most recent GC finished.
|
||||
* null if no GC occurs.
|
||||
*/
|
||||
public MemoryUsage getAfterGcUsage() {
|
||||
return afterGcUsage;
|
||||
}
|
||||
}
|
||||
768
jdkSrc/jdk8/sun/tools/jconsole/MemoryTab.java
Normal file
768
jdkSrc/jdk8/sun/tools/jconsole/MemoryTab.java
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
import javax.management.*;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Formatter.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class MemoryTab extends Tab implements ActionListener, ItemListener {
|
||||
JComboBox<Plotter> plotterChoice;
|
||||
TimeComboBox timeComboBox;
|
||||
JButton gcButton;
|
||||
|
||||
PlotterPanel plotterPanel;
|
||||
JPanel bottomPanel;
|
||||
HTMLPane details;
|
||||
PoolChart poolChart;
|
||||
|
||||
ArrayList<Plotter> plotterList;
|
||||
Plotter heapPlotter, nonHeapPlotter;
|
||||
|
||||
private MemoryOverviewPanel overviewPanel;
|
||||
|
||||
private static final String usedKey = "used";
|
||||
private static final String committedKey = "committed";
|
||||
private static final String maxKey = "max";
|
||||
private static final String thresholdKey = "threshold";
|
||||
private static final Color usedColor = Plotter.defaultColor;
|
||||
private static final Color committedColor = null;
|
||||
private static final Color maxColor = null;
|
||||
private static final Color thresholdColor = Color.red;
|
||||
|
||||
/*
|
||||
Hierarchy of panels and layouts for this tab:
|
||||
|
||||
MemoryTab (BorderLayout)
|
||||
|
||||
North: topPanel (BorderLayout)
|
||||
|
||||
Center: controlPanel (FlowLayout)
|
||||
plotterChoice, timeComboBox
|
||||
|
||||
East: topRightPanel (FlowLayout)
|
||||
gcButton
|
||||
|
||||
Center: plotterPanel
|
||||
|
||||
Center: plotter
|
||||
|
||||
South: bottomPanel (BorderLayout)
|
||||
|
||||
Center: details
|
||||
East: poolChart
|
||||
*/
|
||||
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.MEMORY;
|
||||
}
|
||||
|
||||
public MemoryTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
plotterPanel = new PlotterPanel(null);
|
||||
bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
add(plotterPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
// Plotter choice
|
||||
plotterChoice = new JComboBox<Plotter>();
|
||||
plotterChoice.addItemListener(this);
|
||||
controlPanel.add(new LabeledComponent(Messages.CHART_COLON,
|
||||
Resources.getMnemonicInt(Messages.CHART_COLON),
|
||||
plotterChoice));
|
||||
|
||||
// Range control
|
||||
timeComboBox = new TimeComboBox();
|
||||
controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox));
|
||||
|
||||
gcButton = new JButton(Messages.PERFORM_GC);
|
||||
gcButton.setMnemonic(Resources.getMnemonicInt(Messages.PERFORM_GC));
|
||||
gcButton.addActionListener(this);
|
||||
gcButton.setToolTipText(Messages.PERFORM_GC_TOOLTIP);
|
||||
JPanel topRightPanel = new JPanel();
|
||||
topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
|
||||
topRightPanel.add(gcButton);
|
||||
topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
|
||||
|
||||
bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
|
||||
new EmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
details = new HTMLPane();
|
||||
setAccessibleName(details, Messages.DETAILS);
|
||||
bottomPanel.add(new JScrollPane(details), BorderLayout.CENTER);
|
||||
|
||||
poolChart = new PoolChart();
|
||||
bottomPanel.add(poolChart, BorderLayout.AFTER_LINE_ENDS);
|
||||
}
|
||||
|
||||
|
||||
private void createPlotters() throws IOException {
|
||||
plotterList = new ArrayList<Plotter>();
|
||||
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
heapPlotter = new Plotter(Plotter.Unit.BYTES) {
|
||||
public String toString() {
|
||||
return Messages.HEAP_MEMORY_USAGE;
|
||||
}
|
||||
};
|
||||
proxyClient.addWeakPropertyChangeListener(heapPlotter);
|
||||
|
||||
nonHeapPlotter = new Plotter(Plotter.Unit.BYTES) {
|
||||
public String toString() {
|
||||
return Messages.NON_HEAP_MEMORY_USAGE;
|
||||
}
|
||||
};
|
||||
|
||||
setAccessibleName(heapPlotter,
|
||||
Messages.MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME);
|
||||
setAccessibleName(nonHeapPlotter,
|
||||
Messages.MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME);
|
||||
|
||||
proxyClient.addWeakPropertyChangeListener(nonHeapPlotter);
|
||||
|
||||
heapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
heapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
heapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
|
||||
nonHeapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
nonHeapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
nonHeapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
|
||||
plotterList.add(heapPlotter);
|
||||
plotterList.add(nonHeapPlotter);
|
||||
|
||||
// Now add memory pools
|
||||
Map<ObjectName, MBeanInfo> mBeanMap = proxyClient.getMBeans("java.lang");
|
||||
Set<ObjectName> keys = mBeanMap.keySet();
|
||||
ObjectName[] objectNames = keys.toArray(new ObjectName[keys.size()]);
|
||||
ArrayList<PoolPlotter> nonHeapPlotters = new ArrayList<PoolPlotter>(2);
|
||||
for (ObjectName objectName : objectNames) {
|
||||
String type = objectName.getKeyProperty("type");
|
||||
if (type.equals("MemoryPool")) {
|
||||
String name = Resources.format(Messages.MEMORY_POOL_LABEL,
|
||||
objectName.getKeyProperty("name"));
|
||||
// Heap or non-heap?
|
||||
boolean isHeap = false;
|
||||
AttributeList al =
|
||||
proxyClient.getAttributes(objectName,
|
||||
new String[] { "Type" });
|
||||
if (al.size() > 0) {
|
||||
isHeap = MemoryType.HEAP.name().equals(((Attribute)al.get(0)).getValue());
|
||||
}
|
||||
PoolPlotter poolPlotter = new PoolPlotter(objectName, name, isHeap);
|
||||
proxyClient.addWeakPropertyChangeListener(poolPlotter);
|
||||
|
||||
poolPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
poolPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
poolPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
poolPlotter.createSequence(thresholdKey, Messages.THRESHOLD, thresholdColor, false);
|
||||
poolPlotter.setUseDashedTransitions(thresholdKey, true);
|
||||
|
||||
if (isHeap) {
|
||||
plotterList.add(poolPlotter);
|
||||
} else {
|
||||
// Will be added to plotterList below
|
||||
nonHeapPlotters.add(poolPlotter);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add non-heap plotters last
|
||||
for (PoolPlotter poolPlotter : nonHeapPlotters) {
|
||||
plotterList.add(poolPlotter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void itemStateChanged(ItemEvent ev) {
|
||||
if (ev.getStateChange() == ItemEvent.SELECTED) {
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
plotterPanel.setPlotter(plotter);
|
||||
plotterPanel.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void gc() {
|
||||
new Thread("MemoryPanel.gc") {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
try {
|
||||
proxyClient.getMemoryMXBean().gc();
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
return new SwingWorker<Boolean, Object>() {
|
||||
private long[] used, committed, max, threshold;
|
||||
private long timeStamp;
|
||||
private String detailsStr;
|
||||
private boolean initialRun = false;
|
||||
|
||||
public Boolean doInBackground() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
if (plotterList == null) {
|
||||
try {
|
||||
createPlotters();
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (final IOException ex) {
|
||||
return false;
|
||||
}
|
||||
initialRun = true;
|
||||
}
|
||||
|
||||
int n = plotterList.size();
|
||||
used = new long[n];
|
||||
committed = new long[n];
|
||||
max = new long[n];
|
||||
threshold = new long[n];
|
||||
timeStamp = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Plotter plotter = plotterList.get(i);
|
||||
MemoryUsage mu = null;
|
||||
used[i] = -1L;
|
||||
threshold[i] = -1L;
|
||||
|
||||
try {
|
||||
if (plotter instanceof PoolPlotter) {
|
||||
PoolPlotter poolPlotter = (PoolPlotter)plotter;
|
||||
ObjectName objectName = poolPlotter.objectName;
|
||||
AttributeList al =
|
||||
proxyClient.getAttributes(objectName,
|
||||
new String[] { "Usage", "UsageThreshold" });
|
||||
if (al.size() > 0) {
|
||||
CompositeData cd = (CompositeData)((Attribute)al.get(0)).getValue();
|
||||
mu = MemoryUsage.from(cd);
|
||||
|
||||
if (al.size() > 1) {
|
||||
threshold[i] = (Long)((Attribute)al.get(1)).getValue();
|
||||
}
|
||||
}
|
||||
} else if (plotter == heapPlotter) {
|
||||
mu = proxyClient.getMemoryMXBean().getHeapMemoryUsage();
|
||||
} else if (plotter == nonHeapPlotter) {
|
||||
mu = proxyClient.getMemoryMXBean().getNonHeapMemoryUsage();
|
||||
}
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
// Skip this plotter
|
||||
}
|
||||
|
||||
if (mu != null) {
|
||||
used[i] = mu.getUsed();
|
||||
committed[i] = mu.getCommitted();
|
||||
max[i] = mu.getMax();
|
||||
}
|
||||
}
|
||||
detailsStr = formatDetails();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
if (!get()) {
|
||||
return;
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
return;
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialRun) {
|
||||
// Add Memory Pools
|
||||
for (Plotter p : plotterList) {
|
||||
plotterChoice.addItem(p);
|
||||
timeComboBox.addPlotter(p);
|
||||
}
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
|
||||
int n = plotterList.size();
|
||||
int poolCount = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Plotter plotter = plotterList.get(i);
|
||||
if (used[i] >= 0L) {
|
||||
if (plotter instanceof PoolPlotter) {
|
||||
plotter.addValues(timeStamp, used[i], committed[i], max[i], threshold[i]);
|
||||
if (threshold[i] > 0L) {
|
||||
plotter.setIsPlotted(thresholdKey, true);
|
||||
}
|
||||
poolChart.setValue(poolCount++, (PoolPlotter)plotter,
|
||||
used[i], threshold[i], max[i]);
|
||||
} else {
|
||||
plotter.addValues(timeStamp, used[i], committed[i], max[i]);
|
||||
}
|
||||
|
||||
if (plotter == heapPlotter && overviewPanel != null) {
|
||||
overviewPanel.getPlotter().addValues(timeStamp, used[i]);
|
||||
overviewPanel.updateMemoryInfo(used[i], committed[i], max[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
details.setText(detailsStr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String formatDetails() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
if (proxyClient.isDead()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String text = "<table cellspacing=0 cellpadding=0>";
|
||||
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
if (plotter == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
//long time = plotter.getLastTimeStamp();
|
||||
long time = System.currentTimeMillis();
|
||||
String timeStamp = formatDateTime(time);
|
||||
text += newRow(Messages.TIME, timeStamp);
|
||||
|
||||
long used = plotter.getLastValue(usedKey);
|
||||
long committed = plotter.getLastValue(committedKey);
|
||||
long max = plotter.getLastValue(maxKey);
|
||||
long threshold = plotter.getLastValue(thresholdKey);
|
||||
|
||||
text += newRow(Messages.USED, formatKBytes(used));
|
||||
if (committed > 0L) {
|
||||
text += newRow(Messages.COMMITTED, formatKBytes(committed));
|
||||
}
|
||||
if (max > 0L) {
|
||||
text += newRow(Messages.MAX, formatKBytes(max));
|
||||
}
|
||||
if (threshold > 0L) {
|
||||
text += newRow(Messages.USAGE_THRESHOLD, formatKBytes(threshold));
|
||||
}
|
||||
|
||||
try {
|
||||
Collection<GarbageCollectorMXBean> garbageCollectors =
|
||||
proxyClient.getGarbageCollectorMXBeans();
|
||||
|
||||
boolean descPrinted = false;
|
||||
for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
|
||||
String gcName = garbageCollectorMBean.getName();
|
||||
long gcCount = garbageCollectorMBean.getCollectionCount();
|
||||
long gcTime = garbageCollectorMBean.getCollectionTime();
|
||||
String str = Resources.format(Messages.GC_TIME_DETAILS, justify(formatTime(gcTime), 14),
|
||||
gcName,
|
||||
String.format("%,d",gcCount));
|
||||
if (!descPrinted) {
|
||||
text += newRow(Messages.GC_TIME, str);
|
||||
descPrinted = true;
|
||||
} else {
|
||||
text += newRow(null, str);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
Object src = ev.getSource();
|
||||
if (src == gcButton) {
|
||||
gc();
|
||||
}
|
||||
}
|
||||
|
||||
private class PoolPlotter extends Plotter {
|
||||
ObjectName objectName;
|
||||
String name;
|
||||
boolean isHeap;
|
||||
long value, threshold, max;
|
||||
int barX;
|
||||
|
||||
public PoolPlotter(ObjectName objectName, String name, boolean isHeap) {
|
||||
super(Plotter.Unit.BYTES);
|
||||
|
||||
this.objectName = objectName;
|
||||
this.name = name;
|
||||
this.isHeap = isHeap;
|
||||
|
||||
setAccessibleName(this,
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME,
|
||||
name));
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private class PoolChart extends BorderedComponent
|
||||
implements Accessible, MouseListener {
|
||||
final int height = 150;
|
||||
final int leftMargin = 50;
|
||||
final int rightMargin = 23;
|
||||
final int bottomMargin = 35;
|
||||
final int barWidth = 22;
|
||||
final int barGap = 3;
|
||||
final int groupGap = 8;
|
||||
final int barHeight = height * 2 / 3;
|
||||
|
||||
final Color greenBar = new Color(100, 255, 100);
|
||||
final Color greenBarBackground = new Color(210, 255, 210);
|
||||
final Color redBarBackground = new Color(255, 210, 210);
|
||||
|
||||
Font smallFont = null;
|
||||
|
||||
ArrayList<PoolPlotter> poolPlotters = new ArrayList<PoolPlotter>(5);
|
||||
|
||||
int nHeapPools = 0;
|
||||
int nNonHeapPools = 0;
|
||||
Rectangle heapRect = new Rectangle(leftMargin, height - bottomMargin + 6, barWidth, 20);
|
||||
Rectangle nonHeapRect = new Rectangle(leftMargin + groupGap, height - bottomMargin + 6, barWidth, 20);
|
||||
|
||||
public PoolChart() {
|
||||
super(null, null);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
ToolTipManager.sharedInstance().registerComponent(this);
|
||||
}
|
||||
|
||||
public void setValue(int poolIndex, PoolPlotter poolPlotter,
|
||||
long value, long threshold, long max) {
|
||||
poolPlotter.value = value;
|
||||
poolPlotter.threshold = threshold;
|
||||
poolPlotter.max = max;
|
||||
|
||||
if (poolIndex == poolPlotters.size()) {
|
||||
poolPlotters.add(poolPlotter);
|
||||
if (poolPlotter.isHeap) {
|
||||
poolPlotter.barX = nHeapPools * (barWidth + barGap);
|
||||
nHeapPools++;
|
||||
heapRect.width = nHeapPools * barWidth + (nHeapPools - 1) * barGap;
|
||||
nonHeapRect.x = leftMargin + heapRect.width + groupGap;
|
||||
} else {
|
||||
poolPlotter.barX = nonHeapRect.x - leftMargin + nNonHeapPools * (barWidth + barGap);
|
||||
nNonHeapPools++;
|
||||
nonHeapRect.width = nNonHeapPools * barWidth + (nNonHeapPools - 1) * barGap;
|
||||
}
|
||||
} else {
|
||||
poolPlotters.set(poolIndex, poolPlotter);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void paintPoolBar(Graphics g, PoolPlotter poolPlotter) {
|
||||
Rectangle barRect = getBarRect(poolPlotter);
|
||||
g.setColor(Color.gray);
|
||||
g.drawRect(barRect.x, barRect.y, barRect.width, barRect.height);
|
||||
|
||||
long value = poolPlotter.value;
|
||||
long max = poolPlotter.max;
|
||||
if (max > 0L) {
|
||||
g.translate(barRect.x, barRect.y);
|
||||
|
||||
// Paint green background
|
||||
g.setColor(greenBarBackground);
|
||||
g.fillRect(1, 1, barRect.width - 1, barRect.height - 1);
|
||||
|
||||
int greenHeight = (int)(value * barRect.height / max);
|
||||
long threshold = poolPlotter.threshold;
|
||||
if (threshold > 0L) {
|
||||
int redHeight = (int)(threshold * barRect.height / max);
|
||||
|
||||
// Paint red background
|
||||
g.setColor(redBarBackground);
|
||||
g.fillRect(1, 1, barRect.width - 1, barRect.height - redHeight);
|
||||
|
||||
if (value > threshold) {
|
||||
// Over threshold, paint red bar
|
||||
g.setColor(thresholdColor);
|
||||
g.fillRect(1, barRect.height - greenHeight,
|
||||
barRect.width - 1, greenHeight - redHeight);
|
||||
greenHeight = redHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Paint green bar
|
||||
g.setColor(greenBar);
|
||||
g.fillRect(1, barRect.height - greenHeight,
|
||||
barRect.width - 1, greenHeight);
|
||||
|
||||
g.translate(-barRect.x, -barRect.y);
|
||||
}
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if (poolPlotters.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (smallFont == null) {
|
||||
smallFont = g.getFont().deriveFont(9.0F);
|
||||
}
|
||||
|
||||
// Paint background for chart area
|
||||
g.setColor(getBackground());
|
||||
Rectangle r = g.getClipBounds();
|
||||
g.fillRect(r.x, r.y, r.width, r.height);
|
||||
|
||||
g.setFont(smallFont);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int fontDescent = fm.getDescent();
|
||||
|
||||
// Paint percentage axis
|
||||
g.setColor(getForeground());
|
||||
for (int pc : new int[] { 0, 25, 50, 75, 100 }) {
|
||||
String str = pc + "% --";
|
||||
g.drawString(str,
|
||||
leftMargin - fm.stringWidth(str) - 4,
|
||||
height - bottomMargin - (pc * barHeight / 100) + fontDescent + 1);
|
||||
}
|
||||
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
paintPoolBar(g, poolPlotter);
|
||||
}
|
||||
|
||||
g.setColor(Color.gray);
|
||||
g.drawRect(heapRect.x, heapRect.y, heapRect.width, heapRect.height);
|
||||
g.drawRect(nonHeapRect.x, nonHeapRect.y, nonHeapRect.width, nonHeapRect.height);
|
||||
|
||||
Color heapColor = greenBar;
|
||||
Color nonHeapColor = greenBar;
|
||||
|
||||
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
if (poolPlotter.threshold > 0L && poolPlotter.value > poolPlotter.threshold) {
|
||||
if (poolPlotter.isHeap) {
|
||||
heapColor = thresholdColor;
|
||||
} else {
|
||||
nonHeapColor = thresholdColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
g.setColor(heapColor);
|
||||
g.fillRect(heapRect.x + 1, heapRect.y + 1, heapRect.width - 1, heapRect.height - 1);
|
||||
g.setColor(nonHeapColor);
|
||||
g.fillRect(nonHeapRect.x + 1, nonHeapRect.y + 1, nonHeapRect.width - 1, nonHeapRect.height - 1);
|
||||
|
||||
String str = Messages.HEAP;
|
||||
int stringWidth = fm.stringWidth(str);
|
||||
int x = heapRect.x + (heapRect.width - stringWidth) / 2;
|
||||
int y = heapRect.y + heapRect.height - 6;
|
||||
g.setColor(Color.white);
|
||||
g.drawString(str, x-1, y-1);
|
||||
g.drawString(str, x+1, y-1);
|
||||
g.drawString(str, x-1, y+1);
|
||||
g.drawString(str, x+1, y+1);
|
||||
g.setColor(Color.black);
|
||||
g.drawString(str, x, y);
|
||||
|
||||
str = Messages.NON_HEAP;
|
||||
stringWidth = fm.stringWidth(str);
|
||||
x = nonHeapRect.x + (nonHeapRect.width - stringWidth) / 2;
|
||||
y = nonHeapRect.y + nonHeapRect.height - 6;
|
||||
g.setColor(Color.white);
|
||||
g.drawString(str, x-1, y-1);
|
||||
g.drawString(str, x+1, y-1);
|
||||
g.drawString(str, x-1, y+1);
|
||||
g.drawString(str, x+1, y+1);
|
||||
g.setColor(Color.black);
|
||||
g.drawString(str, x, y);
|
||||
|
||||
// Highlight current plotter
|
||||
g.setColor(Color.blue);
|
||||
r = null;
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
if (plotter == heapPlotter) {
|
||||
r = heapRect;
|
||||
} else if (plotter == nonHeapPlotter) {
|
||||
r = nonHeapRect;
|
||||
} else if (plotter instanceof PoolPlotter) {
|
||||
r = getBarRect((PoolPlotter)plotter);
|
||||
}
|
||||
if (r != null) {
|
||||
g.drawRect(r.x - 1, r.y - 1, r.width + 2, r.height + 2);
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle getBarRect(PoolPlotter poolPlotter) {
|
||||
return new Rectangle(leftMargin + poolPlotter.barX,
|
||||
height - bottomMargin - barHeight,
|
||||
barWidth, barHeight);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(nonHeapRect.x + nonHeapRect.width + rightMargin,
|
||||
height);
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
requestFocusInWindow();
|
||||
Plotter plotter = getPlotter(e);
|
||||
|
||||
if (plotter != null && plotter != plotterChoice.getSelectedItem()) {
|
||||
plotterChoice.setSelectedItem(plotter);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
Plotter plotter = getPlotter(e);
|
||||
|
||||
return (plotter != null) ? plotter.toString() : null;
|
||||
}
|
||||
|
||||
private Plotter getPlotter(MouseEvent e) {
|
||||
Point p = e.getPoint();
|
||||
Plotter plotter = null;
|
||||
|
||||
if (heapRect.contains(p)) {
|
||||
plotter = heapPlotter;
|
||||
} else if (nonHeapRect.contains(p)) {
|
||||
plotter = nonHeapPlotter;
|
||||
} else {
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
if (getBarRect(poolPlotter).contains(p)) {
|
||||
plotter = poolPlotter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return plotter;
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {}
|
||||
public void mouseReleased(MouseEvent e) {}
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
|
||||
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessiblePoolChart();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
protected class AccessiblePoolChart extends AccessibleJPanel {
|
||||
public String getAccessibleName() {
|
||||
String name = Messages.MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
|
||||
|
||||
String keyValueList = "";
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
String value = (poolPlotter.value * 100 / poolPlotter.max) + "%";
|
||||
// Assume format string ends with newline
|
||||
keyValueList +=
|
||||
Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE,
|
||||
poolPlotter.toString(), value);
|
||||
if (poolPlotter.threshold > 0L) {
|
||||
String threshold =
|
||||
(poolPlotter.threshold * 100 / poolPlotter.max) + "%";
|
||||
if (poolPlotter.value > poolPlotter.threshold) {
|
||||
keyValueList +=
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD,
|
||||
threshold);
|
||||
} else {
|
||||
keyValueList +=
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD,
|
||||
threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name + "\n" + keyValueList + ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new MemoryOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
private static class MemoryOverviewPanel extends OverviewPanel {
|
||||
MemoryOverviewPanel() {
|
||||
super(Messages.HEAP_MEMORY_USAGE, usedKey, Messages.USED, Plotter.Unit.BYTES);
|
||||
}
|
||||
|
||||
private void updateMemoryInfo(long used, long committed, long max) {
|
||||
getInfoLabel().setText(Resources.format(Messages.MEMORY_TAB_INFO_LABEL_FORMAT,
|
||||
formatBytes(used, true),
|
||||
formatBytes(committed, true),
|
||||
formatBytes(max, true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
325
jdkSrc/jdk8/sun/tools/jconsole/Messages.java
Normal file
325
jdkSrc/jdk8/sun/tools/jconsole/Messages.java
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 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 sun.tools.jconsole;
|
||||
|
||||
|
||||
/**
|
||||
* Class that contains localized messages.
|
||||
*
|
||||
*/
|
||||
final public class Messages {
|
||||
private static final String BUNDLE_NAME = "sun.tools.jconsole.resources.messages";
|
||||
|
||||
static {
|
||||
Resources.initializeMessages(Messages.class, BUNDLE_NAME);
|
||||
}
|
||||
// TODO:
|
||||
// The names of some of the constants below look strange.
|
||||
// That's because they were generated programmatically
|
||||
// from the messages. They should be cleaned up,
|
||||
// ___ should be removed etc.
|
||||
public static String ONE_DAY;
|
||||
public static String ONE_HOUR;
|
||||
public static String ONE_MIN;
|
||||
public static String ONE_MONTH;
|
||||
public static String ONE_YEAR;
|
||||
public static String TWO_HOURS;
|
||||
public static String THREE_HOURS;
|
||||
public static String THREE_MONTHS;
|
||||
public static String FIVE_MIN;
|
||||
public static String SIX_HOURS;
|
||||
public static String SIX_MONTHS;
|
||||
public static String SEVEN_DAYS;
|
||||
public static String TEN_MIN;
|
||||
public static String TWELVE_HOURS;
|
||||
public static String THIRTY_MIN;
|
||||
public static String LESS_THAN;
|
||||
public static String A_LOT_LESS_THAN;
|
||||
public static String GREATER_THAN;
|
||||
public static String ACTION_CAPITALIZED;
|
||||
public static String ACTION_INFO_CAPITALIZED;
|
||||
public static String ALL;
|
||||
public static String ARCHITECTURE;
|
||||
public static String ATTRIBUTE;
|
||||
public static String ATTRIBUTE_VALUE;
|
||||
public static String ATTRIBUTE_VALUES;
|
||||
public static String ATTRIBUTES;
|
||||
public static String BLANK;
|
||||
public static String BLOCKED_COUNT_WAITED_COUNT;
|
||||
public static String BOOT_CLASS_PATH;
|
||||
public static String BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
|
||||
public static String CPU_USAGE;
|
||||
public static String CPU_USAGE_FORMAT;
|
||||
public static String CANCEL;
|
||||
public static String CASCADE;
|
||||
public static String CHART_COLON;
|
||||
public static String CLASS_PATH;
|
||||
public static String CLASS_NAME;
|
||||
public static String CLASS_TAB_INFO_LABEL_FORMAT;
|
||||
public static String CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String CLASSES;
|
||||
public static String CLOSE;
|
||||
public static String COLUMN_NAME;
|
||||
public static String COLUMN_PID;
|
||||
public static String COMMITTED_MEMORY;
|
||||
public static String COMMITTED_VIRTUAL_MEMORY;
|
||||
public static String COMMITTED;
|
||||
public static String CONNECT;
|
||||
public static String CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
|
||||
public static String CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
|
||||
public static String CONNECT_DIALOG_MASTHEAD_TITLE;
|
||||
public static String CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME;
|
||||
public static String CONNECT_DIALOG_TITLE;
|
||||
public static String CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
|
||||
public static String CONNECTION_FAILED;
|
||||
public static String CONNECTION;
|
||||
public static String CONNECTION_NAME;
|
||||
public static String CONNECTION_NAME__DISCONNECTED_;
|
||||
public static String CONSTRUCTOR;
|
||||
public static String CURRENT_CLASSES_LOADED;
|
||||
public static String CURRENT_HEAP_SIZE;
|
||||
public static String CURRENT_VALUE;
|
||||
public static String CREATE;
|
||||
public static String DAEMON_THREADS;
|
||||
public static String DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
|
||||
public static String DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE;
|
||||
public static String DOUBLE_CLICK_TO_VISUALIZE;
|
||||
public static String DESCRIPTION;
|
||||
public static String DESCRIPTOR;
|
||||
public static String DETAILS;
|
||||
public static String DETECT_DEADLOCK;
|
||||
public static String DETECT_DEADLOCK_TOOLTIP;
|
||||
public static String DIMENSION_IS_NOT_SUPPORTED_COLON;
|
||||
public static String DISCARD_CHART;
|
||||
public static String DURATION_DAYS_HOURS_MINUTES;
|
||||
public static String DURATION_HOURS_MINUTES;
|
||||
public static String DURATION_MINUTES;
|
||||
public static String DURATION_SECONDS;
|
||||
public static String EMPTY_ARRAY;
|
||||
public static String ERROR;
|
||||
public static String ERROR_COLON_MBEANS_ALREADY_EXIST;
|
||||
public static String ERROR_COLON_MBEANS_DO_NOT_EXIST;
|
||||
public static String EVENT;
|
||||
public static String EXIT;
|
||||
public static String FAIL_TO_LOAD_PLUGIN;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_MESSAGE;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_OK_OPTION;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_TITLE;
|
||||
public static String FILE_CHOOSER_SAVED_FILE;
|
||||
public static String FILE_CHOOSER_SAVE_FAILED_MESSAGE;
|
||||
public static String FILE_CHOOSER_SAVE_FAILED_TITLE;
|
||||
public static String FREE_PHYSICAL_MEMORY;
|
||||
public static String FREE_SWAP_SPACE;
|
||||
public static String GARBAGE_COLLECTOR;
|
||||
public static String GC_INFO;
|
||||
public static String GC_TIME;
|
||||
public static String GC_TIME_DETAILS;
|
||||
public static String HEAP_MEMORY_USAGE;
|
||||
public static String HEAP;
|
||||
public static String HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String HELP_ABOUT_DIALOG_JCONSOLE_VERSION;
|
||||
public static String HELP_ABOUT_DIALOG_JAVA_VERSION;
|
||||
public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
|
||||
public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE;
|
||||
public static String HELP_ABOUT_DIALOG_TITLE;
|
||||
public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
|
||||
public static String HELP_MENU_ABOUT_TITLE;
|
||||
public static String HELP_MENU_USER_GUIDE_TITLE;
|
||||
public static String HELP_MENU_TITLE;
|
||||
public static String HOTSPOT_MBEANS_ELLIPSIS;
|
||||
public static String HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String IMPACT;
|
||||
public static String INFO;
|
||||
public static String INFO_CAPITALIZED;
|
||||
public static String INSECURE;
|
||||
public static String INVALID_PLUGIN_PATH;
|
||||
public static String INVALID_URL;
|
||||
public static String IS;
|
||||
public static String JAVA_MONITORING___MANAGEMENT_CONSOLE;
|
||||
public static String JCONSOLE_COLON_;
|
||||
public static String JCONSOLE_VERSION; // in version template
|
||||
public static String JCONSOLE_ACCESSIBLE_DESCRIPTION;
|
||||
public static String JIT_COMPILER;
|
||||
public static String LIBRARY_PATH;
|
||||
public static String LIVE_THREADS;
|
||||
public static String LOADED;
|
||||
public static String LOCAL_PROCESS_COLON;
|
||||
public static String MASTHEAD_FONT;
|
||||
public static String MANAGEMENT_NOT_ENABLED;
|
||||
public static String MANAGEMENT_WILL_BE_ENABLED;
|
||||
public static String MBEAN_ATTRIBUTE_INFO;
|
||||
public static String MBEAN_INFO;
|
||||
public static String MBEAN_NOTIFICATION_INFO;
|
||||
public static String MBEAN_OPERATION_INFO;
|
||||
public static String MBEANS;
|
||||
public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE;
|
||||
public static String MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE;
|
||||
public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON;
|
||||
public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE;
|
||||
public static String MBEANS_TAB_TABULAR_NAVIGATION_SINGLE;
|
||||
public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MANAGE_HOTSPOT_MBEANS_IN_COLON_;
|
||||
public static String MAX;
|
||||
public static String MAXIMUM_HEAP_SIZE;
|
||||
public static String MEMORY;
|
||||
public static String MEMORY_POOL_LABEL;
|
||||
public static String MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_INFO_LABEL_FORMAT;
|
||||
public static String MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD;
|
||||
public static String MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD;
|
||||
public static String MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MESSAGE;
|
||||
public static String METHOD_SUCCESSFULLY_INVOKED;
|
||||
public static String MINIMIZE_ALL;
|
||||
public static String MONITOR_LOCKED;
|
||||
public static String NAME;
|
||||
public static String NAME_STATE;
|
||||
public static String NAME_STATE_LOCK_NAME;
|
||||
public static String NAME_STATE_LOCK_NAME_LOCK_OWNER;
|
||||
public static String NAME_AND_BUILD;// in version template
|
||||
public static String NEW_CONNECTION_ELLIPSIS;
|
||||
public static String NO_DEADLOCK_DETECTED;
|
||||
public static String NON_HEAP_MEMORY_USAGE;
|
||||
public static String NON_HEAP;
|
||||
public static String NOTIFICATION;
|
||||
public static String NOTIFICATION_BUFFER;
|
||||
public static String NOTIFICATIONS;
|
||||
public static String NOTIF_TYPES;
|
||||
public static String NUMBER_OF_THREADS;
|
||||
public static String NUMBER_OF_LOADED_CLASSES;
|
||||
public static String NUMBER_OF_PROCESSORS;
|
||||
public static String OBJECT_NAME;
|
||||
public static String OPERATING_SYSTEM;
|
||||
public static String OPERATION;
|
||||
public static String OPERATION_INVOCATION;
|
||||
public static String OPERATION_RETURN_VALUE;
|
||||
public static String OPERATIONS;
|
||||
public static String OVERVIEW;
|
||||
public static String OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String PARAMETER;
|
||||
public static String PASSWORD_COLON_;
|
||||
public static String PASSWORD_ACCESSIBLE_NAME;
|
||||
public static String PEAK;
|
||||
public static String PERFORM_GC;
|
||||
public static String PERFORM_GC_TOOLTIP;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA;
|
||||
public static String PLOTTER_SAVE_AS_MENU_ITEM;
|
||||
public static String PLOTTER_TIME_RANGE_MENU;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_OK;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_MESSAGE;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_TITLE;
|
||||
public static String PROBLEM_ADDING_LISTENER;
|
||||
public static String PROBLEM_DISPLAYING_MBEAN;
|
||||
public static String PROBLEM_INVOKING;
|
||||
public static String PROBLEM_REMOVING_LISTENER;
|
||||
public static String PROBLEM_SETTING_ATTRIBUTE;
|
||||
public static String PROCESS_CPU_TIME;
|
||||
public static String READABLE;
|
||||
public static String RECONNECT;
|
||||
public static String REMOTE_PROCESS_COLON;
|
||||
public static String REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME;
|
||||
public static String RESTORE_ALL;
|
||||
public static String RETURN_TYPE;
|
||||
public static String SEQ_NUM;
|
||||
public static String SIZE_BYTES;
|
||||
public static String SIZE_GB;
|
||||
public static String SIZE_KB;
|
||||
public static String SIZE_MB;
|
||||
public static String SOURCE;
|
||||
public static String STACK_TRACE;
|
||||
public static String SUMMARY_TAB_HEADER_DATE_TIME_FORMAT;
|
||||
public static String SUMMARY_TAB_PENDING_FINALIZATION_LABEL;
|
||||
public static String SUMMARY_TAB_PENDING_FINALIZATION_VALUE;
|
||||
public static String SUMMARY_TAB_TAB_NAME;
|
||||
public static String SUMMARY_TAB_VM_VERSION;
|
||||
public static String THREADS;
|
||||
public static String THREAD_TAB_INFO_LABEL_FORMAT;
|
||||
public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME;
|
||||
public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE;
|
||||
public static String THRESHOLD;
|
||||
public static String TILE;
|
||||
public static String TIME_RANGE_COLON;
|
||||
public static String TIME;
|
||||
public static String TIME_STAMP;
|
||||
public static String TOTAL_LOADED;
|
||||
public static String TOTAL_CLASSES_LOADED;
|
||||
public static String TOTAL_CLASSES_UNLOADED;
|
||||
public static String TOTAL_COMPILE_TIME;
|
||||
public static String TOTAL_PHYSICAL_MEMORY;
|
||||
public static String TOTAL_THREADS_STARTED;
|
||||
public static String TOTAL_SWAP_SPACE;
|
||||
public static String TYPE;
|
||||
public static String UNAVAILABLE;
|
||||
public static String UNKNOWN_CAPITALIZED;
|
||||
public static String UNKNOWN_HOST;
|
||||
public static String UNREGISTER;
|
||||
public static String UPTIME;
|
||||
public static String USAGE_THRESHOLD;
|
||||
public static String REMOTE_TF_USAGE;
|
||||
public static String USED;
|
||||
public static String USERNAME_COLON_;
|
||||
public static String USERNAME_ACCESSIBLE_NAME;
|
||||
public static String USER_DATA;
|
||||
public static String VIRTUAL_MACHINE;
|
||||
public static String VM_ARGUMENTS;
|
||||
public static String VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION;
|
||||
public static String VALUE;
|
||||
public static String VENDOR;
|
||||
public static String VERBOSE_OUTPUT;
|
||||
public static String VERBOSE_OUTPUT_TOOLTIP;
|
||||
public static String VIEW;
|
||||
public static String WINDOW;
|
||||
public static String WINDOWS;
|
||||
public static String WRITABLE;
|
||||
public static String CONNECTION_FAILED1;
|
||||
public static String CONNECTION_FAILED2;
|
||||
public static String CONNECTION_FAILED_SSL1;
|
||||
public static String CONNECTION_FAILED_SSL2;
|
||||
public static String CONNECTION_LOST1;
|
||||
public static String CONNECTING_TO1;
|
||||
public static String CONNECTING_TO2;
|
||||
public static String DEADLOCK_TAB;
|
||||
public static String DEADLOCK_TAB_N;
|
||||
public static String EXPAND;
|
||||
public static String KBYTES;
|
||||
public static String PLOT;
|
||||
public static String VISUALIZE;
|
||||
public static String ZZ_USAGE_TEXT;
|
||||
}
|
||||
131
jdkSrc/jdk8/sun/tools/jconsole/OutputViewer.java
Normal file
131
jdkSrc/jdk8/sun/tools/jconsole/OutputViewer.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* A simple console window to display messages sent to System.out and
|
||||
* System.err.
|
||||
*
|
||||
* A stop-gap solution until an error dialog is implemented.
|
||||
*/
|
||||
public class OutputViewer {
|
||||
private static JFrame frame;
|
||||
private static JTextArea ta;
|
||||
|
||||
static {
|
||||
System.setOut(PipeListener.create("System.out"));
|
||||
System.setErr(PipeListener.create("System.err"));
|
||||
}
|
||||
|
||||
// Dummy to cause class to be loaded
|
||||
public static void init() { }
|
||||
|
||||
private static void append(String s) {
|
||||
if (frame == null) {
|
||||
// FIXME: The frame title should be a localized string.
|
||||
frame = new JFrame("JConsole: Output");
|
||||
ta = new JTextArea();
|
||||
ta.setEditable(false);
|
||||
frame.getContentPane().add(new JScrollPane(ta));
|
||||
ta.setFont(new Font("Monospaced", Font.BOLD, 14));
|
||||
frame.setSize(500, 600);
|
||||
frame.setLocation(1024-500, 768-600);
|
||||
// Exit JConsole if no window remains.
|
||||
// e.g. jconsole -version only creates the OutputViewer
|
||||
// but no other window.
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (JFrame.getFrames().length == 1) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
ta.append(s);
|
||||
ta.setCaretPosition(ta.getText().length());
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static void appendln(String s) {
|
||||
append(s+"\n");
|
||||
}
|
||||
|
||||
private static class PipeListener extends Thread {
|
||||
public PrintStream ps;
|
||||
private String name;
|
||||
private PipedInputStream inPipe;
|
||||
private BufferedReader br;
|
||||
|
||||
public static PrintStream create(String name) {
|
||||
return new PipeListener(name).ps;
|
||||
}
|
||||
|
||||
private PipeListener(String name) {
|
||||
this.name = name;
|
||||
|
||||
try {
|
||||
inPipe = new PipedInputStream();
|
||||
ps = new PrintStream(new PipedOutputStream(inPipe));
|
||||
br = new BufferedReader(new InputStreamReader(inPipe));
|
||||
} catch (IOException e) {
|
||||
appendln("PipeListener<init>("+name+"): " + e);
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
String str;
|
||||
while ((str = br.readLine()) != null) {
|
||||
appendln(str);
|
||||
|
||||
// Hack: Turn off thread check in PipedInputStream.
|
||||
// Any thread should be allowed to write except this one
|
||||
// but we just use this one to keep the pipe alive.
|
||||
try {
|
||||
java.lang.reflect.Field f =
|
||||
PipedInputStream.class.getDeclaredField("writeSide");
|
||||
f.setAccessible(true);
|
||||
f.set(inPipe, this);
|
||||
} catch (Exception e) {
|
||||
appendln("PipeListener("+name+").run: "+e);
|
||||
}
|
||||
}
|
||||
appendln("-- "+name+" closed --");
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
appendln("PipeListener("+name+").run: "+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
jdkSrc/jdk8/sun/tools/jconsole/OverviewPanel.java
Normal file
115
jdkSrc/jdk8/sun/tools/jconsole/OverviewPanel.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
import static javax.swing.SwingConstants.*;
|
||||
import static sun.tools.jconsole.JConsole.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
abstract class OverviewPanel extends PlotterPanel {
|
||||
private static final Dimension PREFERRED_PLOTTER_SIZE = new Dimension(300, 200);
|
||||
private static final Dimension MINIMUM_PLOTTER_SIZE = new Dimension(200, 150);
|
||||
|
||||
// This is the default view range for all the overview plotters
|
||||
static final int VIEW_RANGE = -1; // Show all data
|
||||
|
||||
static Color PLOTTER_COLOR = IS_GTK ? new Color(231, 111, 80) : null;
|
||||
|
||||
private JLabel infoLabel;
|
||||
|
||||
public OverviewPanel(String title) {
|
||||
this(title, null, null, null);
|
||||
}
|
||||
|
||||
public OverviewPanel(String title, String plotterKey,
|
||||
String plotterName, Plotter.Unit plotterUnit) {
|
||||
super(title);
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
|
||||
if (plotterKey != null && plotterName != null) {
|
||||
Plotter plotter = new Plotter();
|
||||
plotter.setPreferredSize(PREFERRED_PLOTTER_SIZE);
|
||||
plotter.setMinimumSize(MINIMUM_PLOTTER_SIZE);
|
||||
plotter.setViewRange(VIEW_RANGE);
|
||||
if (plotterUnit != null) {
|
||||
plotter.setUnit(plotterUnit);
|
||||
}
|
||||
plotter.createSequence(plotterKey, plotterName, PLOTTER_COLOR, true);
|
||||
setAccessibleName(plotter,
|
||||
Resources.format(Messages.OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME,
|
||||
title));
|
||||
setPlotter(plotter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public JLabel getInfoLabel() {
|
||||
if (infoLabel == null) {
|
||||
infoLabel = new JLabel("", CENTER) {
|
||||
@Override
|
||||
public void setText(String text) {
|
||||
if (text.startsWith("<html>")) {
|
||||
// Replace spaces with nbsp, except the
|
||||
// last one of two or more (to allow wrapping)
|
||||
StringBuilder buf = new StringBuilder();
|
||||
char[] chars = text.toCharArray();
|
||||
int n = chars.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (chars[i] == ' '
|
||||
&& ((i < n-1 && chars[i+1] == ' ')
|
||||
|| ((i == 0 || chars[i-1] != ' ')
|
||||
&& (i == n-1 || chars[i+1] != ' ')))) {
|
||||
buf.append(" ");
|
||||
} else {
|
||||
buf.append(chars[i]);
|
||||
}
|
||||
}
|
||||
text = buf.toString();
|
||||
}
|
||||
super.setText(text);
|
||||
}
|
||||
};
|
||||
|
||||
if (IS_GTK) {
|
||||
JPanel southPanel = new JPanel(new BorderLayout());
|
||||
JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
|
||||
southPanel.add(separator, BorderLayout.NORTH);
|
||||
southPanel.add(infoLabel, BorderLayout.SOUTH);
|
||||
add(southPanel, BorderLayout.SOUTH);
|
||||
} else {
|
||||
add(infoLabel, BorderLayout.SOUTH);
|
||||
}
|
||||
}
|
||||
return infoLabel;
|
||||
}
|
||||
}
|
||||
152
jdkSrc/jdk8/sun/tools/jconsole/OverviewTab.java
Normal file
152
jdkSrc/jdk8/sun/tools/jconsole/OverviewTab.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class OverviewTab extends Tab {
|
||||
JPanel gridPanel;
|
||||
TimeComboBox timeComboBox;
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.OVERVIEW;
|
||||
}
|
||||
|
||||
public OverviewTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
timeComboBox = new TimeComboBox();
|
||||
LabeledComponent lc = new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox);
|
||||
controlPanel.add(lc);
|
||||
|
||||
gridPanel = new JPanel(new AutoGridLayout(10, 6));
|
||||
gridPanel.setBorder(null);
|
||||
JScrollPane sp = new JScrollPane(gridPanel);
|
||||
sp.setBorder(null);
|
||||
sp.setViewportBorder(null);
|
||||
add(sp, BorderLayout.CENTER);
|
||||
|
||||
// Note that panels are added on first update
|
||||
}
|
||||
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
return new SwingWorker<Object, Object>() {
|
||||
public Object doInBackground() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
if (gridPanel.getComponentCount() == 0) {
|
||||
final ArrayList<Plotter> plotters = new ArrayList<Plotter>();
|
||||
for (Tab tab : vmPanel.getTabs()) {
|
||||
OverviewPanel[] ops = tab.getOverviewPanels();
|
||||
if (ops != null) {
|
||||
for (OverviewPanel op : ops) {
|
||||
gridPanel.add(op);
|
||||
Plotter plotter = op.getPlotter();
|
||||
if (plotter != null) {
|
||||
plotters.add(plotter);
|
||||
timeComboBox.addPlotter(plotter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plotters.size() > 0) {
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
for (Plotter plotter : plotters) {
|
||||
proxyClient.addWeakPropertyChangeListener(plotter);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (getParent() instanceof JTabbedPane) {
|
||||
Utilities.updateTransparency((JTabbedPane)getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class AutoGridLayout extends GridLayout {
|
||||
public AutoGridLayout(int hGap, int vGap) {
|
||||
super(0, 1, hGap, vGap);
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
return minimumLayoutSize(parent);
|
||||
}
|
||||
|
||||
public Dimension minimumLayoutSize(Container parent) {
|
||||
updateColumns(parent);
|
||||
return super.minimumLayoutSize(parent);
|
||||
}
|
||||
|
||||
private void updateColumns(Container parent) {
|
||||
// Use the outer panel width, not the scrolling gridPanel
|
||||
int parentWidth = OverviewTab.this.getWidth();
|
||||
|
||||
int columnWidth = 1;
|
||||
|
||||
for (Component c : parent.getComponents()) {
|
||||
columnWidth = Math.max(columnWidth, c.getPreferredSize().width);
|
||||
}
|
||||
|
||||
int n = parent.getComponentCount();
|
||||
int maxCols = Math.min(n, parentWidth / columnWidth);
|
||||
|
||||
for (int columns = maxCols; columns >= 1; columns--) {
|
||||
if (columns == 1) {
|
||||
setColumns(maxCols);
|
||||
} else if ((n % columns) == 0) {
|
||||
setColumns(columns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1100
jdkSrc/jdk8/sun/tools/jconsole/Plotter.java
Normal file
1100
jdkSrc/jdk8/sun/tools/jconsole/Plotter.java
Normal file
File diff suppressed because it is too large
Load Diff
93
jdkSrc/jdk8/sun/tools/jconsole/PlotterPanel.java
Normal file
93
jdkSrc/jdk8/sun/tools/jconsole/PlotterPanel.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
import javax.swing.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PlotterPanel extends BorderedComponent {
|
||||
Plotter plotter;
|
||||
|
||||
public PlotterPanel(String labelStr, Plotter.Unit unit, boolean collapsible) {
|
||||
super(labelStr, new Plotter(unit), collapsible);
|
||||
|
||||
this.plotter = (Plotter)comp;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public PlotterPanel(String labelStr) {
|
||||
super(labelStr, null);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public Plotter getPlotter() {
|
||||
return this.plotter;
|
||||
}
|
||||
|
||||
public void setPlotter(Plotter plotter) {
|
||||
this.plotter = plotter;
|
||||
setComponent(plotter);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JPopupMenu getComponentPopupMenu() {
|
||||
return (getPlotter() != null)? getPlotter().getComponentPopupMenu() : null;
|
||||
}
|
||||
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessiblePlotterPanel();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
protected class AccessiblePlotterPanel extends AccessibleJComponent {
|
||||
public String getAccessibleName() {
|
||||
String name = null;
|
||||
if (getPlotter() != null) {
|
||||
name = getPlotter().getAccessibleContext().getAccessibleName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = super.getAccessibleName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
1059
jdkSrc/jdk8/sun/tools/jconsole/ProxyClient.java
Normal file
1059
jdkSrc/jdk8/sun/tools/jconsole/ProxyClient.java
Normal file
File diff suppressed because it is too large
Load Diff
209
jdkSrc/jdk8/sun/tools/jconsole/Resources.java
Normal file
209
jdkSrc/jdk8/sun/tools/jconsole/Resources.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Toolkit that provides resource support for JConsole.
|
||||
*/
|
||||
public final class Resources {
|
||||
private static Map<String, Integer> MNEMONIC_LOOKUP = Collections
|
||||
.synchronizedMap(new IdentityHashMap<String, Integer>());
|
||||
|
||||
private Resources() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for {@link MessageFormat#format(String, Object...)}.
|
||||
*
|
||||
* @param pattern the pattern
|
||||
* @param objects the arguments for the pattern
|
||||
*
|
||||
* @return a formatted string
|
||||
*/
|
||||
public static String format(String pattern, Object... arguments) {
|
||||
return MessageFormat.format(pattern, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mnemonic for a message.
|
||||
*
|
||||
* @param message the message
|
||||
*
|
||||
* @return the mnemonic <code>int</code>
|
||||
*/
|
||||
public static int getMnemonicInt(String message) {
|
||||
Integer integer = MNEMONIC_LOOKUP.get(message);
|
||||
if (integer != null) {
|
||||
return integer.intValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all non-final public static fields in the given class with
|
||||
* messages from a {@link ResourceBundle}.
|
||||
*
|
||||
* @param clazz the class containing the fields
|
||||
*/
|
||||
public static void initializeMessages(Class<?> clazz, String rbName) {
|
||||
ResourceBundle rb = null;
|
||||
try {
|
||||
rb = ResourceBundle.getBundle(rbName);
|
||||
} catch (MissingResourceException mre) {
|
||||
// fall through, handled later
|
||||
}
|
||||
for (Field field : clazz.getFields()) {
|
||||
if (isWritableField(field)) {
|
||||
String key = field.getName();
|
||||
String message = getMessage(rb, key);
|
||||
int mnemonicInt = findMnemonicInt(message);
|
||||
message = removeMnemonicAmpersand(message);
|
||||
message = replaceWithPlatformLineFeed(message);
|
||||
setFieldValue(field, message);
|
||||
MNEMONIC_LOOKUP.put(message, mnemonicInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWritableField(Field field) {
|
||||
int modifiers = field.getModifiers();
|
||||
return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)
|
||||
&& !Modifier.isFinal(modifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message corresponding to the key in the bundle or a text
|
||||
* describing it's missing.
|
||||
*
|
||||
* @param rb the resource bundle
|
||||
* @param key the key
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
private static String getMessage(ResourceBundle rb, String key) {
|
||||
if (rb == null) {
|
||||
return "missing resource bundle";
|
||||
}
|
||||
try {
|
||||
return rb.getString(key);
|
||||
} catch (MissingResourceException mre) {
|
||||
return "missing message for key = \"" + key
|
||||
+ "\" in resource bundle ";
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFieldValue(Field field, String value) {
|
||||
try {
|
||||
field.set(null, value);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new Error("Unable to access or set message for field " + field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link String} where all <code>\n</code> in the <text> have
|
||||
* been replaced with the line separator for the platform.
|
||||
*
|
||||
* @param text the to be replaced
|
||||
*
|
||||
* @return the replaced text
|
||||
*/
|
||||
private static String replaceWithPlatformLineFeed(String text) {
|
||||
return text.replace("\n", System.getProperty("line.separator"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mnemonic identifier (<code>&</code>) from a string unless
|
||||
* it's escaped by <code>&&</code> or placed at the end.
|
||||
*
|
||||
* @param message the message
|
||||
*
|
||||
* @return a message with the mnemonic identifier removed
|
||||
*/
|
||||
private static String removeMnemonicAmpersand(String message) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < message.length(); i++) {
|
||||
char current = message.charAt(i);
|
||||
if (current != '&' || i == message.length() - 1
|
||||
|| message.charAt(i + 1) == '&') {
|
||||
s.append(current);
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the mnemonic character in a message.
|
||||
*
|
||||
* The mnemonic character is the first character followed by the first
|
||||
* <code>&</code> that is not followed by another <code>&</code>.
|
||||
*
|
||||
* @return the mnemonic as an <code>int</code>, or <code>0</code> if it
|
||||
* can't be found.
|
||||
*/
|
||||
private static int findMnemonicInt(String s) {
|
||||
for (int i = 0; i < s.length() - 1; i++) {
|
||||
if (s.charAt(i) == '&') {
|
||||
if (s.charAt(i + 1) != '&') {
|
||||
return lookupMnemonicInt(s.substring(i + 1, i + 2));
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookups the mnemonic for a key in the {@link KeyEvent} class.
|
||||
*
|
||||
* @param c the character to lookup
|
||||
*
|
||||
* @return the mnemonic as an <code>int</code>, or <code>0</code> if it
|
||||
* can't be found.
|
||||
*/
|
||||
private static int lookupMnemonicInt(String c) {
|
||||
try {
|
||||
return KeyEvent.class.getDeclaredField("VK_" + c.toUpperCase())
|
||||
.getInt(null);
|
||||
} catch (IllegalArgumentException | IllegalAccessException
|
||||
| NoSuchFieldException | SecurityException e) {
|
||||
// Missing VK is okay
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
263
jdkSrc/jdk8/sun/tools/jconsole/SheetDialog.java
Normal file
263
jdkSrc/jdk8/sun/tools/jconsole/SheetDialog.java
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import static javax.swing.JOptionPane.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public final class SheetDialog {
|
||||
// Reusable objects
|
||||
private static Rectangle iconR = new Rectangle();
|
||||
private static Rectangle textR = new Rectangle();
|
||||
private static Rectangle viewR = new Rectangle();
|
||||
private static Insets viewInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
/** Don't let anyone instantiate this class */
|
||||
private SheetDialog() {
|
||||
}
|
||||
|
||||
static JOptionPane showOptionDialog(final VMPanel vmPanel, Object message,
|
||||
int optionType, int messageType,
|
||||
Icon icon, Object[] options, Object initialValue) {
|
||||
|
||||
JRootPane rootPane = SwingUtilities.getRootPane(vmPanel);
|
||||
JPanel glassPane = (JPanel)rootPane.getGlassPane();
|
||||
|
||||
if (!(glassPane instanceof SlideAndFadeGlassPane)) {
|
||||
glassPane = new SlideAndFadeGlassPane();
|
||||
glassPane.setName(rootPane.getName()+".glassPane");
|
||||
rootPane.setGlassPane(glassPane);
|
||||
rootPane.revalidate();
|
||||
}
|
||||
|
||||
final SlideAndFadeGlassPane safGlassPane = (SlideAndFadeGlassPane)glassPane;
|
||||
|
||||
// Workaround for the fact that JOptionPane does not handle
|
||||
// limiting the width when using multi-line html messages.
|
||||
// See Swing bug 5074006 and JConsole bug 6426317
|
||||
message = fixWrapping(message, rootPane.getWidth() - 75); // Leave room for icon
|
||||
|
||||
final SheetOptionPane optionPane = new SheetOptionPane(message, messageType, optionType,
|
||||
icon, options, initialValue);
|
||||
|
||||
optionPane.setComponentOrientation(vmPanel.getComponentOrientation());
|
||||
optionPane.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (event.getPropertyName().equals(VALUE_PROPERTY) &&
|
||||
event.getNewValue() != null &&
|
||||
event.getNewValue() != UNINITIALIZED_VALUE) {
|
||||
((SlideAndFadeGlassPane)optionPane.getParent()).hide(optionPane);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Delay this (even though we're already on the EDT)
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
safGlassPane.show(optionPane);
|
||||
}
|
||||
});
|
||||
|
||||
return optionPane;
|
||||
}
|
||||
|
||||
private static Object fixWrapping(Object message, final int maxWidth) {
|
||||
if (message instanceof Object[]) {
|
||||
Object[] arr = (Object[])message;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = fixWrapping(arr[i], maxWidth);
|
||||
}
|
||||
} else if (message instanceof String &&
|
||||
((String)message).startsWith("<html>")) {
|
||||
message = new JLabel((String)message) {
|
||||
public Dimension getPreferredSize() {
|
||||
String text = getText();
|
||||
Insets insets = getInsets(viewInsets);
|
||||
FontMetrics fm = getFontMetrics(getFont());
|
||||
Dimension pref = super.getPreferredSize();
|
||||
Dimension min = getMinimumSize();
|
||||
|
||||
iconR.x = iconR.y = iconR.width = iconR.height = 0;
|
||||
textR.x = textR.y = textR.width = textR.height = 0;
|
||||
int dx = insets.left + insets.right;
|
||||
int dy = insets.top + insets.bottom;
|
||||
viewR.x = dx;
|
||||
viewR.y = dy;
|
||||
viewR.width = viewR.height = Short.MAX_VALUE;
|
||||
|
||||
View v = (View)getClientProperty("html");
|
||||
if (v != null) {
|
||||
// Use pref width if less than 300, otherwise
|
||||
// min width up to size of window.
|
||||
int w = Math.min(maxWidth,
|
||||
Math.min(pref.width,
|
||||
Math.max(min.width, 300)));
|
||||
v.setSize((float)w, 0F);
|
||||
|
||||
SwingUtilities.layoutCompoundLabel(this, fm, text, null,
|
||||
getVerticalAlignment(),
|
||||
getHorizontalAlignment(),
|
||||
getVerticalTextPosition(),
|
||||
getHorizontalTextPosition(),
|
||||
viewR, iconR, textR,
|
||||
getIconTextGap());
|
||||
return new Dimension(textR.width + dx,
|
||||
textR.height + dy);
|
||||
} else {
|
||||
return pref; // Should not happen
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private static class SlideAndFadeGlassPane extends JPanel {
|
||||
SheetOptionPane optionPane;
|
||||
|
||||
int fade = 20;
|
||||
boolean slideIn = true;
|
||||
|
||||
SlideAndFadeGlassPane() {
|
||||
super(null);
|
||||
setVisible(false);
|
||||
setOpaque(false);
|
||||
|
||||
// Grab mouse input, making the dialog modal
|
||||
addMouseListener(new MouseAdapter() {});
|
||||
}
|
||||
|
||||
public void show(SheetOptionPane optionPane) {
|
||||
this.optionPane = optionPane;
|
||||
removeAll();
|
||||
add(optionPane);
|
||||
setVisible(true);
|
||||
slideIn = true;
|
||||
revalidate();
|
||||
repaint();
|
||||
doSlide();
|
||||
}
|
||||
|
||||
public void hide(SheetOptionPane optionPane) {
|
||||
if (optionPane != this.optionPane) {
|
||||
return;
|
||||
}
|
||||
|
||||
slideIn = false;
|
||||
revalidate();
|
||||
repaint();
|
||||
doSlide();
|
||||
}
|
||||
|
||||
private void doSlide() {
|
||||
if (optionPane.getParent() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (optionPane.getWidth() == 0) {
|
||||
optionPane.setSize(optionPane.getPreferredSize());
|
||||
}
|
||||
|
||||
int glassPaneWidth = getWidth();
|
||||
if (glassPaneWidth == 0 && getParent() != null) {
|
||||
glassPaneWidth = getParent().getWidth();
|
||||
}
|
||||
|
||||
int x = (glassPaneWidth - optionPane.getWidth()) / 2;
|
||||
|
||||
if (!slideIn) {
|
||||
remove(optionPane);
|
||||
setVisible(false);
|
||||
return;
|
||||
} else {
|
||||
optionPane.setLocation(x, 0);
|
||||
setGrayLevel(fade);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void setGrayLevel(int gray) {
|
||||
gray = gray * 255 / 100;
|
||||
setBackground(new Color(0, 0, 0, gray));
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class SheetOptionPane extends JOptionPane {
|
||||
SheetOptionPane(Object message, int messageType, int optionType,
|
||||
Icon icon, Object[] options, Object initialValue) {
|
||||
super(message, messageType, optionType, icon, options, initialValue);
|
||||
|
||||
setBorder(new CompoundBorder(new LineBorder(new Color(204, 204, 204), 1),
|
||||
new EmptyBorder(4, 4, 4, 4)));
|
||||
}
|
||||
|
||||
|
||||
private static Composite comp =
|
||||
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8F);
|
||||
|
||||
private static Color bgColor = new Color(241, 239, 239);
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
SlideAndFadeGlassPane glassPane = (SlideAndFadeGlassPane)getParent();
|
||||
if (glassPane != null) {
|
||||
if (visible) {
|
||||
glassPane.show(this);
|
||||
} else {
|
||||
glassPane.hide(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
Composite oldComp = g2d.getComposite();
|
||||
g2d.setComposite(comp);
|
||||
Color oldColor = g2d.getColor();
|
||||
g2d.setColor(bgColor);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
g2d.setColor(oldColor);
|
||||
g2d.setComposite(oldComp);
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
374
jdkSrc/jdk8/sun/tools/jconsole/SummaryTab.java
Normal file
374
jdkSrc/jdk8/sun/tools/jconsole/SummaryTab.java
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Formatter.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class SummaryTab extends Tab {
|
||||
private static final String cpuUsageKey = "cpu";
|
||||
|
||||
private static final String newDivider = "<tr><td colspan=4><font size =-1><hr>";
|
||||
private static final String newTable = "<tr><td colspan=4 align=left><table cellpadding=1>";
|
||||
private static final String newLeftTable = "<tr><td colspan=2 align=left><table cellpadding=1>";
|
||||
private static final String newRightTable = "<td colspan=2 align=left><table cellpadding=1>";
|
||||
private static final String endTable = "</table>";
|
||||
|
||||
private static final int CPU_DECIMALS = 1;
|
||||
|
||||
private CPUOverviewPanel overviewPanel;
|
||||
private DateFormat headerDateTimeFormat;
|
||||
private String pathSeparator = null;
|
||||
HTMLPane info;
|
||||
|
||||
private static class Result {
|
||||
long upTime = -1L;
|
||||
long processCpuTime = -1L;
|
||||
long timeStamp;
|
||||
int nCPUs;
|
||||
String summary;
|
||||
}
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.SUMMARY_TAB_TAB_NAME;
|
||||
}
|
||||
|
||||
public SummaryTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
info = new HTMLPane();
|
||||
setAccessibleName(info, getTabName());
|
||||
add(new JScrollPane(info));
|
||||
|
||||
headerDateTimeFormat =
|
||||
Formatter.getDateTimeFormat(Messages.SUMMARY_TAB_HEADER_DATE_TIME_FORMAT);
|
||||
}
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
return new SwingWorker<Result, Object>() {
|
||||
public Result doInBackground() {
|
||||
return formatSummary();
|
||||
}
|
||||
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
Result result = get();
|
||||
if (result != null) {
|
||||
info.setText(result.summary);
|
||||
if (overviewPanel != null &&
|
||||
result.upTime > 0L &&
|
||||
result.processCpuTime >= 0L) {
|
||||
|
||||
overviewPanel.updateCPUInfo(result);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
StringBuilder buf;
|
||||
|
||||
synchronized Result formatSummary() {
|
||||
Result result = new Result();
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
if (proxyClient.isDead()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
buf = new StringBuilder();
|
||||
append("<table cellpadding=1>");
|
||||
|
||||
try {
|
||||
RuntimeMXBean rmBean = proxyClient.getRuntimeMXBean();
|
||||
CompilationMXBean cmpMBean = proxyClient.getCompilationMXBean();
|
||||
ThreadMXBean tmBean = proxyClient.getThreadMXBean();
|
||||
MemoryMXBean memoryBean = proxyClient.getMemoryMXBean();
|
||||
ClassLoadingMXBean clMBean = proxyClient.getClassLoadingMXBean();
|
||||
OperatingSystemMXBean osMBean = proxyClient.getOperatingSystemMXBean();
|
||||
com.sun.management.OperatingSystemMXBean sunOSMBean =
|
||||
proxyClient.getSunOperatingSystemMXBean();
|
||||
|
||||
append("<tr><td colspan=4>");
|
||||
append("<center><b>" + Messages.SUMMARY_TAB_TAB_NAME + "</b></center>");
|
||||
String dateTime =
|
||||
headerDateTimeFormat.format(System.currentTimeMillis());
|
||||
append("<center>" + dateTime + "</center>");
|
||||
|
||||
append(newDivider);
|
||||
|
||||
{ // VM info
|
||||
append(newLeftTable);
|
||||
append(Messages.CONNECTION_NAME, vmPanel.getDisplayName());
|
||||
append(Messages.VIRTUAL_MACHINE,
|
||||
Resources.format(Messages.SUMMARY_TAB_VM_VERSION,
|
||||
rmBean.getVmName(), rmBean.getVmVersion()));
|
||||
append(Messages.VENDOR, rmBean.getVmVendor());
|
||||
append(Messages.NAME, rmBean.getName());
|
||||
append(endTable);
|
||||
|
||||
append(newRightTable);
|
||||
result.upTime = rmBean.getUptime();
|
||||
append(Messages.UPTIME, formatTime(result.upTime));
|
||||
if (sunOSMBean != null) {
|
||||
result.processCpuTime = sunOSMBean.getProcessCpuTime();
|
||||
append(Messages.PROCESS_CPU_TIME, formatNanoTime(result.processCpuTime));
|
||||
}
|
||||
|
||||
if (cmpMBean != null) {
|
||||
append(Messages.JIT_COMPILER, cmpMBean.getName());
|
||||
append(Messages.TOTAL_COMPILE_TIME,
|
||||
cmpMBean.isCompilationTimeMonitoringSupported()
|
||||
? formatTime(cmpMBean.getTotalCompilationTime())
|
||||
: Messages.UNAVAILABLE);
|
||||
} else {
|
||||
append(Messages.JIT_COMPILER, Messages.UNAVAILABLE);
|
||||
}
|
||||
append(endTable);
|
||||
}
|
||||
|
||||
append(newDivider);
|
||||
|
||||
{ // Threads and Classes
|
||||
append(newLeftTable);
|
||||
int tlCount = tmBean.getThreadCount();
|
||||
int tdCount = tmBean.getDaemonThreadCount();
|
||||
int tpCount = tmBean.getPeakThreadCount();
|
||||
long ttCount = tmBean.getTotalStartedThreadCount();
|
||||
String[] strings1 = formatLongs(tlCount, tpCount,
|
||||
tdCount, ttCount);
|
||||
append(Messages.LIVE_THREADS, strings1[0]);
|
||||
append(Messages.PEAK, strings1[1]);
|
||||
append(Messages.DAEMON_THREADS, strings1[2]);
|
||||
append(Messages.TOTAL_THREADS_STARTED, strings1[3]);
|
||||
append(endTable);
|
||||
|
||||
append(newRightTable);
|
||||
long clCount = clMBean.getLoadedClassCount();
|
||||
long cuCount = clMBean.getUnloadedClassCount();
|
||||
long ctCount = clMBean.getTotalLoadedClassCount();
|
||||
String[] strings2 = formatLongs(clCount, cuCount, ctCount);
|
||||
append(Messages.CURRENT_CLASSES_LOADED, strings2[0]);
|
||||
append(Messages.TOTAL_CLASSES_LOADED, strings2[2]);
|
||||
append(Messages.TOTAL_CLASSES_UNLOADED, strings2[1]);
|
||||
append(null, "");
|
||||
append(endTable);
|
||||
}
|
||||
|
||||
append(newDivider);
|
||||
|
||||
{ // Memory
|
||||
MemoryUsage u = memoryBean.getHeapMemoryUsage();
|
||||
|
||||
append(newLeftTable);
|
||||
String[] strings1 = formatKByteStrings(u.getUsed(), u.getMax());
|
||||
append(Messages.CURRENT_HEAP_SIZE, strings1[0]);
|
||||
append(Messages.MAXIMUM_HEAP_SIZE, strings1[1]);
|
||||
append(endTable);
|
||||
|
||||
append(newRightTable);
|
||||
String[] strings2 = formatKByteStrings(u.getCommitted());
|
||||
append(Messages.COMMITTED_MEMORY, strings2[0]);
|
||||
append(Messages.SUMMARY_TAB_PENDING_FINALIZATION_LABEL,
|
||||
Resources.format(Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE,
|
||||
memoryBean.getObjectPendingFinalizationCount()));
|
||||
append(endTable);
|
||||
|
||||
append(newTable);
|
||||
Collection<GarbageCollectorMXBean> garbageCollectors =
|
||||
proxyClient.getGarbageCollectorMXBeans();
|
||||
for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
|
||||
String gcName = garbageCollectorMBean.getName();
|
||||
long gcCount = garbageCollectorMBean.getCollectionCount();
|
||||
long gcTime = garbageCollectorMBean.getCollectionTime();
|
||||
|
||||
append(Messages.GARBAGE_COLLECTOR,
|
||||
Resources.format(Messages.GC_INFO, gcName, gcCount,
|
||||
(gcTime >= 0) ? formatTime(gcTime)
|
||||
: Messages.UNAVAILABLE),
|
||||
4);
|
||||
}
|
||||
append(endTable);
|
||||
}
|
||||
|
||||
append(newDivider);
|
||||
|
||||
{ // Operating System info
|
||||
append(newLeftTable);
|
||||
String osName = osMBean.getName();
|
||||
String osVersion = osMBean.getVersion();
|
||||
String osArch = osMBean.getArch();
|
||||
result.nCPUs = osMBean.getAvailableProcessors();
|
||||
append(Messages.OPERATING_SYSTEM, osName + " " + osVersion);
|
||||
append(Messages.ARCHITECTURE, osArch);
|
||||
append(Messages.NUMBER_OF_PROCESSORS, result.nCPUs+"");
|
||||
|
||||
if (pathSeparator == null) {
|
||||
// Must use separator of remote OS, not File.pathSeparator
|
||||
// from this local VM. In the future, consider using
|
||||
// RuntimeMXBean to get the remote system property.
|
||||
pathSeparator = osName.startsWith("Windows ") ? ";" : ":";
|
||||
}
|
||||
|
||||
if (sunOSMBean != null) {
|
||||
String[] kbStrings1 =
|
||||
formatKByteStrings(sunOSMBean.getCommittedVirtualMemorySize());
|
||||
|
||||
String[] kbStrings2 =
|
||||
formatKByteStrings(sunOSMBean.getTotalPhysicalMemorySize(),
|
||||
sunOSMBean.getFreePhysicalMemorySize(),
|
||||
sunOSMBean.getTotalSwapSpaceSize(),
|
||||
sunOSMBean.getFreeSwapSpaceSize());
|
||||
|
||||
append(Messages.COMMITTED_VIRTUAL_MEMORY, kbStrings1[0]);
|
||||
append(endTable);
|
||||
|
||||
append(newRightTable);
|
||||
append(Messages.TOTAL_PHYSICAL_MEMORY, kbStrings2[0]);
|
||||
append(Messages.FREE_PHYSICAL_MEMORY, kbStrings2[1]);
|
||||
append(Messages.TOTAL_SWAP_SPACE, kbStrings2[2]);
|
||||
append(Messages.FREE_SWAP_SPACE, kbStrings2[3]);
|
||||
}
|
||||
|
||||
append(endTable);
|
||||
}
|
||||
|
||||
append(newDivider);
|
||||
|
||||
{ // VM arguments and paths
|
||||
append(newTable);
|
||||
String args = "";
|
||||
java.util.List<String> inputArguments = rmBean.getInputArguments();
|
||||
for (String arg : inputArguments) {
|
||||
args += arg + " ";
|
||||
}
|
||||
append(Messages.VM_ARGUMENTS, args, 4);
|
||||
append(Messages.CLASS_PATH, rmBean.getClassPath(), 4);
|
||||
append(Messages.LIBRARY_PATH, rmBean.getLibraryPath(), 4);
|
||||
append(Messages.BOOT_CLASS_PATH,
|
||||
rmBean.isBootClassPathSupported()
|
||||
? rmBean.getBootClassPath()
|
||||
: Messages.UNAVAILABLE,
|
||||
4);
|
||||
append(endTable);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
proxyClient.markAsDead();
|
||||
return null;
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
proxyClient.markAsDead();
|
||||
return null;
|
||||
}
|
||||
|
||||
append("</table>");
|
||||
|
||||
result.timeStamp = System.currentTimeMillis();
|
||||
result.summary = buf.toString();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private synchronized void append(String str) {
|
||||
buf.append(str);
|
||||
}
|
||||
|
||||
void append(String label, String value) {
|
||||
append(newRow(label, value));
|
||||
}
|
||||
|
||||
private void append(String label, String value, int columnPerRow) {
|
||||
if (columnPerRow == 4 && pathSeparator != null) {
|
||||
value = value.replace(pathSeparator,
|
||||
"<b></b>" + pathSeparator);
|
||||
}
|
||||
append(newRow(label, value, columnPerRow));
|
||||
}
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new CPUOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
private static class CPUOverviewPanel extends OverviewPanel {
|
||||
private long prevUpTime, prevProcessCpuTime;
|
||||
|
||||
CPUOverviewPanel() {
|
||||
super(Messages.CPU_USAGE, cpuUsageKey, Messages.CPU_USAGE, Plotter.Unit.PERCENT);
|
||||
getPlotter().setDecimals(CPU_DECIMALS);
|
||||
}
|
||||
|
||||
public void updateCPUInfo(Result result) {
|
||||
if (prevUpTime > 0L && result.upTime > prevUpTime) {
|
||||
// elapsedCpu is in ns and elapsedTime is in ms.
|
||||
long elapsedCpu = result.processCpuTime - prevProcessCpuTime;
|
||||
long elapsedTime = result.upTime - prevUpTime;
|
||||
// cpuUsage could go higher than 100% because elapsedTime
|
||||
// and elapsedCpu are not fetched simultaneously. Limit to
|
||||
// 99% to avoid Plotter showing a scale from 0% to 200%.
|
||||
float cpuUsage =
|
||||
Math.min(99F,
|
||||
elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
|
||||
|
||||
cpuUsage = Math.max(0F, cpuUsage);
|
||||
|
||||
getPlotter().addValues(result.timeStamp,
|
||||
Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
|
||||
getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,
|
||||
String.format("%."+CPU_DECIMALS+"f", cpuUsage)));
|
||||
}
|
||||
this.prevUpTime = result.upTime;
|
||||
this.prevProcessCpuTime = result.processCpuTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
94
jdkSrc/jdk8/sun/tools/jconsole/Tab.java
Normal file
94
jdkSrc/jdk8/sun/tools/jconsole/Tab.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public abstract class Tab extends JPanel {
|
||||
private String name;
|
||||
private Worker worker;
|
||||
|
||||
protected VMPanel vmPanel;
|
||||
|
||||
private SwingWorker<?, ?> prevSW;
|
||||
|
||||
public Tab(VMPanel vmPanel, String name) {
|
||||
this.vmPanel = vmPanel;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
final ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
if (!proxyClient.hasPlatformMXBeans()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Platform MXBeans not registered in MBeanServer");
|
||||
}
|
||||
|
||||
SwingWorker<?,?> sw = newSwingWorker();
|
||||
// schedule SwingWorker to run only if the previous
|
||||
// SwingWorker has finished its task and it hasn't started.
|
||||
if (prevSW == null || prevSW.isDone()) {
|
||||
if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) {
|
||||
prevSW = sw;
|
||||
if (sw != null) {
|
||||
sw.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if(worker != null)
|
||||
worker.stopWorker();
|
||||
|
||||
// Subclasses will override to clean up
|
||||
}
|
||||
|
||||
protected VMPanel getVMPanel() {
|
||||
return vmPanel;
|
||||
}
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void workerAdd(Runnable job) {
|
||||
if (worker == null) {
|
||||
worker = new Worker(name+"-"+vmPanel.getConnectionName());
|
||||
worker.start();
|
||||
}
|
||||
worker.add(job);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(700, 500);
|
||||
}
|
||||
}
|
||||
695
jdkSrc/jdk8/sun/tools/jconsole/ThreadTab.java
Normal file
695
jdkSrc/jdk8/sun/tools/jconsole/ThreadTab.java
Normal file
@@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.List;
|
||||
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class ThreadTab extends Tab implements ActionListener, DocumentListener, ListSelectionListener {
|
||||
PlotterPanel threadMeter;
|
||||
TimeComboBox timeComboBox;
|
||||
JTabbedPane threadListTabbedPane;
|
||||
DefaultListModel<Long> listModel;
|
||||
JTextField filterTF;
|
||||
JLabel messageLabel;
|
||||
JSplitPane threadsSplitPane;
|
||||
HashMap<Long, String> nameCache = new HashMap<Long, String>();
|
||||
|
||||
private ThreadOverviewPanel overviewPanel;
|
||||
private boolean plotterListening = false;
|
||||
|
||||
|
||||
private static final String threadCountKey = "threadCount";
|
||||
private static final String peakKey = "peak";
|
||||
|
||||
private static final Color threadCountColor = Plotter.defaultColor;
|
||||
private static final Color peakColor = Color.red;
|
||||
|
||||
private static final Border thinEmptyBorder = new EmptyBorder(2, 2, 2, 2);
|
||||
|
||||
/*
|
||||
Hierarchy of panels and layouts for this tab:
|
||||
|
||||
ThreadTab (BorderLayout)
|
||||
|
||||
North: topPanel (BorderLayout)
|
||||
|
||||
Center: controlPanel (FlowLayout)
|
||||
timeComboBox
|
||||
|
||||
Center: plotterPanel (BorderLayout)
|
||||
|
||||
Center: plotter
|
||||
|
||||
*/
|
||||
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.THREADS;
|
||||
}
|
||||
|
||||
public ThreadTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
JPanel plotterPanel = new JPanel(new VariableGridLayout(0, 1, 4, 4, true, true));
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
add(plotterPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
threadMeter = new PlotterPanel(Messages.NUMBER_OF_THREADS,
|
||||
Plotter.Unit.NONE, true);
|
||||
threadMeter.plotter.createSequence(threadCountKey, Messages.LIVE_THREADS, threadCountColor, true);
|
||||
threadMeter.plotter.createSequence(peakKey, Messages.PEAK, peakColor, true);
|
||||
setAccessibleName(threadMeter.plotter,
|
||||
Messages.THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME);
|
||||
|
||||
plotterPanel.add(threadMeter);
|
||||
|
||||
timeComboBox = new TimeComboBox(threadMeter.plotter);
|
||||
controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox));
|
||||
|
||||
listModel = new DefaultListModel<Long>();
|
||||
|
||||
JTextArea textArea = new JTextArea();
|
||||
textArea.setBorder(thinEmptyBorder);
|
||||
textArea.setEditable(false);
|
||||
setAccessibleName(textArea,
|
||||
Messages.THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME);
|
||||
ThreadJList list = new ThreadJList(listModel, textArea);
|
||||
|
||||
Dimension di = new Dimension(super.getPreferredSize());
|
||||
di.width = Math.min(di.width, 200);
|
||||
|
||||
JScrollPane threadlistSP = new JScrollPane(list);
|
||||
threadlistSP.setPreferredSize(di);
|
||||
threadlistSP.setBorder(null);
|
||||
|
||||
JScrollPane textAreaSP = new JScrollPane(textArea);
|
||||
textAreaSP.setBorder(null);
|
||||
|
||||
threadListTabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
threadsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
||||
threadlistSP, textAreaSP);
|
||||
threadsSplitPane.setOneTouchExpandable(true);
|
||||
threadsSplitPane.setBorder(null);
|
||||
|
||||
JPanel firstTabPanel = new JPanel(new BorderLayout());
|
||||
firstTabPanel.setOpaque(false);
|
||||
|
||||
JPanel firstTabToolPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 2));
|
||||
firstTabToolPanel.setOpaque(false);
|
||||
|
||||
filterTF = new PromptingTextField("Filter", 20);
|
||||
filterTF.getDocument().addDocumentListener(this);
|
||||
firstTabToolPanel.add(filterTF);
|
||||
|
||||
JSeparator separator = new JSeparator(JSeparator.VERTICAL);
|
||||
separator.setPreferredSize(new Dimension(separator.getPreferredSize().width,
|
||||
filterTF.getPreferredSize().height));
|
||||
firstTabToolPanel.add(separator);
|
||||
|
||||
JButton detectDeadlockButton = new JButton(Messages.DETECT_DEADLOCK);
|
||||
detectDeadlockButton.setMnemonic(Resources.getMnemonicInt(Messages.DETECT_DEADLOCK));
|
||||
detectDeadlockButton.setActionCommand("detectDeadlock");
|
||||
detectDeadlockButton.addActionListener(this);
|
||||
detectDeadlockButton.setToolTipText(Messages.DETECT_DEADLOCK_TOOLTIP);
|
||||
firstTabToolPanel.add(detectDeadlockButton);
|
||||
|
||||
messageLabel = new JLabel();
|
||||
firstTabToolPanel.add(messageLabel);
|
||||
|
||||
firstTabPanel.add(threadsSplitPane, BorderLayout.CENTER);
|
||||
firstTabPanel.add(firstTabToolPanel, BorderLayout.SOUTH);
|
||||
threadListTabbedPane.addTab(Messages.THREADS, firstTabPanel);
|
||||
|
||||
plotterPanel.add(threadListTabbedPane);
|
||||
}
|
||||
|
||||
private long oldThreads[] = new long[0];
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
final ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
if (!plotterListening) {
|
||||
proxyClient.addWeakPropertyChangeListener(threadMeter.plotter);
|
||||
plotterListening = true;
|
||||
}
|
||||
|
||||
return new SwingWorker<Boolean, Object>() {
|
||||
private int tlCount;
|
||||
private int tpCount;
|
||||
private long ttCount;
|
||||
private long[] threads;
|
||||
private long timeStamp;
|
||||
|
||||
public Boolean doInBackground() {
|
||||
try {
|
||||
ThreadMXBean threadMBean = proxyClient.getThreadMXBean();
|
||||
|
||||
tlCount = threadMBean.getThreadCount();
|
||||
tpCount = threadMBean.getPeakThreadCount();
|
||||
if (overviewPanel != null) {
|
||||
ttCount = threadMBean.getTotalStartedThreadCount();
|
||||
} else {
|
||||
ttCount = 0L;
|
||||
}
|
||||
|
||||
threads = threadMBean.getAllThreadIds();
|
||||
for (long newThread : threads) {
|
||||
if (nameCache.get(newThread) == null) {
|
||||
ThreadInfo ti = threadMBean.getThreadInfo(newThread);
|
||||
if (ti != null) {
|
||||
String name = ti.getThreadName();
|
||||
if (name != null) {
|
||||
nameCache.put(newThread, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timeStamp = System.currentTimeMillis();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
if (!get()) {
|
||||
return;
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
return;
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
threadMeter.plotter.addValues(timeStamp, tlCount, tpCount);
|
||||
threadMeter.setValueLabel(tlCount+"");
|
||||
|
||||
if (overviewPanel != null) {
|
||||
overviewPanel.updateThreadsInfo(tlCount, tpCount, ttCount, timeStamp);
|
||||
}
|
||||
|
||||
String filter = filterTF.getText().toLowerCase(Locale.ENGLISH);
|
||||
boolean doFilter = (filter.length() > 0);
|
||||
|
||||
ArrayList<Long> l = new ArrayList<Long>();
|
||||
for (long t : threads) {
|
||||
l.add(t);
|
||||
}
|
||||
Iterator<Long> iterator = l.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
long newThread = iterator.next();
|
||||
String name = nameCache.get(newThread);
|
||||
if (doFilter && name != null &&
|
||||
name.toLowerCase(Locale.ENGLISH).indexOf(filter) < 0) {
|
||||
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
long[] newThreads = threads;
|
||||
if (l.size() < threads.length) {
|
||||
newThreads = new long[l.size()];
|
||||
for (int i = 0; i < newThreads.length; i++) {
|
||||
newThreads[i] = l.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (long oldThread : oldThreads) {
|
||||
boolean found = false;
|
||||
for (long newThread : newThreads) {
|
||||
if (newThread == oldThread) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
listModel.removeElement(oldThread);
|
||||
if (!doFilter) {
|
||||
nameCache.remove(oldThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Threads are in reverse chronological order
|
||||
for (int i = newThreads.length - 1; i >= 0; i--) {
|
||||
long newThread = newThreads[i];
|
||||
boolean found = false;
|
||||
for (long oldThread : oldThreads) {
|
||||
if (newThread == oldThread) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
listModel.addElement(newThread);
|
||||
}
|
||||
}
|
||||
oldThreads = newThreads;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
long lastSelected = -1;
|
||||
|
||||
public void valueChanged(ListSelectionEvent ev) {
|
||||
ThreadJList list = (ThreadJList)ev.getSource();
|
||||
final JTextArea textArea = list.textArea;
|
||||
|
||||
Long selected = (Long)list.getSelectedValue();
|
||||
if (selected == null) {
|
||||
if (lastSelected != -1) {
|
||||
selected = lastSelected;
|
||||
}
|
||||
} else {
|
||||
lastSelected = selected;
|
||||
}
|
||||
textArea.setText("");
|
||||
if (selected != null) {
|
||||
final long threadID = selected;
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
ThreadMXBean threadMBean = proxyClient.getThreadMXBean();
|
||||
ThreadInfo ti = null;
|
||||
MonitorInfo[] monitors = null;
|
||||
if (proxyClient.isLockUsageSupported() &&
|
||||
threadMBean.isObjectMonitorUsageSupported()) {
|
||||
// VMs that support the monitor usage monitoring
|
||||
ThreadInfo[] infos = threadMBean.dumpAllThreads(true, false);
|
||||
for (ThreadInfo info : infos) {
|
||||
if (info.getThreadId() == threadID) {
|
||||
ti = info;
|
||||
monitors = info.getLockedMonitors();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// VM doesn't support monitor usage monitoring
|
||||
ti = threadMBean.getThreadInfo(threadID, Integer.MAX_VALUE);
|
||||
}
|
||||
if (ti != null) {
|
||||
if (ti.getLockName() == null) {
|
||||
sb.append(Resources.format(Messages.NAME_STATE,
|
||||
ti.getThreadName(),
|
||||
ti.getThreadState().toString()));
|
||||
} else if (ti.getLockOwnerName() == null) {
|
||||
sb.append(Resources.format(Messages.NAME_STATE_LOCK_NAME,
|
||||
ti.getThreadName(),
|
||||
ti.getThreadState().toString(),
|
||||
ti.getLockName()));
|
||||
} else {
|
||||
sb.append(Resources.format(Messages.NAME_STATE_LOCK_NAME_LOCK_OWNER,
|
||||
ti.getThreadName(),
|
||||
ti.getThreadState().toString(),
|
||||
ti.getLockName(),
|
||||
ti.getLockOwnerName()));
|
||||
}
|
||||
sb.append(Resources.format(Messages.BLOCKED_COUNT_WAITED_COUNT,
|
||||
ti.getBlockedCount(),
|
||||
ti.getWaitedCount()));
|
||||
sb.append(Messages.STACK_TRACE);
|
||||
int index = 0;
|
||||
for (StackTraceElement e : ti.getStackTrace()) {
|
||||
sb.append(e.toString()+"\n");
|
||||
if (monitors != null) {
|
||||
for (MonitorInfo mi : monitors) {
|
||||
if (mi.getLockedStackDepth() == index) {
|
||||
sb.append(Resources.format(Messages.MONITOR_LOCKED, mi.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
}
|
||||
final String text = sb.toString();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
textArea.setText(text);
|
||||
textArea.setCaretPosition(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void doUpdate() {
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void detectDeadlock() {
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final Long[][] deadlockedThreads = getDeadlockedThreadIds();
|
||||
|
||||
if (deadlockedThreads == null || deadlockedThreads.length == 0) {
|
||||
// Display message for 30 seconds. Do it on a separate thread so
|
||||
// the sleep won't hold up the worker queue.
|
||||
// This will be replaced later by separate statusbar logic.
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
String msg = Messages.NO_DEADLOCK_DETECTED;
|
||||
messageLabel.setText(msg);
|
||||
threadListTabbedPane.revalidate();
|
||||
}
|
||||
});
|
||||
sleep(30 * 1000);
|
||||
} catch (InterruptedException ex) {
|
||||
// Ignore
|
||||
} catch (InvocationTargetException ex) {
|
||||
// Ignore
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
messageLabel.setText("");
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
return;
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
// Remove old deadlock tabs
|
||||
while (threadListTabbedPane.getTabCount() > 1) {
|
||||
threadListTabbedPane.removeTabAt(1);
|
||||
}
|
||||
|
||||
if (deadlockedThreads != null) {
|
||||
for (int i = 0; i < deadlockedThreads.length; i++) {
|
||||
DefaultListModel<Long> listModel = new DefaultListModel<Long>();
|
||||
JTextArea textArea = new JTextArea();
|
||||
textArea.setBorder(thinEmptyBorder);
|
||||
textArea.setEditable(false);
|
||||
setAccessibleName(textArea,
|
||||
Messages.THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME);
|
||||
ThreadJList list = new ThreadJList(listModel, textArea);
|
||||
JScrollPane threadlistSP = new JScrollPane(list);
|
||||
JScrollPane textAreaSP = new JScrollPane(textArea);
|
||||
threadlistSP.setBorder(null);
|
||||
textAreaSP.setBorder(null);
|
||||
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
||||
threadlistSP, textAreaSP);
|
||||
splitPane.setOneTouchExpandable(true);
|
||||
splitPane.setBorder(null);
|
||||
splitPane.setDividerLocation(threadsSplitPane.getDividerLocation());
|
||||
String tabName;
|
||||
if (deadlockedThreads.length > 1) {
|
||||
tabName = Resources.format(Messages.DEADLOCK_TAB_N, i+1);
|
||||
} else {
|
||||
tabName = Messages.DEADLOCK_TAB;
|
||||
}
|
||||
threadListTabbedPane.addTab(tabName, splitPane);
|
||||
|
||||
for (long t : deadlockedThreads[i]) {
|
||||
listModel.addElement(t);
|
||||
}
|
||||
}
|
||||
threadListTabbedPane.setSelectedIndex(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Return deadlocked threads or null
|
||||
public Long[][] getDeadlockedThreadIds() throws IOException {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
ThreadMXBean threadMBean = proxyClient.getThreadMXBean();
|
||||
|
||||
long[] ids = proxyClient.findDeadlockedThreads();
|
||||
if (ids == null) {
|
||||
return null;
|
||||
}
|
||||
ThreadInfo[] infos = threadMBean.getThreadInfo(ids, Integer.MAX_VALUE);
|
||||
|
||||
List<Long[]> dcycles = new ArrayList<Long[]>();
|
||||
List<Long> cycle = new ArrayList<Long>();
|
||||
|
||||
// keep track of which thread is visited
|
||||
// one thread can only be in one cycle
|
||||
boolean[] visited = new boolean[ids.length];
|
||||
|
||||
int deadlockedThread = -1; // Index into arrays
|
||||
while (true) {
|
||||
if (deadlockedThread < 0) {
|
||||
if (cycle.size() > 0) {
|
||||
// a cycle found
|
||||
dcycles.add(cycle.toArray(new Long[0]));
|
||||
cycle = new ArrayList<Long>();
|
||||
}
|
||||
// start a new cycle from a non-visited thread
|
||||
for (int j = 0; j < ids.length; j++) {
|
||||
if (!visited[j]) {
|
||||
deadlockedThread = j;
|
||||
visited[j] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deadlockedThread < 0) {
|
||||
// done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cycle.add(ids[deadlockedThread]);
|
||||
long nextThreadId = infos[deadlockedThread].getLockOwnerId();
|
||||
for (int j = 0; j < ids.length; j++) {
|
||||
ThreadInfo ti = infos[j];
|
||||
if (ti.getThreadId() == nextThreadId) {
|
||||
if (visited[j]) {
|
||||
deadlockedThread = -1;
|
||||
} else {
|
||||
deadlockedThread = j;
|
||||
visited[j] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dcycles.toArray(new Long[0][0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ActionListener interface
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
String cmd = ((AbstractButton)evt.getSource()).getActionCommand();
|
||||
|
||||
if (cmd == "detectDeadlock") {
|
||||
messageLabel.setText("");
|
||||
detectDeadlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// DocumentListener interface
|
||||
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
doUpdate();
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
doUpdate();
|
||||
}
|
||||
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
doUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class ThreadJList extends JList<Long> {
|
||||
private JTextArea textArea;
|
||||
|
||||
ThreadJList(DefaultListModel<Long> listModel, JTextArea textArea) {
|
||||
super(listModel);
|
||||
|
||||
this.textArea = textArea;
|
||||
|
||||
setBorder(thinEmptyBorder);
|
||||
|
||||
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
textArea.setText(Messages.THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE);
|
||||
addListSelectionListener(ThreadTab.this);
|
||||
setCellRenderer(new DefaultListCellRenderer() {
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
|
||||
if (value != null) {
|
||||
String name = nameCache.get(value);
|
||||
if (name == null) {
|
||||
name = value.toString();
|
||||
}
|
||||
setText(name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension d = super.getPreferredSize();
|
||||
d.width = Math.max(d.width, 100);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
private class PromptingTextField extends JTextField implements FocusListener {
|
||||
private String prompt;
|
||||
boolean promptRemoved = false;
|
||||
Color fg;
|
||||
|
||||
public PromptingTextField(String prompt, int columns) {
|
||||
super(prompt, columns);
|
||||
|
||||
this.prompt = prompt;
|
||||
updateForeground();
|
||||
addFocusListener(this);
|
||||
setAccessibleName(this, prompt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revalidate() {
|
||||
super.revalidate();
|
||||
updateForeground();
|
||||
}
|
||||
|
||||
private void updateForeground() {
|
||||
this.fg = UIManager.getColor("TextField.foreground");
|
||||
if (promptRemoved) {
|
||||
setForeground(fg);
|
||||
} else {
|
||||
setForeground(Color.gray);
|
||||
}
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
if (!promptRemoved) {
|
||||
return "";
|
||||
} else {
|
||||
return super.getText();
|
||||
}
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (!promptRemoved) {
|
||||
setText("");
|
||||
setForeground(fg);
|
||||
promptRemoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (promptRemoved && getText().equals("")) {
|
||||
setText(prompt);
|
||||
setForeground(Color.gray);
|
||||
promptRemoved = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new ThreadOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
|
||||
private static class ThreadOverviewPanel extends OverviewPanel {
|
||||
ThreadOverviewPanel() {
|
||||
super(Messages.THREADS, threadCountKey, Messages.LIVE_THREADS, null);
|
||||
}
|
||||
|
||||
private void updateThreadsInfo(long tlCount, long tpCount, long ttCount, long timeStamp) {
|
||||
getPlotter().addValues(timeStamp, tlCount);
|
||||
getInfoLabel().setText(Resources.format(Messages.THREAD_TAB_INFO_LABEL_FORMAT, tlCount, tpCount, ttCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
91
jdkSrc/jdk8/sun/tools/jconsole/TimeComboBox.java
Normal file
91
jdkSrc/jdk8/sun/tools/jconsole/TimeComboBox.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2006, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* A combo box to control the visible time range for one or more Plotter components.
|
||||
* When used with two or more Plotters, it also acts to coordinate the range between
|
||||
* them.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class TimeComboBox extends JComboBox implements ItemListener, PropertyChangeListener {
|
||||
private ArrayList<Plotter> plotters = new ArrayList<Plotter>();
|
||||
|
||||
public TimeComboBox(Plotter... plotterArray) {
|
||||
super(Plotter.rangeNames);
|
||||
|
||||
addItemListener(this);
|
||||
|
||||
if (plotterArray != null && plotterArray.length > 0) {
|
||||
plotters.addAll(Arrays.asList(plotterArray));
|
||||
selectValue(plotterArray[0].getViewRange());
|
||||
for (Plotter plotter : plotters) {
|
||||
plotter.addPropertyChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlotter(Plotter plotter) {
|
||||
plotters.add(plotter);
|
||||
if (plotters.size() == 1) {
|
||||
selectValue(plotter.getViewRange());
|
||||
}
|
||||
plotter.addPropertyChangeListener(this);
|
||||
}
|
||||
|
||||
public void itemStateChanged(ItemEvent ev) {
|
||||
for (Plotter plotter : plotters) {
|
||||
plotter.setViewRange(Plotter.rangeValues[getSelectedIndex()]);
|
||||
}
|
||||
}
|
||||
|
||||
private void selectValue(int value) {
|
||||
// Set the selected value
|
||||
for (int i = 0; i < Plotter.rangeValues.length; i++) {
|
||||
if (Plotter.rangeValues[i] == value) {
|
||||
setSelectedItem(Plotter.rangeNames[i]);
|
||||
}
|
||||
}
|
||||
// Make sure all plotters show this value
|
||||
if (plotters.size() > 1) {
|
||||
for (Plotter plotter : plotters) {
|
||||
plotter.setViewRange(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent ev) {
|
||||
if (ev.getPropertyName() == "viewRange") {
|
||||
selectValue((Integer)ev.getNewValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
166
jdkSrc/jdk8/sun/tools/jconsole/Utilities.java
Normal file
166
jdkSrc/jdk8/sun/tools/jconsole/Utilities.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.tree.*;
|
||||
|
||||
import sun.tools.jconsole.inspector.*;
|
||||
|
||||
import static java.lang.Math.*;
|
||||
|
||||
/**
|
||||
* Miscellaneous utility methods for JConsole
|
||||
*/
|
||||
public class Utilities {
|
||||
private static final String windowsLaF =
|
||||
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
|
||||
|
||||
public static void updateTransparency(JComponent comp) {
|
||||
LookAndFeel laf = UIManager.getLookAndFeel();
|
||||
boolean transparent = laf.getClass().getName().equals(windowsLaF);
|
||||
setTabbedPaneTransparency(comp, transparent);
|
||||
}
|
||||
|
||||
private static void setTabbedPaneTransparency(JComponent comp, boolean transparent) {
|
||||
for (Component child : comp.getComponents()) {
|
||||
if (comp instanceof JTabbedPane) {
|
||||
setTransparency((JComponent)child, transparent);
|
||||
} else if (child instanceof JComponent) {
|
||||
setTabbedPaneTransparency((JComponent)child, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setTransparency(JComponent comp, boolean transparent) {
|
||||
comp.setOpaque(!transparent);
|
||||
for (Component child : comp.getComponents()) {
|
||||
if (child instanceof JPanel ||
|
||||
child instanceof JSplitPane ||
|
||||
child instanceof JScrollPane ||
|
||||
child instanceof JViewport ||
|
||||
child instanceof JCheckBox) {
|
||||
|
||||
setTransparency((JComponent)child, transparent);
|
||||
}
|
||||
if (child instanceof XTree) {
|
||||
XTree t = (XTree)child;
|
||||
DefaultTreeCellRenderer cr = (DefaultTreeCellRenderer)t.getCellRenderer();
|
||||
|
||||
cr.setBackground(null);
|
||||
cr.setBackgroundNonSelectionColor(new Color(0, 0, 0, 1));
|
||||
t.setCellRenderer(cr);
|
||||
setTransparency((JComponent)child, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A slightly modified border for JScrollPane to be used with a JTable inside
|
||||
* a JTabbedPane. It has only top part and the rest is clipped to make the
|
||||
* overall border less thick.
|
||||
* The top border helps differentiating the containing table from its container.
|
||||
*/
|
||||
public static JScrollPane newTableScrollPane(JComponent comp) {
|
||||
return new TableScrollPane(comp);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class TableScrollPane extends JScrollPane {
|
||||
public TableScrollPane(JComponent comp) {
|
||||
super(comp);
|
||||
}
|
||||
|
||||
protected void paintBorder(Graphics g) {
|
||||
Border border = getBorder();
|
||||
if (border != null) {
|
||||
Insets insets = border.getBorderInsets(this);
|
||||
if (insets != null) {
|
||||
Shape oldClip = g.getClip();
|
||||
g.clipRect(0, 0, getWidth(), insets.top);
|
||||
super.paintBorder(g);
|
||||
g.setClip(oldClip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAccessibleName(Accessible comp, String name) {
|
||||
comp.getAccessibleContext().setAccessibleName(name);
|
||||
}
|
||||
|
||||
public static void setAccessibleDescription(Accessible comp, String description) {
|
||||
comp.getAccessibleContext().setAccessibleDescription(description);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modifies color c1 to ensure it has acceptable contrast
|
||||
* relative to color c2.
|
||||
*
|
||||
* http://www.w3.org/TR/AERT#color-contrast
|
||||
* http://www.cs.rit.edu/~ncs/color/t_convert.html#RGB%20to%20YIQ%20&%20YIQ%20to%20RGB
|
||||
*/
|
||||
public static Color ensureContrast(Color c1, Color c2) {
|
||||
double y1 = getColorBrightness(c1);
|
||||
double y2 = getColorBrightness(c2);
|
||||
|
||||
if (abs(y1 - y2) < 125.0) {
|
||||
if (y2 < 128.0) {
|
||||
c1 = setColorBrightness(c1, y2 + 125.0);
|
||||
} else {
|
||||
c1 = setColorBrightness(c1, y2 - 125.0);
|
||||
}
|
||||
}
|
||||
|
||||
return c1;
|
||||
}
|
||||
|
||||
public static double getColorBrightness(Color c) {
|
||||
// Convert RGB -> YIQ and return the Y value
|
||||
return (c.getRed() * 0.299 + c.getGreen() * 0.587 + c.getBlue() * 0.114);
|
||||
}
|
||||
|
||||
private static Color setColorBrightness(Color c, double y) {
|
||||
// Convert YIQ -> RGB
|
||||
double i = (c.getRed() * 0.596 - c.getGreen() * 0.275 - c.getBlue() * 0.321);
|
||||
double q = (c.getRed() * 0.212 - c.getGreen() * 0.523 + c.getBlue() * 0.311);
|
||||
|
||||
// Keep values in legal range. This may reduce the
|
||||
// achieved contrast somewhat.
|
||||
int r = max(0, min(255, (int)round(y + i * 0.956 + q * 0.621)));
|
||||
int g = max(0, min(255, (int)round(y - i * 0.272 - q * 0.647)));
|
||||
int b = max(0, min(255, (int)round(y - i * 1.105 + q * 1.702)));
|
||||
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
}
|
||||
65
jdkSrc/jdk8/sun/tools/jconsole/VMInternalFrame.java
Normal file
65
jdkSrc/jdk8/sun/tools/jconsole/VMInternalFrame.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class VMInternalFrame extends MaximizableInternalFrame {
|
||||
private VMPanel vmPanel;
|
||||
|
||||
public VMInternalFrame(VMPanel vmPanel) {
|
||||
super("", true, true, true, true);
|
||||
|
||||
this.vmPanel = vmPanel;
|
||||
setAccessibleDescription(this,
|
||||
Messages.VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION);
|
||||
getContentPane().add(vmPanel, BorderLayout.CENTER);
|
||||
pack();
|
||||
vmPanel.updateFrameTitle();
|
||||
}
|
||||
|
||||
public VMPanel getVMPanel() {
|
||||
return vmPanel;
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension d = super.getPreferredSize();
|
||||
JDesktopPane desktop = getDesktopPane();
|
||||
if (desktop != null) {
|
||||
Dimension desktopSize = desktop.getSize();
|
||||
if (desktopSize.width > 0 && desktopSize.height > 0) {
|
||||
d.width = Math.min(desktopSize.width - 40, d.width);
|
||||
d.height = Math.min(desktopSize.height - 40, d.height);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
668
jdkSrc/jdk8/sun/tools/jconsole/VMPanel.java
Normal file
668
jdkSrc/jdk8/sun/tools/jconsole/VMPanel.java
Normal file
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
|
||||
|
||||
import com.sun.tools.jconsole.JConsolePlugin;
|
||||
import com.sun.tools.jconsole.JConsoleContext;
|
||||
|
||||
import static sun.tools.jconsole.ProxyClient.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class VMPanel extends JTabbedPane implements PropertyChangeListener {
|
||||
|
||||
private ProxyClient proxyClient;
|
||||
private Timer timer;
|
||||
private int updateInterval;
|
||||
private String hostName;
|
||||
private int port;
|
||||
private String userName;
|
||||
private String password;
|
||||
private String url;
|
||||
private VMInternalFrame vmIF = null;
|
||||
private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>();
|
||||
private boolean wasConnected = false;
|
||||
private boolean userDisconnected = false;
|
||||
private boolean shouldUseSSL = true;
|
||||
|
||||
// The everConnected flag keeps track of whether the window can be
|
||||
// closed if the user clicks Cancel after a failed connection attempt.
|
||||
//
|
||||
private boolean everConnected = false;
|
||||
|
||||
// The initialUpdate flag is used to enable/disable tabs each time
|
||||
// a connect or reconnect takes place. This flag avoids having to
|
||||
// enable/disable tabs on each update call.
|
||||
//
|
||||
private boolean initialUpdate = true;
|
||||
|
||||
// Each VMPanel has its own instance of the JConsolePlugin
|
||||
// A map of JConsolePlugin to the previous SwingWorker
|
||||
private Map<ExceptionSafePlugin, SwingWorker<?, ?>> plugins = null;
|
||||
private boolean pluginTabsAdded = false;
|
||||
|
||||
// Update these only on the EDT
|
||||
private JOptionPane optionPane;
|
||||
private JProgressBar progressBar;
|
||||
private long time0;
|
||||
|
||||
static {
|
||||
tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true));
|
||||
tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true));
|
||||
tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true));
|
||||
tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true));
|
||||
tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true));
|
||||
tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true));
|
||||
}
|
||||
|
||||
public static TabInfo[] getTabInfos() {
|
||||
return tabInfos.toArray(new TabInfo[tabInfos.size()]);
|
||||
}
|
||||
|
||||
VMPanel(ProxyClient proxyClient, int updateInterval) {
|
||||
this.proxyClient = proxyClient;
|
||||
this.updateInterval = updateInterval;
|
||||
this.hostName = proxyClient.getHostName();
|
||||
this.port = proxyClient.getPort();
|
||||
this.userName = proxyClient.getUserName();
|
||||
this.password = proxyClient.getPassword();
|
||||
this.url = proxyClient.getUrl();
|
||||
|
||||
for (TabInfo tabInfo : tabInfos) {
|
||||
if (tabInfo.tabVisible) {
|
||||
addTab(tabInfo);
|
||||
}
|
||||
}
|
||||
|
||||
plugins = new LinkedHashMap<ExceptionSafePlugin, SwingWorker<?, ?>>();
|
||||
for (JConsolePlugin p : JConsole.getPlugins()) {
|
||||
p.setContext(proxyClient);
|
||||
plugins.put(new ExceptionSafePlugin(p), null);
|
||||
}
|
||||
|
||||
Utilities.updateTransparency(this);
|
||||
|
||||
ToolTipManager.sharedInstance().registerComponent(this);
|
||||
|
||||
// Start listening to connection state events
|
||||
//
|
||||
proxyClient.addPropertyChangeListener(this);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) {
|
||||
|
||||
if (isConnected()) {
|
||||
userDisconnected = true;
|
||||
disconnect();
|
||||
wasConnected = false;
|
||||
} else {
|
||||
connect();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
private static Icon connectedIcon16 =
|
||||
new ImageIcon(VMPanel.class.getResource("resources/connected16.png"));
|
||||
private static Icon connectedIcon24 =
|
||||
new ImageIcon(VMPanel.class.getResource("resources/connected24.png"));
|
||||
private static Icon disconnectedIcon16 =
|
||||
new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png"));
|
||||
private static Icon disconnectedIcon24 =
|
||||
new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png"));
|
||||
private Rectangle connectedIconBounds;
|
||||
|
||||
// Override to increase right inset for tab area,
|
||||
// in order to reserve space for the connect toggle.
|
||||
public void setUI(TabbedPaneUI ui) {
|
||||
Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
|
||||
if (insets != null) {
|
||||
insets = (Insets) insets.clone();
|
||||
insets.right += connectedIcon24.getIconWidth() + 8;
|
||||
UIManager.put("TabbedPane.tabAreaInsets", insets);
|
||||
}
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
// Override to paint the connect toggle
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
Icon icon;
|
||||
Component c0 = getComponent(0);
|
||||
if (c0 != null && c0.getY() > 24) {
|
||||
icon = isConnected() ? connectedIcon24 : disconnectedIcon24;
|
||||
} else {
|
||||
icon = isConnected() ? connectedIcon16 : disconnectedIcon16;
|
||||
}
|
||||
Insets insets = getInsets();
|
||||
int x = getWidth() - insets.right - icon.getIconWidth() - 4;
|
||||
int y = insets.top;
|
||||
if (c0 != null) {
|
||||
y = (c0.getY() - icon.getIconHeight()) / 2;
|
||||
}
|
||||
icon.paintIcon(this, g, x, y);
|
||||
connectedIconBounds = new Rectangle(x, y, icon.getIconWidth(), icon.getIconHeight());
|
||||
}
|
||||
|
||||
public String getToolTipText(MouseEvent event) {
|
||||
if (connectedIconBounds.contains(event.getPoint())) {
|
||||
if (isConnected()) {
|
||||
return Messages.CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
|
||||
} else {
|
||||
return Messages.DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
|
||||
}
|
||||
} else {
|
||||
return super.getToolTipText(event);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void addTab(TabInfo tabInfo) {
|
||||
Tab tab = instantiate(tabInfo);
|
||||
if (tab != null) {
|
||||
addTab(tabInfo.name, tab);
|
||||
} else {
|
||||
tabInfo.tabVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void insertTab(TabInfo tabInfo, int index) {
|
||||
Tab tab = instantiate(tabInfo);
|
||||
if (tab != null) {
|
||||
insertTab(tabInfo.name, null, tab, null, index);
|
||||
} else {
|
||||
tabInfo.tabVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeTabAt(int index) {
|
||||
super.removeTabAt(index);
|
||||
}
|
||||
|
||||
private Tab instantiate(TabInfo tabInfo) {
|
||||
try {
|
||||
Constructor<?> con = tabInfo.tabClass.getConstructor(VMPanel.class);
|
||||
return (Tab) con.newInstance(this);
|
||||
} catch (Exception ex) {
|
||||
System.err.println(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isConnected() {
|
||||
return proxyClient.isConnected();
|
||||
}
|
||||
|
||||
public int getUpdateInterval() {
|
||||
return updateInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING NEVER CALL THIS METHOD TO MAKE JMX REQUEST
|
||||
* IF assertThread == false.
|
||||
* DISPATCHER THREAD IS NOT ASSERTED.
|
||||
* IT IS USED TO MAKE SOME LOCAL MANIPULATIONS.
|
||||
*/
|
||||
ProxyClient getProxyClient(boolean assertThread) {
|
||||
if (assertThread) {
|
||||
return getProxyClient();
|
||||
} else {
|
||||
return proxyClient;
|
||||
}
|
||||
}
|
||||
|
||||
public ProxyClient getProxyClient() {
|
||||
String threadClass = Thread.currentThread().getClass().getName();
|
||||
if (threadClass.equals("java.awt.EventDispatchThread")) {
|
||||
String msg = "Calling VMPanel.getProxyClient() from the Event Dispatch Thread!";
|
||||
new RuntimeException(msg).printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return proxyClient;
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
//proxyClient.disconnect();
|
||||
for (Tab tab : getTabs()) {
|
||||
tab.dispose();
|
||||
}
|
||||
for (JConsolePlugin p : plugins.keySet()) {
|
||||
p.dispose();
|
||||
}
|
||||
// Cancel pending update tasks
|
||||
//
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
}
|
||||
// Stop listening to connection state events
|
||||
//
|
||||
proxyClient.removePropertyChangeListener(this);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void connect() {
|
||||
if (isConnected()) {
|
||||
// create plugin tabs if not done
|
||||
createPluginTabs();
|
||||
// Notify tabs
|
||||
fireConnectedChange(true);
|
||||
// Enable/disable tabs on initial update
|
||||
initialUpdate = true;
|
||||
// Start/Restart update timer on connect/reconnect
|
||||
startUpdateTimer();
|
||||
} else {
|
||||
new Thread("VMPanel.connect") {
|
||||
|
||||
public void run() {
|
||||
proxyClient.connect(shouldUseSSL);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void disconnect() {
|
||||
proxyClient.disconnect();
|
||||
updateFrameTitle();
|
||||
}
|
||||
|
||||
// Called on EDT
|
||||
public void propertyChange(PropertyChangeEvent ev) {
|
||||
String prop = ev.getPropertyName();
|
||||
|
||||
if (prop == CONNECTION_STATE_PROPERTY) {
|
||||
ConnectionState oldState = (ConnectionState) ev.getOldValue();
|
||||
ConnectionState newState = (ConnectionState) ev.getNewValue();
|
||||
switch (newState) {
|
||||
case CONNECTING:
|
||||
onConnecting();
|
||||
break;
|
||||
|
||||
case CONNECTED:
|
||||
if (progressBar != null) {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setValue(100);
|
||||
}
|
||||
closeOptionPane();
|
||||
updateFrameTitle();
|
||||
// create tabs if not done
|
||||
createPluginTabs();
|
||||
repaint();
|
||||
// Notify tabs
|
||||
fireConnectedChange(true);
|
||||
// Enable/disable tabs on initial update
|
||||
initialUpdate = true;
|
||||
// Start/Restart update timer on connect/reconnect
|
||||
startUpdateTimer();
|
||||
break;
|
||||
|
||||
case DISCONNECTED:
|
||||
if (progressBar != null) {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setValue(0);
|
||||
closeOptionPane();
|
||||
}
|
||||
vmPanelDied();
|
||||
if (oldState == ConnectionState.CONNECTED) {
|
||||
// Notify tabs
|
||||
fireConnectedChange(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called on EDT
|
||||
private void onConnecting() {
|
||||
time0 = System.currentTimeMillis();
|
||||
|
||||
SwingUtilities.getWindowAncestor(this);
|
||||
|
||||
String connectionName = getConnectionName();
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setIndeterminate(true);
|
||||
JPanel progressPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
progressPanel.add(progressBar);
|
||||
|
||||
Object[] message = {
|
||||
"<html><h3>" + Resources.format(Messages.CONNECTING_TO1, connectionName) + "</h3></html>",
|
||||
progressPanel,
|
||||
"<html><b>" + Resources.format(Messages.CONNECTING_TO2, connectionName) + "</b></html>"
|
||||
};
|
||||
|
||||
optionPane =
|
||||
SheetDialog.showOptionDialog(this,
|
||||
message,
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.INFORMATION_MESSAGE, null,
|
||||
new String[]{Messages.CANCEL},
|
||||
0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Called on EDT
|
||||
private void closeOptionPane() {
|
||||
if (optionPane != null) {
|
||||
new Thread("VMPanel.sleeper") {
|
||||
public void run() {
|
||||
long elapsed = System.currentTimeMillis() - time0;
|
||||
if (elapsed < 2000) {
|
||||
try {
|
||||
sleep(2000 - elapsed);
|
||||
} catch (InterruptedException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
optionPane.setVisible(false);
|
||||
progressBar = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
void updateFrameTitle() {
|
||||
VMInternalFrame vmIF = getFrame();
|
||||
if (vmIF != null) {
|
||||
String displayName = getDisplayName();
|
||||
if (!proxyClient.isConnected()) {
|
||||
displayName = Resources.format(Messages.CONNECTION_NAME__DISCONNECTED_, displayName);
|
||||
}
|
||||
vmIF.setTitle(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
private VMInternalFrame getFrame() {
|
||||
if (vmIF == null) {
|
||||
vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class,
|
||||
this);
|
||||
}
|
||||
return vmIF;
|
||||
}
|
||||
|
||||
// TODO: this method is not needed when all JConsole tabs
|
||||
// are migrated to use the new JConsolePlugin API.
|
||||
//
|
||||
// A thread safe clone of all JConsole tabs
|
||||
synchronized List<Tab> getTabs() {
|
||||
ArrayList<Tab> list = new ArrayList<Tab>();
|
||||
int n = getTabCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Component c = getComponentAt(i);
|
||||
if (c instanceof Tab) {
|
||||
list.add((Tab) c);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void startUpdateTimer() {
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
}
|
||||
TimerTask timerTask = new TimerTask() {
|
||||
|
||||
public void run() {
|
||||
update();
|
||||
}
|
||||
};
|
||||
String timerName = "Timer-" + getConnectionName();
|
||||
timer = new Timer(timerName, true);
|
||||
timer.schedule(timerTask, 0, updateInterval);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void vmPanelDied() {
|
||||
disconnect();
|
||||
|
||||
if (userDisconnected) {
|
||||
userDisconnected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
JOptionPane optionPane;
|
||||
String msgTitle, msgExplanation, buttonStr;
|
||||
|
||||
if (wasConnected) {
|
||||
wasConnected = false;
|
||||
msgTitle = Messages.CONNECTION_LOST1;
|
||||
msgExplanation = Resources.format(Messages.CONNECTING_TO2, getConnectionName());
|
||||
buttonStr = Messages.RECONNECT;
|
||||
} else if (shouldUseSSL) {
|
||||
msgTitle = Messages.CONNECTION_FAILED_SSL1;
|
||||
msgExplanation = Resources.format(Messages.CONNECTION_FAILED_SSL2, getConnectionName());
|
||||
buttonStr = Messages.INSECURE;
|
||||
} else {
|
||||
msgTitle = Messages.CONNECTION_FAILED1;
|
||||
msgExplanation = Resources.format(Messages.CONNECTION_FAILED2, getConnectionName());
|
||||
buttonStr = Messages.CONNECT;
|
||||
}
|
||||
|
||||
optionPane =
|
||||
SheetDialog.showOptionDialog(this,
|
||||
"<html><h3>" + msgTitle + "</h3>" +
|
||||
"<b>" + msgExplanation + "</b>",
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE, null,
|
||||
new String[]{buttonStr, Messages.CANCEL},
|
||||
0);
|
||||
|
||||
optionPane.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
|
||||
Object value = event.getNewValue();
|
||||
|
||||
if (value == Messages.RECONNECT || value == Messages.CONNECT) {
|
||||
connect();
|
||||
} else if (value == Messages.INSECURE) {
|
||||
shouldUseSSL = false;
|
||||
connect();
|
||||
} else if (!everConnected) {
|
||||
try {
|
||||
getFrame().setClosed(true);
|
||||
} catch (PropertyVetoException ex) {
|
||||
// Should not happen, but can be ignored.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Note: This method is called on a TimerTask thread. Any GUI manipulation
|
||||
// must be performed with invokeLater() or invokeAndWait().
|
||||
private Object lockObject = new Object();
|
||||
|
||||
private void update() {
|
||||
synchronized (lockObject) {
|
||||
if (!isConnected()) {
|
||||
if (wasConnected) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
vmPanelDied();
|
||||
}
|
||||
});
|
||||
}
|
||||
wasConnected = false;
|
||||
return;
|
||||
} else {
|
||||
wasConnected = true;
|
||||
everConnected = true;
|
||||
}
|
||||
proxyClient.flush();
|
||||
List<Tab> tabs = getTabs();
|
||||
final int n = tabs.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
final int index = i;
|
||||
try {
|
||||
if (!proxyClient.isDead()) {
|
||||
// Update tab
|
||||
//
|
||||
tabs.get(index).update();
|
||||
// Enable tab on initial update
|
||||
//
|
||||
if (initialUpdate) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
setEnabledAt(index, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Disable tab on initial update
|
||||
//
|
||||
if (initialUpdate) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
setEnabledAt(index, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// plugin GUI update
|
||||
for (ExceptionSafePlugin p : plugins.keySet()) {
|
||||
SwingWorker<?, ?> sw = p.newSwingWorker();
|
||||
SwingWorker<?, ?> prevSW = plugins.get(p);
|
||||
// schedule SwingWorker to run only if the previous
|
||||
// SwingWorker has finished its task and it hasn't started.
|
||||
if (prevSW == null || prevSW.isDone()) {
|
||||
if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) {
|
||||
plugins.put(p, sw);
|
||||
if (sw != null) {
|
||||
p.executeSwingWorker(sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the first enabled tab in the tab's list
|
||||
// as the selected tab on initial update
|
||||
//
|
||||
if (initialUpdate) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
// Select first enabled tab if current tab isn't.
|
||||
int index = getSelectedIndex();
|
||||
if (index < 0 || !isEnabledAt(index)) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (isEnabledAt(i)) {
|
||||
setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
initialUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getConnectionName() {
|
||||
return proxyClient.connectionName();
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return proxyClient.getDisplayName();
|
||||
}
|
||||
|
||||
static class TabInfo {
|
||||
|
||||
Class<? extends Tab> tabClass;
|
||||
String name;
|
||||
boolean tabVisible;
|
||||
|
||||
TabInfo(Class<? extends Tab> tabClass, String name, boolean tabVisible) {
|
||||
this.tabClass = tabClass;
|
||||
this.name = name;
|
||||
this.tabVisible = tabVisible;
|
||||
}
|
||||
}
|
||||
|
||||
private void createPluginTabs() {
|
||||
// add plugin tabs if not done
|
||||
if (!pluginTabsAdded) {
|
||||
for (JConsolePlugin p : plugins.keySet()) {
|
||||
Map<String, JPanel> tabs = p.getTabs();
|
||||
for (Map.Entry<String, JPanel> e : tabs.entrySet()) {
|
||||
addTab(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
pluginTabsAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void fireConnectedChange(boolean connected) {
|
||||
for (Tab tab : getTabs()) {
|
||||
tab.firePropertyChange(JConsoleContext.CONNECTION_STATE_PROPERTY, !connected, connected);
|
||||
}
|
||||
}
|
||||
}
|
||||
238
jdkSrc/jdk8/sun/tools/jconsole/VariableGridLayout.java
Normal file
238
jdkSrc/jdk8/sun/tools/jconsole/VariableGridLayout.java
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class VariableGridLayout extends GridLayout {
|
||||
|
||||
private boolean fillRows, fillColumns;
|
||||
|
||||
public VariableGridLayout(int rows, int cols,
|
||||
int hgap, int vgap,
|
||||
boolean fillRows, boolean fillColumns) {
|
||||
super(rows, cols, hgap, vgap);
|
||||
|
||||
this.fillRows = fillRows;
|
||||
this.fillColumns = fillColumns;
|
||||
}
|
||||
|
||||
public void setFillRow(JComponent c, boolean b) {
|
||||
c.putClientProperty("VariableGridLayout.fillRow", b);
|
||||
}
|
||||
|
||||
public void setFillColumn(JComponent c, boolean b) {
|
||||
c.putClientProperty("VariableGridLayout.fillColumn", b);
|
||||
}
|
||||
|
||||
public boolean getFillRow(JComponent c) {
|
||||
Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillRow");
|
||||
return (b != null) ? b : fillRows;
|
||||
}
|
||||
|
||||
public boolean getFillColumn(JComponent c) {
|
||||
Boolean b = (Boolean)c.getClientProperty("VariableGridLayout.fillColumn");
|
||||
return (b != null) ? b : fillColumns;
|
||||
}
|
||||
|
||||
public void layoutContainer(Container parent) {
|
||||
Insets insets = parent.getInsets();
|
||||
int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
int hgap = getHgap();
|
||||
int vgap = getVgap();
|
||||
|
||||
if (nrows > 0) {
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
} else {
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
// Set heights
|
||||
int x;
|
||||
int y;
|
||||
int nFills = 0;
|
||||
boolean[] fills = new boolean[nrows];
|
||||
int lastFillRow = -1;
|
||||
int nComps = parent.getComponentCount();
|
||||
|
||||
y = insets.top;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
// Find largest minimum height for this row
|
||||
int h = 0;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
h = Math.max(h, c.getMinimumSize().height);
|
||||
}
|
||||
}
|
||||
// Set heights for this row
|
||||
x = insets.left;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
JComponent c = (JComponent)parent.getComponent(row * ncols + col);
|
||||
int w = c.getWidth();
|
||||
c.setBounds(x, y, w, h);
|
||||
x += w + hgap;
|
||||
if (col == 0 && getFillRow(c)) {
|
||||
fills[row] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
y += h + vgap;
|
||||
if (fills[row]) {
|
||||
nFills++;
|
||||
lastFillRow = row;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill heights
|
||||
if (nFills > 0 && y < parent.getHeight()) {
|
||||
// How much height to add
|
||||
int hAdd = (parent.getHeight() - y) / nFills;
|
||||
int hAdded = 0;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
if (fills[row]) {
|
||||
if (row == lastFillRow) {
|
||||
// Compensate for rounding error
|
||||
hAdd = parent.getHeight() - (y+hAdded);
|
||||
}
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
Rectangle b = c.getBounds();
|
||||
c.setBounds(b.x, b.y + hAdded, b.width, b.height + hAdd);
|
||||
}
|
||||
}
|
||||
hAdded += hAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set widths
|
||||
nFills = 0;
|
||||
fills = new boolean[ncols];
|
||||
int lastFillCol = -1;
|
||||
|
||||
x = insets.left;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
// Find largest minimum width for this column
|
||||
int w = 0;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
w = Math.max(w, c.getMinimumSize().width);
|
||||
}
|
||||
}
|
||||
// Set widths for this column
|
||||
y = insets.top;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
JComponent c = (JComponent)parent.getComponent(row * ncols + col);
|
||||
int h = c.getHeight();
|
||||
c.setBounds(x, y, w, h);
|
||||
y += h + vgap;
|
||||
if (row == 0 && getFillColumn(c)) {
|
||||
fills[col] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
x += w + hgap;
|
||||
if (fills[col]) {
|
||||
nFills++;
|
||||
lastFillCol = col;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill widths
|
||||
if (nFills > 0 && x < parent.getWidth()) {
|
||||
// How much width to add
|
||||
int wAdd = (parent.getWidth() - x) / nFills;
|
||||
int wAdded = 0;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
if (fills[col]) {
|
||||
if (col == lastFillCol) {
|
||||
wAdd = parent.getWidth() - (x+wAdded);
|
||||
}
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
Rectangle b = c.getBounds();
|
||||
c.setBounds(b.x + wAdded, b.y, b.width + wAdd, b.height);
|
||||
}
|
||||
}
|
||||
wAdded += wAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
Insets insets = parent.getInsets();
|
||||
int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
int hgap = getHgap();
|
||||
int vgap = getVgap();
|
||||
|
||||
if (nrows > 0) {
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
} else {
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
int nComps = parent.getComponentCount();
|
||||
|
||||
int y = insets.top;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
int h = 0;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
h = Math.max(h, c.getMinimumSize().height);
|
||||
}
|
||||
}
|
||||
y += h + vgap;
|
||||
}
|
||||
|
||||
int x = insets.left;
|
||||
for (int col = 0; col < ncols; col++) {
|
||||
int w = 0;
|
||||
for (int row = 0; row < nrows; row++) {
|
||||
if (row * ncols + col < nComps) {
|
||||
Component c = parent.getComponent(row * ncols + col);
|
||||
w = Math.max(w, c.getMinimumSize().width);
|
||||
}
|
||||
}
|
||||
x += w + hgap;
|
||||
}
|
||||
return new Dimension(x, y);
|
||||
}
|
||||
}
|
||||
56
jdkSrc/jdk8/sun/tools/jconsole/Version.java
Normal file
56
jdkSrc/jdk8/sun/tools/jconsole/Version.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import sun.tools.jconsole.Messages;
|
||||
|
||||
public class Version {
|
||||
private static final String jconsole_version =
|
||||
"1.8.0_462-b08";
|
||||
|
||||
public static void print(PrintStream ps) {
|
||||
printFullVersion(ps);
|
||||
|
||||
ps.println(Resources.format(Messages.NAME_AND_BUILD,
|
||||
System.getProperty("java.runtime.name"),
|
||||
System.getProperty("java.runtime.version")));
|
||||
|
||||
ps.println(Resources.format(Messages.NAME_AND_BUILD,
|
||||
System.getProperty("java.vm.name"),
|
||||
System.getProperty("java.vm.version"),
|
||||
System.getProperty("java.vm.info")));
|
||||
|
||||
}
|
||||
|
||||
public static void printFullVersion(PrintStream ps) {
|
||||
ps.println(Resources.format(Messages.JCONSOLE_VERSION, jconsole_version));
|
||||
}
|
||||
|
||||
static String getVersion() {
|
||||
return jconsole_version;
|
||||
}
|
||||
}
|
||||
78
jdkSrc/jdk8/sun/tools/jconsole/Worker.java
Normal file
78
jdkSrc/jdk8/sun/tools/jconsole/Worker.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2020 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Worker extends Thread {
|
||||
ArrayList<Runnable> jobs = new ArrayList<Runnable>();
|
||||
private volatile boolean stopped = false;
|
||||
|
||||
public Worker(String name) {
|
||||
super("Worker-"+name);
|
||||
|
||||
setPriority(NORM_PRIORITY - 1);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (!stopped) {
|
||||
Runnable job;
|
||||
synchronized(jobs) {
|
||||
while (!stopped && jobs.size() == 0) {
|
||||
try {
|
||||
jobs.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if(stopped) break;
|
||||
|
||||
job = jobs.remove(0);
|
||||
}
|
||||
job.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopWorker() {
|
||||
stopped = true;
|
||||
synchronized(jobs) {
|
||||
jobs.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Runnable job) {
|
||||
synchronized(jobs) {
|
||||
jobs.add(job);
|
||||
jobs.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean queueFull() {
|
||||
synchronized(jobs) {
|
||||
return (jobs.size() > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
jdkSrc/jdk8/sun/tools/jconsole/inspector/IconManager.java
Normal file
50
jdkSrc/jdk8/sun/tools/jconsole/inspector/IconManager.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2006, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.Image;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import sun.tools.jconsole.JConsole;
|
||||
|
||||
public class IconManager {
|
||||
|
||||
public static Icon MBEAN =
|
||||
getSmallIcon(getImage("mbean.gif"));
|
||||
public static Icon MBEANSERVERDELEGATE =
|
||||
getSmallIcon(getImage("mbeanserverdelegate.gif"));
|
||||
public static Icon DEFAULT_XOBJECT =
|
||||
getSmallIcon(getImage("xobject.gif"));
|
||||
|
||||
private static ImageIcon getImage(String img) {
|
||||
return new ImageIcon(JConsole.class.getResource("resources/" + img));
|
||||
}
|
||||
|
||||
private static ImageIcon getSmallIcon(ImageIcon icon) {
|
||||
return new ImageIcon(
|
||||
icon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
|
||||
}
|
||||
}
|
||||
112
jdkSrc/jdk8/sun/tools/jconsole/inspector/OperationEntry.java
Normal file
112
jdkSrc/jdk8/sun/tools/jconsole/inspector/OperationEntry.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.management.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class OperationEntry extends JPanel {
|
||||
private MBeanOperationInfo operation;
|
||||
private JComboBox sigs;
|
||||
private XTextField inputs[];
|
||||
|
||||
public OperationEntry (MBeanOperationInfo operation,
|
||||
boolean isCallable,
|
||||
JButton button,
|
||||
XOperations xoperations) {
|
||||
super(new BorderLayout());
|
||||
this.operation = operation;
|
||||
setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
setPanel(isCallable, button, xoperations);
|
||||
}
|
||||
|
||||
private void setPanel(boolean isCallable,
|
||||
JButton button,
|
||||
XOperations xoperations) {
|
||||
try {
|
||||
MBeanParameterInfo params[] = operation.getSignature();
|
||||
add(new JLabel("(",JLabel.CENTER));
|
||||
inputs = new XTextField[params.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if(params[i].getName() != null) {
|
||||
JLabel name =
|
||||
new JLabel(params[i].getName(), JLabel.CENTER);
|
||||
name.setToolTipText(params[i].getDescription());
|
||||
add(name);
|
||||
}
|
||||
|
||||
String defaultTextValue =
|
||||
Utils.getDefaultValue(params[i].getType());
|
||||
int fieldWidth = defaultTextValue.length();
|
||||
if (fieldWidth > 15) fieldWidth = 15;
|
||||
else
|
||||
if (fieldWidth < 10) fieldWidth = 10;
|
||||
|
||||
add(inputs[i] =
|
||||
new XTextField(Utils.getReadableClassName(defaultTextValue),
|
||||
Utils.getClass(params[i].getType()),
|
||||
fieldWidth,
|
||||
isCallable,
|
||||
button,
|
||||
xoperations));
|
||||
inputs[i].setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
if (i < params.length-1)
|
||||
add(new JLabel(",",JLabel.CENTER));
|
||||
}
|
||||
add(new JLabel(")",JLabel.CENTER));
|
||||
validate();
|
||||
doLayout();
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error setting Operation panel :"+
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getSignature() {
|
||||
MBeanParameterInfo params[] = operation.getSignature();
|
||||
String result[] = new String[params.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
result[i] = params[i].getType();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object[] getParameters() throws Exception {
|
||||
MBeanParameterInfo params[] = operation.getSignature();
|
||||
String signature[] = new String[params.length];
|
||||
for (int i = 0; i < params.length; i++)
|
||||
signature[i] = params[i].getType();
|
||||
return Utils.getParameters(inputs,signature);
|
||||
}
|
||||
|
||||
public String getReturnType() {
|
||||
return operation.getReturnType();
|
||||
}
|
||||
}
|
||||
292
jdkSrc/jdk8/sun/tools/jconsole/inspector/TableSorter.java
Normal file
292
jdkSrc/jdk8/sun/tools/jconsole/inspector/TableSorter.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
|
||||
// Imports for picking up mouse events from the JTable.
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.Vector;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import sun.tools.jconsole.JConsole;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TableSorter extends DefaultTableModel implements MouseListener {
|
||||
private boolean ascending = true;
|
||||
private TableColumnModel columnModel;
|
||||
private JTable tableView;
|
||||
private Vector<TableModelListener> evtListenerList;
|
||||
private int sortColumn = 0;
|
||||
|
||||
private int[] invertedIndex;
|
||||
|
||||
public TableSorter() {
|
||||
super();
|
||||
evtListenerList = new Vector<TableModelListener>();
|
||||
}
|
||||
|
||||
public TableSorter(Object[] columnNames, int numRows) {
|
||||
super(columnNames,numRows);
|
||||
evtListenerList = new Vector<TableModelListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newDataAvailable(TableModelEvent e) {
|
||||
super.newDataAvailable(e);
|
||||
invertedIndex = new int[getRowCount()];
|
||||
for (int i = 0; i < invertedIndex.length; i++) {
|
||||
invertedIndex[i] = i;
|
||||
}
|
||||
sort(this.sortColumn, this.ascending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableModelListener(TableModelListener l) {
|
||||
evtListenerList.add(l);
|
||||
super.addTableModelListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTableModelListener(TableModelListener l) {
|
||||
evtListenerList.remove(l);
|
||||
super.removeTableModelListener(l);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
for(TableModelListener tnl : evtListenerList)
|
||||
super.removeTableModelListener(tnl);
|
||||
}
|
||||
|
||||
private void restoreListeners() {
|
||||
for(TableModelListener tnl : evtListenerList)
|
||||
super.addTableModelListener(tnl);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private int compare(Object o1, Object o2) {
|
||||
// take care of the case where both o1 & o2 are null. Needed to keep
|
||||
// the method symmetric. Without this quickSort gives surprising results.
|
||||
if (o1 == o2)
|
||||
return 0;
|
||||
if (o1==null)
|
||||
return 1;
|
||||
if (o2==null)
|
||||
return -1;
|
||||
//two object of the same class and that are comparable
|
||||
else if ((o1.getClass().equals(o2.getClass())) &&
|
||||
(o1 instanceof Comparable)) {
|
||||
return (((Comparable) o1).compareTo(o2));
|
||||
}
|
||||
else {
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void sort(int column, boolean isAscending) {
|
||||
final XMBeanAttributes attrs =
|
||||
(tableView instanceof XMBeanAttributes)
|
||||
?(XMBeanAttributes) tableView
|
||||
:null;
|
||||
|
||||
// We cannot sort rows when a cell is being
|
||||
// edited - so we're going to cancel cell editing here if needed.
|
||||
// This might happen when the user is editing a row, and clicks on
|
||||
// another row without validating. In that case there are two events
|
||||
// that compete: one is the validation of the value that was previously
|
||||
// edited, the other is the mouse click that opens the new editor.
|
||||
//
|
||||
// When we reach here the previous value is already validated, and the
|
||||
// old editor is closed, but the new editor might have opened.
|
||||
// It's this new editor that wil be cancelled here, if needed.
|
||||
//
|
||||
if (attrs != null && attrs.isEditing())
|
||||
attrs.cancelCellEditing();
|
||||
|
||||
// remove registered listeners
|
||||
removeListeners();
|
||||
// do the sort
|
||||
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("sorting table against column="+column
|
||||
+" ascending="+isAscending);
|
||||
}
|
||||
quickSort(0,getRowCount()-1,column,isAscending);
|
||||
// restore registered listeners
|
||||
restoreListeners();
|
||||
|
||||
// update row heights in XMBeanAttributes (required by expandable cells)
|
||||
if (attrs != null) {
|
||||
for (int i = 0; i < getRowCount(); i++) {
|
||||
Vector data = (Vector) dataVector.elementAt(i);
|
||||
attrs.updateRowHeight(data.elementAt(1), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean compareS(Object s1, Object s2, boolean isAscending) {
|
||||
if (isAscending)
|
||||
return (compare(s1,s2) > 0);
|
||||
else
|
||||
return (compare(s1,s2) < 0);
|
||||
}
|
||||
|
||||
private boolean compareG(Object s1, Object s2, boolean isAscending) {
|
||||
if (isAscending)
|
||||
return (compare(s1,s2) < 0);
|
||||
else
|
||||
return (compare(s1,s2) > 0);
|
||||
}
|
||||
|
||||
private void quickSort(int lo0,int hi0, int key, boolean isAscending) {
|
||||
int lo = lo0;
|
||||
int hi = hi0;
|
||||
Object mid;
|
||||
|
||||
if ( hi0 > lo0)
|
||||
{
|
||||
mid = getValueAt( ( lo0 + hi0 ) / 2 , key);
|
||||
|
||||
while( lo <= hi )
|
||||
{
|
||||
/* find the first element that is greater than
|
||||
* or equal to the partition element starting
|
||||
* from the left Index.
|
||||
*/
|
||||
while( ( lo < hi0 ) &&
|
||||
( compareS(mid,getValueAt(lo,key), isAscending) ))
|
||||
++lo;
|
||||
|
||||
/* find an element that is smaller than or equal to
|
||||
* the partition element starting from the right Index.
|
||||
*/
|
||||
while( ( hi > lo0 ) &&
|
||||
( compareG(mid,getValueAt(hi,key), isAscending) ))
|
||||
--hi;
|
||||
|
||||
// if the indexes have not crossed, swap
|
||||
if( lo <= hi )
|
||||
{
|
||||
swap(lo, hi, key);
|
||||
++lo;
|
||||
--hi;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the right index has not reached the
|
||||
* left side of array
|
||||
* must now sort the left partition.
|
||||
*/
|
||||
if( lo0 < hi )
|
||||
quickSort(lo0, hi , key, isAscending);
|
||||
|
||||
/* If the left index has not reached the right
|
||||
* side of array
|
||||
* must now sort the right partition.
|
||||
*/
|
||||
if( lo <= hi0 )
|
||||
quickSort(lo, hi0 , key, isAscending);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector getRow(int row) {
|
||||
return (Vector) dataVector.elementAt(row);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setRow(Vector data, int row) {
|
||||
dataVector.setElementAt(data,row);
|
||||
}
|
||||
|
||||
private void swap(int i, int j, int column) {
|
||||
Vector data = getRow(i);
|
||||
setRow(getRow(j),i);
|
||||
setRow(data,j);
|
||||
|
||||
int a = invertedIndex[i];
|
||||
invertedIndex[i] = invertedIndex[j];
|
||||
invertedIndex[j] = a;
|
||||
}
|
||||
|
||||
public void sortByColumn(int column) {
|
||||
sortByColumn(column, !ascending);
|
||||
}
|
||||
|
||||
public void sortByColumn(int column, boolean ascending) {
|
||||
this.ascending = ascending;
|
||||
this.sortColumn = column;
|
||||
sort(column,ascending);
|
||||
}
|
||||
|
||||
public int getIndexOfRow(int row) {
|
||||
return invertedIndex[row];
|
||||
}
|
||||
|
||||
// Add a mouse listener to the Table to trigger a table sort
|
||||
// when a column heading is clicked in the JTable.
|
||||
public void addMouseListenerToHeaderInTable(JTable table) {
|
||||
tableView = table;
|
||||
columnModel = tableView.getColumnModel();
|
||||
JTableHeader th = tableView.getTableHeader();
|
||||
th.addMouseListener(this);
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
int viewColumn = columnModel.getColumnIndexAtX(e.getX());
|
||||
int column = tableView.convertColumnIndexToModel(viewColumn);
|
||||
if (e.getClickCount() == 1 && column != -1) {
|
||||
if (tableView instanceof XTable) {
|
||||
XTable attrs = (XTable) tableView;
|
||||
// inform the table view that the rows are going to be sorted
|
||||
// against the values in a given column. This gives the
|
||||
// chance to the table view to close its editor - if needed.
|
||||
//
|
||||
attrs.sortRequested(column);
|
||||
}
|
||||
tableView.invalidate();
|
||||
sortByColumn(column);
|
||||
tableView.validate();
|
||||
tableView.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
56
jdkSrc/jdk8/sun/tools/jconsole/inspector/ThreadDialog.java
Normal file
56
jdkSrc/jdk8/sun/tools/jconsole/inspector/ThreadDialog.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
// java import
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
//
|
||||
|
||||
public class ThreadDialog implements Runnable {
|
||||
|
||||
Component parentComponent;
|
||||
Object message;
|
||||
String title;
|
||||
int messageType;
|
||||
|
||||
public ThreadDialog(Component parentComponent,
|
||||
Object message,
|
||||
String title,
|
||||
int messageType) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.message = message;
|
||||
this.title = title;
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
JOptionPane pane = new JOptionPane(message, messageType);
|
||||
JDialog dialog = pane.createDialog(parentComponent, title);
|
||||
dialog.setResizable(true);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
462
jdkSrc/jdk8/sun/tools/jconsole/inspector/Utils.java
Normal file
462
jdkSrc/jdk8/sun/tools/jconsole/inspector/Utils.java
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.management.*;
|
||||
import javax.management.openmbean.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
public class Utils {
|
||||
|
||||
private Utils() {
|
||||
}
|
||||
private static Set<Integer> tableNavigationKeys =
|
||||
new HashSet<Integer>(Arrays.asList(new Integer[]{
|
||||
KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
|
||||
KeyEvent.VK_HOME, KeyEvent.VK_END,
|
||||
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
|
||||
KeyEvent.VK_UP, KeyEvent.VK_DOWN,
|
||||
KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN
|
||||
}));
|
||||
private static final Set<Class<?>> primitiveWrappers =
|
||||
new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
|
||||
Byte.class, Short.class, Integer.class, Long.class,
|
||||
Float.class, Double.class, Character.class, Boolean.class
|
||||
}));
|
||||
private static final Set<Class<?>> primitives = new HashSet<Class<?>>();
|
||||
private static final Map<String, Class<?>> primitiveMap =
|
||||
new HashMap<String, Class<?>>();
|
||||
private static final Map<String, Class<?>> primitiveToWrapper =
|
||||
new HashMap<String, Class<?>>();
|
||||
private static final Set<String> editableTypes = new HashSet<String>();
|
||||
private static final Set<Class<?>> extraEditableClasses =
|
||||
new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
|
||||
BigDecimal.class, BigInteger.class, Number.class,
|
||||
String.class, ObjectName.class
|
||||
}));
|
||||
private static final Set<String> numericalTypes = new HashSet<String>();
|
||||
private static final Set<String> extraNumericalTypes =
|
||||
new HashSet<String>(Arrays.asList(new String[]{
|
||||
BigDecimal.class.getName(), BigInteger.class.getName(),
|
||||
Number.class.getName()
|
||||
}));
|
||||
private static final Set<String> booleanTypes =
|
||||
new HashSet<String>(Arrays.asList(new String[]{
|
||||
Boolean.TYPE.getName(), Boolean.class.getName()
|
||||
}));
|
||||
|
||||
static {
|
||||
// compute primitives/primitiveMap/primitiveToWrapper
|
||||
for (Class<?> c : primitiveWrappers) {
|
||||
try {
|
||||
Field f = c.getField("TYPE");
|
||||
Class<?> p = (Class<?>) f.get(null);
|
||||
primitives.add(p);
|
||||
primitiveMap.put(p.getName(), p);
|
||||
primitiveToWrapper.put(p.getName(), c);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
// compute editableTypes
|
||||
for (Class<?> c : primitives) {
|
||||
editableTypes.add(c.getName());
|
||||
}
|
||||
for (Class<?> c : primitiveWrappers) {
|
||||
editableTypes.add(c.getName());
|
||||
}
|
||||
for (Class<?> c : extraEditableClasses) {
|
||||
editableTypes.add(c.getName());
|
||||
}
|
||||
// compute numericalTypes
|
||||
for (Class<?> c : primitives) {
|
||||
String name = c.getName();
|
||||
if (!name.equals(Boolean.TYPE.getName())) {
|
||||
numericalTypes.add(name);
|
||||
}
|
||||
}
|
||||
for (Class<?> c : primitiveWrappers) {
|
||||
String name = c.getName();
|
||||
if (!name.equals(Boolean.class.getName())) {
|
||||
numericalTypes.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the class matching the name className.
|
||||
* It's used to cater for the primitive types.
|
||||
*/
|
||||
public static Class<?> getClass(String className)
|
||||
throws ClassNotFoundException {
|
||||
Class<?> c;
|
||||
if ((c = primitiveMap.get(className)) != null) {
|
||||
return c;
|
||||
}
|
||||
return Class.forName(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given collection is a uniform collection of the given type.
|
||||
*/
|
||||
public static boolean isUniformCollection(Collection<?> c, Class<?> e) {
|
||||
if (e == null) {
|
||||
throw new IllegalArgumentException("Null reference type");
|
||||
}
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("Null collection");
|
||||
}
|
||||
if (c.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Object o : c) {
|
||||
if (o == null || !e.isAssignableFrom(o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given element denotes a supported array-friendly data
|
||||
* structure, i.e. a data structure jconsole can render as an array.
|
||||
*/
|
||||
public static boolean canBeRenderedAsArray(Object elem) {
|
||||
if (isSupportedArray(elem)) {
|
||||
return true;
|
||||
}
|
||||
if (elem instanceof Collection) {
|
||||
Collection<?> c = (Collection<?>) elem;
|
||||
if (c.isEmpty()) {
|
||||
// Empty collections of any Java type are not handled as arrays
|
||||
//
|
||||
return false;
|
||||
} else {
|
||||
// - Collections of CompositeData/TabularData are not handled
|
||||
// as arrays
|
||||
// - Collections of other Java types are handled as arrays
|
||||
//
|
||||
return !isUniformCollection(c, CompositeData.class) &&
|
||||
!isUniformCollection(c, TabularData.class);
|
||||
}
|
||||
}
|
||||
if (elem instanceof Map) {
|
||||
return !(elem instanceof TabularData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given element is an array.
|
||||
*
|
||||
* Multidimensional arrays are not supported.
|
||||
*
|
||||
* Non-empty 1-dimensional arrays of CompositeData
|
||||
* and TabularData are not handled as arrays but as
|
||||
* tabular data.
|
||||
*/
|
||||
public static boolean isSupportedArray(Object elem) {
|
||||
if (elem == null || !elem.getClass().isArray()) {
|
||||
return false;
|
||||
}
|
||||
Class<?> ct = elem.getClass().getComponentType();
|
||||
if (ct.isArray()) {
|
||||
return false;
|
||||
}
|
||||
if (Array.getLength(elem) > 0 &&
|
||||
(CompositeData.class.isAssignableFrom(ct) ||
|
||||
TabularData.class.isAssignableFrom(ct))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method provides a readable classname if it's an array,
|
||||
* i.e. either the classname of the component type for arrays
|
||||
* of java reference types or the name of the primitive type
|
||||
* for arrays of java primitive types. Otherwise, it returns null.
|
||||
*/
|
||||
public static String getArrayClassName(String name) {
|
||||
String className = null;
|
||||
if (name.startsWith("[")) {
|
||||
int index = name.lastIndexOf("[");
|
||||
className = name.substring(index, name.length());
|
||||
if (className.startsWith("[L")) {
|
||||
className = className.substring(2, className.length() - 1);
|
||||
} else {
|
||||
try {
|
||||
Class<?> c = Class.forName(className);
|
||||
className = c.getComponentType().getName();
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Should not happen
|
||||
throw new IllegalArgumentException(
|
||||
"Bad class name " + name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods provides a readable classname. If the supplied name
|
||||
* parameter denotes an array this method returns either the classname
|
||||
* of the component type for arrays of java reference types or the name
|
||||
* of the primitive type for arrays of java primitive types followed by
|
||||
* n-times "[]" where 'n' denotes the arity of the array. Otherwise, if
|
||||
* the supplied name doesn't denote an array it returns the same classname.
|
||||
*/
|
||||
public static String getReadableClassName(String name) {
|
||||
String className = getArrayClassName(name);
|
||||
if (className == null) {
|
||||
return name;
|
||||
}
|
||||
int index = name.lastIndexOf("[");
|
||||
StringBuilder brackets = new StringBuilder(className);
|
||||
for (int i = 0; i <= index; i++) {
|
||||
brackets.append("[]");
|
||||
}
|
||||
return brackets.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tells whether the type is editable
|
||||
* (means can be created with a String or not)
|
||||
*/
|
||||
public static boolean isEditableType(String type) {
|
||||
return editableTypes.contains(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method inserts a default value for the standard java types,
|
||||
* else it inserts the text name of the expected class type.
|
||||
* It acts to give a clue as to the input type.
|
||||
*/
|
||||
public static String getDefaultValue(String type) {
|
||||
if (numericalTypes.contains(type) ||
|
||||
extraNumericalTypes.contains(type)) {
|
||||
return "0";
|
||||
}
|
||||
if (booleanTypes.contains(type)) {
|
||||
return "true";
|
||||
}
|
||||
type = getReadableClassName(type);
|
||||
int i = type.lastIndexOf('.');
|
||||
if (i > 0) {
|
||||
return type.substring(i + 1, type.length());
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to create a Java object using a one-string-param constructor.
|
||||
*/
|
||||
public static Object newStringConstructor(String type, String param)
|
||||
throws Exception {
|
||||
Constructor<?> c = Utils.getClass(type).getConstructor(String.class);
|
||||
try {
|
||||
return c.newInstance(param);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable t = e.getTargetException();
|
||||
if (t instanceof Exception) {
|
||||
throw (Exception) t;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert a string value into a numerical value.
|
||||
*/
|
||||
private static Number createNumberFromStringValue(String value)
|
||||
throws NumberFormatException {
|
||||
final String suffix = value.substring(value.length() - 1);
|
||||
if ("L".equalsIgnoreCase(suffix)) {
|
||||
return Long.valueOf(value.substring(0, value.length() - 1));
|
||||
}
|
||||
if ("F".equalsIgnoreCase(suffix)) {
|
||||
return Float.valueOf(value.substring(0, value.length() - 1));
|
||||
}
|
||||
if ("D".equalsIgnoreCase(suffix)) {
|
||||
return Double.valueOf(value.substring(0, value.length() - 1));
|
||||
}
|
||||
try {
|
||||
return Integer.valueOf(value);
|
||||
} catch (NumberFormatException e) {
|
||||
// OK: Ignore exception...
|
||||
}
|
||||
try {
|
||||
return Long.valueOf(value);
|
||||
} catch (NumberFormatException e1) {
|
||||
// OK: Ignore exception...
|
||||
}
|
||||
try {
|
||||
return Double.valueOf(value);
|
||||
} catch (NumberFormatException e2) {
|
||||
// OK: Ignore exception...
|
||||
}
|
||||
throw new NumberFormatException("Cannot convert string value '" +
|
||||
value + "' into a numerical value");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attempts to create an object of the given "type"
|
||||
* using the "value" parameter.
|
||||
* e.g. calling createObjectFromString("java.lang.Integer", "10")
|
||||
* will return an Integer object initialized to 10.
|
||||
*/
|
||||
public static Object createObjectFromString(String type, String value)
|
||||
throws Exception {
|
||||
Object result;
|
||||
if (primitiveToWrapper.containsKey(type)) {
|
||||
if (type.equals(Character.TYPE.getName())) {
|
||||
result = new Character(value.charAt(0));
|
||||
} else {
|
||||
result = newStringConstructor(
|
||||
((Class<?>) primitiveToWrapper.get(type)).getName(),
|
||||
value);
|
||||
}
|
||||
} else if (type.equals(Character.class.getName())) {
|
||||
result = new Character(value.charAt(0));
|
||||
} else if (Number.class.isAssignableFrom(Utils.getClass(type))) {
|
||||
result = createNumberFromStringValue(value);
|
||||
} else if (value == null || value.equals("null")) {
|
||||
// hack for null value
|
||||
result = null;
|
||||
} else {
|
||||
// try to create a Java object using
|
||||
// the one-string-param constructor
|
||||
result = newStringConstructor(type, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for converting the inputs given by the user
|
||||
* into a useful object array for passing into a parameter array.
|
||||
*/
|
||||
public static Object[] getParameters(XTextField[] inputs, String[] params)
|
||||
throws Exception {
|
||||
Object result[] = new Object[inputs.length];
|
||||
Object userInput;
|
||||
for (int i = 0; i < inputs.length; i++) {
|
||||
userInput = inputs[i].getValue();
|
||||
// if it's already a complex object, use the value
|
||||
// else try to instantiate with string constructor
|
||||
if (userInput instanceof XObject) {
|
||||
result[i] = ((XObject) userInput).getObject();
|
||||
} else {
|
||||
result[i] = createObjectFromString(params[i].toString(),
|
||||
(String) userInput);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the exception is wrapped, unwrap it.
|
||||
*/
|
||||
public static Throwable getActualException(Throwable e) {
|
||||
if (e instanceof ExecutionException) {
|
||||
e = e.getCause();
|
||||
}
|
||||
if (e instanceof MBeanException ||
|
||||
e instanceof RuntimeMBeanException ||
|
||||
e instanceof RuntimeOperationsException ||
|
||||
e instanceof ReflectionException) {
|
||||
Throwable t = e.getCause();
|
||||
if (t != null) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class ReadOnlyTableCellEditor
|
||||
extends DefaultCellEditor {
|
||||
|
||||
public ReadOnlyTableCellEditor(JTextField tf) {
|
||||
super(tf);
|
||||
tf.addFocusListener(new Utils.EditFocusAdapter(this));
|
||||
tf.addKeyListener(new Utils.CopyKeyAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditFocusAdapter extends FocusAdapter {
|
||||
|
||||
private CellEditor editor;
|
||||
|
||||
public EditFocusAdapter(CellEditor editor) {
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
editor.stopCellEditing();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CopyKeyAdapter extends KeyAdapter {
|
||||
private static final String defaultEditorKitCopyActionName =
|
||||
DefaultEditorKit.copyAction;
|
||||
private static final String transferHandlerCopyActionName =
|
||||
(String) TransferHandler.getCopyAction().getValue(Action.NAME);
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// Accept "copy" key strokes
|
||||
KeyStroke ks = KeyStroke.getKeyStroke(
|
||||
e.getKeyCode(), e.getModifiers());
|
||||
JComponent comp = (JComponent) e.getSource();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
InputMap im = comp.getInputMap(i);
|
||||
Object key = im.get(ks);
|
||||
if (defaultEditorKitCopyActionName.equals(key) ||
|
||||
transferHandlerCopyActionName.equals(key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Accept JTable navigation key strokes
|
||||
if (!tableNavigationKeys.contains(e.getKeyCode())) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/sun/tools/jconsole/inspector/XArrayDataViewer.java
Normal file
113
jdkSrc/jdk8/sun/tools/jconsole/inspector/XArrayDataViewer.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
class XArrayDataViewer {
|
||||
|
||||
private XArrayDataViewer() {}
|
||||
|
||||
public static boolean isViewableValue(Object value) {
|
||||
return Utils.canBeRenderedAsArray(value);
|
||||
}
|
||||
|
||||
public static Component loadArray(Object value) {
|
||||
Component comp = null;
|
||||
if (isViewableValue(value)) {
|
||||
Object[] arr;
|
||||
if (value instanceof Collection) {
|
||||
arr = ((Collection<?>) value).toArray();
|
||||
} else if (value instanceof Map) {
|
||||
arr = ((Map<?,?>) value).entrySet().toArray();
|
||||
} else if (value instanceof Object[]) {
|
||||
arr = (Object[]) value;
|
||||
} else {
|
||||
int length = Array.getLength(value);
|
||||
arr = new Object[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
arr[i] = Array.get(value, i);
|
||||
}
|
||||
}
|
||||
JEditorPane arrayEditor = new JEditorPane();
|
||||
arrayEditor.setContentType("text/html");
|
||||
arrayEditor.setEditable(false);
|
||||
Color evenRowColor = arrayEditor.getBackground();
|
||||
int red = evenRowColor.getRed();
|
||||
int green = evenRowColor.getGreen();
|
||||
int blue = evenRowColor.getBlue();
|
||||
String evenRowColorStr =
|
||||
"rgb(" + red + "," + green + "," + blue + ")";
|
||||
Color oddRowColor = new Color(
|
||||
red < 20 ? red + 20 : red - 20,
|
||||
green < 20 ? green + 20 : green - 20,
|
||||
blue < 20 ? blue + 20 : blue - 20);
|
||||
String oddRowColorStr =
|
||||
"rgb(" + oddRowColor.getRed() + "," +
|
||||
oddRowColor.getGreen() + "," +
|
||||
oddRowColor.getBlue() + ")";
|
||||
Color foreground = arrayEditor.getForeground();
|
||||
String textColor = String.format("%06x",
|
||||
foreground.getRGB() & 0xFFFFFF);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><body text=#"+textColor+"><table width=\"100%\">");
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
sb.append("<tr style=\"background-color: " +
|
||||
evenRowColorStr + "\"><td><pre>" +
|
||||
(arr[i] == null ?
|
||||
arr[i] : htmlize(arr[i].toString())) +
|
||||
"</pre></td></tr>");
|
||||
} else {
|
||||
sb.append("<tr style=\"background-color: " +
|
||||
oddRowColorStr + "\"><td><pre>" +
|
||||
(arr[i] == null ?
|
||||
arr[i] : htmlize(arr[i].toString())) +
|
||||
"</pre></td></tr>");
|
||||
}
|
||||
}
|
||||
if (arr.length == 0) {
|
||||
sb.append("<tr style=\"background-color: " +
|
||||
evenRowColorStr + "\"><td></td></tr>");
|
||||
}
|
||||
sb.append("</table></body></html>");
|
||||
arrayEditor.setText(sb.toString());
|
||||
JScrollPane scrollp = new JScrollPane(arrayEditor);
|
||||
comp = scrollp;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
private static String htmlize(String value) {
|
||||
return value.replace("&", "&").replace("<", "<");
|
||||
}
|
||||
}
|
||||
148
jdkSrc/jdk8/sun/tools/jconsole/inspector/XDataViewer.java
Normal file
148
jdkSrc/jdk8/sun/tools/jconsole/inspector/XDataViewer.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JButton;
|
||||
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
|
||||
import sun.tools.jconsole.MBeansTab;
|
||||
import sun.tools.jconsole.Messages;
|
||||
|
||||
public class XDataViewer {
|
||||
|
||||
public static final int OPEN = 1;
|
||||
public static final int ARRAY = 2;
|
||||
public static final int NUMERIC = 3;
|
||||
public static final int NOT_SUPPORTED = 4;
|
||||
|
||||
private MBeansTab tab;
|
||||
public XDataViewer(MBeansTab tab) {
|
||||
this.tab = tab;
|
||||
}
|
||||
|
||||
public static void registerForMouseEvent(Component comp,
|
||||
MouseListener mouseListener) {
|
||||
if(comp instanceof JScrollPane) {
|
||||
JScrollPane pane = (JScrollPane) comp;
|
||||
comp = pane.getViewport().getView();
|
||||
}
|
||||
if(comp instanceof Container) {
|
||||
Container container = (Container) comp;
|
||||
Component[] components = container.getComponents();
|
||||
for(int i = 0; i < components.length; i++) {
|
||||
registerForMouseEvent(components[i], mouseListener);
|
||||
}
|
||||
}
|
||||
|
||||
//No registration for XOpenTypedata that are themselves clickable.
|
||||
//No registration for JButton that are themselves clickable.
|
||||
if(comp != null &&
|
||||
(!(comp instanceof XOpenTypeViewer.XOpenTypeData) &&
|
||||
!(comp instanceof JButton)) )
|
||||
comp.addMouseListener(mouseListener);
|
||||
}
|
||||
|
||||
public static void dispose(MBeansTab tab) {
|
||||
XPlottingViewer.dispose(tab);
|
||||
}
|
||||
|
||||
public static boolean isViewableValue(Object value) {
|
||||
boolean ret = false;
|
||||
if((ret = XArrayDataViewer.isViewableValue(value)))
|
||||
return ret;
|
||||
if((ret = XOpenTypeViewer.isViewableValue(value)))
|
||||
return ret;
|
||||
if((ret = XPlottingViewer.isViewableValue(value)))
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int getViewerType(Object data) {
|
||||
if(XArrayDataViewer.isViewableValue(data))
|
||||
return ARRAY;
|
||||
if(XOpenTypeViewer.isViewableValue(data))
|
||||
return OPEN;
|
||||
if(XPlottingViewer.isViewableValue(data))
|
||||
return NUMERIC;
|
||||
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
public static String getActionLabel(int type) {
|
||||
if(type == ARRAY ||
|
||||
type == OPEN)
|
||||
return Messages.VISUALIZE;
|
||||
if(type == NUMERIC)
|
||||
return Messages.PLOT;
|
||||
return Messages.EXPAND;
|
||||
}
|
||||
|
||||
public Component createOperationViewer(Object value,
|
||||
XMBean mbean) {
|
||||
if(value instanceof Number) return null;
|
||||
if(value instanceof Component) return (Component) value;
|
||||
return createAttributeViewer(value, mbean, null, null);
|
||||
}
|
||||
|
||||
public static Component createNotificationViewer(Object value) {
|
||||
Component comp = null;
|
||||
|
||||
if(value instanceof Number) return null;
|
||||
|
||||
if((comp = XArrayDataViewer.loadArray(value)) != null)
|
||||
return comp;
|
||||
|
||||
if((comp = XOpenTypeViewer.loadOpenType(value)) != null)
|
||||
return comp;
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Component createAttributeViewer(Object value,
|
||||
XMBean mbean,
|
||||
String attributeName,
|
||||
JTable table) {
|
||||
Component comp = null;
|
||||
if((comp = XArrayDataViewer.loadArray(value)) != null)
|
||||
return comp;
|
||||
if((comp = XOpenTypeViewer.loadOpenType(value)) != null)
|
||||
return comp;
|
||||
if((comp = XPlottingViewer.loadPlotting(mbean,
|
||||
attributeName,
|
||||
value,
|
||||
table,
|
||||
tab)) != null)
|
||||
return comp;
|
||||
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
186
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBean.java
Normal file
186
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBean.java
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.management.*;
|
||||
import javax.swing.Icon;
|
||||
import sun.tools.jconsole.JConsole;
|
||||
import sun.tools.jconsole.MBeansTab;
|
||||
import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection;
|
||||
|
||||
public class XMBean {
|
||||
|
||||
private final MBeansTab mbeansTab;
|
||||
private final ObjectName objectName;
|
||||
private Icon icon;
|
||||
private String text;
|
||||
private Boolean broadcaster;
|
||||
private final Object broadcasterLock = new Object();
|
||||
private MBeanInfo mbeanInfo;
|
||||
private final Object mbeanInfoLock = new Object();
|
||||
|
||||
public XMBean(ObjectName objectName, MBeansTab mbeansTab) {
|
||||
this.mbeansTab = mbeansTab;
|
||||
this.objectName = objectName;
|
||||
text = objectName.getKeyProperty("name");
|
||||
if (text == null) {
|
||||
text = objectName.getDomain();
|
||||
}
|
||||
if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) {
|
||||
icon = IconManager.MBEANSERVERDELEGATE;
|
||||
} else {
|
||||
icon = IconManager.MBEAN;
|
||||
}
|
||||
}
|
||||
|
||||
MBeanServerConnection getMBeanServerConnection() {
|
||||
return mbeansTab.getMBeanServerConnection();
|
||||
}
|
||||
|
||||
SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() {
|
||||
return mbeansTab.getSnapshotMBeanServerConnection();
|
||||
}
|
||||
|
||||
public Boolean isBroadcaster() {
|
||||
synchronized (broadcasterLock) {
|
||||
if (broadcaster == null) {
|
||||
try {
|
||||
broadcaster = getMBeanServerConnection().isInstanceOf(
|
||||
getObjectName(),
|
||||
"javax.management.NotificationBroadcaster");
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Couldn't check if MBean [" +
|
||||
objectName + "] is a notification broadcaster");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return broadcaster;
|
||||
}
|
||||
}
|
||||
|
||||
public Object invoke(String operationName) throws Exception {
|
||||
Object result = getMBeanServerConnection().invoke(
|
||||
getObjectName(), operationName, new Object[0], new String[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object invoke(String operationName, Object params[], String sig[])
|
||||
throws Exception {
|
||||
Object result = getMBeanServerConnection().invoke(
|
||||
getObjectName(), operationName, params, sig);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setAttribute(Attribute attribute)
|
||||
throws AttributeNotFoundException, InstanceNotFoundException,
|
||||
InvalidAttributeValueException, MBeanException,
|
||||
ReflectionException, IOException {
|
||||
getMBeanServerConnection().setAttribute(getObjectName(), attribute);
|
||||
}
|
||||
|
||||
public Object getAttribute(String attributeName)
|
||||
throws AttributeNotFoundException, InstanceNotFoundException,
|
||||
MBeanException, ReflectionException, IOException {
|
||||
return getSnapshotMBeanServerConnection().getAttribute(
|
||||
getObjectName(), attributeName);
|
||||
}
|
||||
|
||||
public AttributeList getAttributes(String attributeNames[])
|
||||
throws AttributeNotFoundException, InstanceNotFoundException,
|
||||
MBeanException, ReflectionException, IOException {
|
||||
return getSnapshotMBeanServerConnection().getAttributes(
|
||||
getObjectName(), attributeNames);
|
||||
}
|
||||
|
||||
public AttributeList getAttributes(MBeanAttributeInfo attributeNames[])
|
||||
throws AttributeNotFoundException, InstanceNotFoundException,
|
||||
MBeanException, ReflectionException, IOException {
|
||||
String attributeString[] = new String[attributeNames.length];
|
||||
for (int i = 0; i < attributeNames.length; i++) {
|
||||
attributeString[i] = attributeNames[i].getName();
|
||||
}
|
||||
return getAttributes(attributeString);
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,
|
||||
IntrospectionException, ReflectionException, IOException {
|
||||
synchronized (mbeanInfoLock) {
|
||||
if (mbeanInfo == null) {
|
||||
mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);
|
||||
}
|
||||
return mbeanInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof XMBean)) {
|
||||
return false;
|
||||
}
|
||||
XMBean that = (XMBean) obj;
|
||||
return getObjectName().equals(that.getObjectName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (objectName == null ? 0 : objectName.hashCode());
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(Icon icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
}
|
||||
1075
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBeanAttributes.java
Normal file
1075
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBeanAttributes.java
Normal file
File diff suppressed because it is too large
Load Diff
413
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBeanInfo.java
Normal file
413
jdkSrc/jdk8/sun/tools/jconsole/inspector/XMBeanInfo.java
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GridLayout;
|
||||
import java.util.*;
|
||||
import javax.management.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.table.*;
|
||||
|
||||
import sun.tools.jconsole.Messages;
|
||||
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XMBeanInfo extends JPanel {
|
||||
|
||||
private static final Color lightYellow = new Color(255, 255, 128);
|
||||
private final int NAME_COLUMN = 0;
|
||||
private final int VALUE_COLUMN = 1;
|
||||
private final String[] columnNames = {
|
||||
Messages.NAME,
|
||||
Messages.VALUE
|
||||
};
|
||||
private JTable infoTable = new JTable();
|
||||
private JTable descTable = new JTable();
|
||||
private JPanel infoBorderPanel = new JPanel(new BorderLayout());
|
||||
private JPanel descBorderPanel = new JPanel(new BorderLayout());
|
||||
|
||||
private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object value, int row, int col) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class TableRowDivider {
|
||||
|
||||
private String tableRowDividerText;
|
||||
|
||||
public TableRowDivider(String tableRowDividerText) {
|
||||
this.tableRowDividerText = tableRowDividerText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tableRowDividerText;
|
||||
}
|
||||
}
|
||||
private static MBeanInfoTableCellRenderer renderer =
|
||||
new MBeanInfoTableCellRenderer();
|
||||
|
||||
private static class MBeanInfoTableCellRenderer
|
||||
extends DefaultTableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table, Object value, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
Component comp = super.getTableCellRendererComponent(
|
||||
table, value, isSelected, hasFocus, row, column);
|
||||
if (value instanceof TableRowDivider) {
|
||||
JLabel label = new JLabel(value.toString());
|
||||
label.setBackground(ensureContrast(lightYellow,
|
||||
label.getForeground()));
|
||||
label.setOpaque(true);
|
||||
return label;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
private static TableCellEditor editor =
|
||||
new MBeanInfoTableCellEditor(new JTextField());
|
||||
|
||||
private static class MBeanInfoTableCellEditor
|
||||
extends Utils.ReadOnlyTableCellEditor {
|
||||
|
||||
public MBeanInfoTableCellEditor(JTextField tf) {
|
||||
super(tf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellEditorComponent(
|
||||
JTable table, Object value, boolean isSelected,
|
||||
int row, int column) {
|
||||
Component comp = super.getTableCellEditorComponent(
|
||||
table, value, isSelected, row, column);
|
||||
if (value instanceof TableRowDivider) {
|
||||
JLabel label = new JLabel(value.toString());
|
||||
label.setBackground(ensureContrast(lightYellow,
|
||||
label.getForeground()));
|
||||
label.setOpaque(true);
|
||||
return label;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
public XMBeanInfo() {
|
||||
// Use the grid layout to display the two tables
|
||||
//
|
||||
super(new GridLayout(2, 1));
|
||||
// MBean*Info table
|
||||
//
|
||||
infoTable.setModel(new ReadOnlyDefaultTableModel());
|
||||
infoTable.setRowSelectionAllowed(false);
|
||||
infoTable.setColumnSelectionAllowed(false);
|
||||
infoTable.getTableHeader().setReorderingAllowed(false);
|
||||
((DefaultTableModel) infoTable.getModel()).setColumnIdentifiers(columnNames);
|
||||
infoTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140);
|
||||
infoTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140);
|
||||
infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer);
|
||||
infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer);
|
||||
infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor);
|
||||
infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor);
|
||||
infoTable.addKeyListener(new Utils.CopyKeyAdapter());
|
||||
infoTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
||||
JScrollPane infoTableScrollPane = new JScrollPane(infoTable);
|
||||
infoBorderPanel.setBorder(
|
||||
BorderFactory.createTitledBorder("MBeanInfoPlaceHolder"));
|
||||
infoBorderPanel.add(infoTableScrollPane);
|
||||
// Descriptor table
|
||||
//
|
||||
descTable.setModel(new ReadOnlyDefaultTableModel());
|
||||
descTable.setRowSelectionAllowed(false);
|
||||
descTable.setColumnSelectionAllowed(false);
|
||||
descTable.getTableHeader().setReorderingAllowed(false);
|
||||
((DefaultTableModel) descTable.getModel()).setColumnIdentifiers(columnNames);
|
||||
descTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140);
|
||||
descTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140);
|
||||
descTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer);
|
||||
descTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer);
|
||||
descTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor);
|
||||
descTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor);
|
||||
descTable.addKeyListener(new Utils.CopyKeyAdapter());
|
||||
descTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
||||
JScrollPane descTableScrollPane = new JScrollPane(descTable);
|
||||
descBorderPanel.setBorder(
|
||||
BorderFactory.createTitledBorder(Messages.DESCRIPTOR));
|
||||
descBorderPanel.add(descTableScrollPane);
|
||||
// Add the two tables to the grid
|
||||
//
|
||||
add(infoBorderPanel);
|
||||
add(descBorderPanel);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void emptyInfoTable() {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
while (tableModel.getRowCount() > 0) {
|
||||
tableModel.removeRow(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void emptyDescTable() {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
|
||||
while (tableModel.getRowCount() > 0) {
|
||||
tableModel.removeRow(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void addDescriptor(Descriptor desc, String text) {
|
||||
if (desc != null && desc.getFieldNames().length > 0) {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
for (String fieldName : desc.getFieldNames()) {
|
||||
rowData[0] = fieldName;
|
||||
Object fieldValue = desc.getFieldValue(fieldName);
|
||||
if (fieldValue instanceof boolean[]) {
|
||||
rowData[1] = Arrays.toString((boolean[]) fieldValue);
|
||||
} else if (fieldValue instanceof byte[]) {
|
||||
rowData[1] = Arrays.toString((byte[]) fieldValue);
|
||||
} else if (fieldValue instanceof char[]) {
|
||||
rowData[1] = Arrays.toString((char[]) fieldValue);
|
||||
} else if (fieldValue instanceof double[]) {
|
||||
rowData[1] = Arrays.toString((double[]) fieldValue);
|
||||
} else if (fieldValue instanceof float[]) {
|
||||
rowData[1] = Arrays.toString((float[]) fieldValue);
|
||||
} else if (fieldValue instanceof int[]) {
|
||||
rowData[1] = Arrays.toString((int[]) fieldValue);
|
||||
} else if (fieldValue instanceof long[]) {
|
||||
rowData[1] = Arrays.toString((long[]) fieldValue);
|
||||
} else if (fieldValue instanceof short[]) {
|
||||
rowData[1] = Arrays.toString((short[]) fieldValue);
|
||||
} else if (fieldValue instanceof Object[]) {
|
||||
rowData[1] = Arrays.toString((Object[]) fieldValue);
|
||||
} else {
|
||||
rowData[1] = fieldValue;
|
||||
}
|
||||
tableModel.addRow(rowData);
|
||||
}
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
|
||||
emptyInfoTable();
|
||||
emptyDescTable();
|
||||
((TitledBorder) infoBorderPanel.getBorder()).setTitle(
|
||||
Messages.MBEAN_INFO);
|
||||
String text = Messages.INFO + ":";
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.OBJECT_NAME;
|
||||
rowData[1] = mbean.getObjectName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.CLASS_NAME;
|
||||
rowData[1] = mbeanInfo.getClassName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mbeanInfo.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mbeanInfo.getDescriptor(), text);
|
||||
// MBeanConstructorInfo
|
||||
//
|
||||
int i = 0;
|
||||
for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) {
|
||||
addMBeanConstructorInfo(mbci,
|
||||
Messages.CONSTRUCTOR + "-" + i + ":");
|
||||
// MBeanParameterInfo
|
||||
//
|
||||
int j = 0;
|
||||
for (MBeanParameterInfo mbpi : mbci.getSignature()) {
|
||||
addMBeanParameterInfo(mbpi,
|
||||
Messages.PARAMETER + "-" + i + "-" + j + ":");
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
|
||||
emptyInfoTable();
|
||||
emptyDescTable();
|
||||
((TitledBorder) infoBorderPanel.getBorder()).setTitle(
|
||||
Messages.MBEAN_ATTRIBUTE_INFO);
|
||||
String text = Messages.ATTRIBUTE + ":";
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NAME;
|
||||
rowData[1] = mbai.getName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mbai.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.READABLE;
|
||||
rowData[1] = mbai.isReadable();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.WRITABLE;
|
||||
rowData[1] = mbai.isWritable();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.IS;
|
||||
rowData[1] = mbai.isIs();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.TYPE;
|
||||
rowData[1] = mbai.getType();
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mbai.getDescriptor(), text);
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
|
||||
emptyInfoTable();
|
||||
emptyDescTable();
|
||||
((TitledBorder) infoBorderPanel.getBorder()).setTitle(
|
||||
Messages.MBEAN_OPERATION_INFO);
|
||||
String text = Messages.OPERATION + ":";
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NAME;
|
||||
rowData[1] = mboi.getName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mboi.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.IMPACT;
|
||||
switch (mboi.getImpact()) {
|
||||
case MBeanOperationInfo.INFO:
|
||||
rowData[1] = Messages.INFO_CAPITALIZED;
|
||||
break;
|
||||
case MBeanOperationInfo.ACTION:
|
||||
rowData[1] = Messages.ACTION_CAPITALIZED;
|
||||
break;
|
||||
case MBeanOperationInfo.ACTION_INFO:
|
||||
rowData[1] = Messages.ACTION_INFO_CAPITALIZED;
|
||||
break;
|
||||
case MBeanOperationInfo.UNKNOWN:
|
||||
rowData[1] = Messages.UNKNOWN_CAPITALIZED;
|
||||
break;
|
||||
}
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.RETURN_TYPE;
|
||||
rowData[1] = mboi.getReturnType();
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mboi.getDescriptor(), text);
|
||||
// MBeanParameterInfo
|
||||
//
|
||||
int i = 0;
|
||||
for (MBeanParameterInfo mbpi : mboi.getSignature()) {
|
||||
addMBeanParameterInfo(mbpi,
|
||||
Messages.PARAMETER + "-" + i++ + ":");
|
||||
}
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
|
||||
emptyInfoTable();
|
||||
emptyDescTable();
|
||||
((TitledBorder) infoBorderPanel.getBorder()).setTitle(
|
||||
Messages.MBEAN_NOTIFICATION_INFO);
|
||||
String text = Messages.NOTIFICATION + ":";
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NAME;
|
||||
rowData[1] = mbni.getName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mbni.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NOTIF_TYPES;
|
||||
rowData[1] = Arrays.toString(mbni.getNotifTypes());
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mbni.getDescriptor(), text);
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NAME;
|
||||
rowData[1] = mbci.getName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mbci.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mbci.getDescriptor(), text);
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
|
||||
Object rowData[] = new Object[2];
|
||||
rowData[0] = new TableRowDivider(text);
|
||||
rowData[1] = new TableRowDivider("");
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.NAME;
|
||||
rowData[1] = mbpi.getName();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.DESCRIPTION;
|
||||
rowData[1] = mbpi.getDescription();
|
||||
tableModel.addRow(rowData);
|
||||
rowData[0] = Messages.TYPE;
|
||||
rowData[1] = mbpi.getType();
|
||||
tableModel.addRow(rowData);
|
||||
addDescriptor(mbpi.getDescriptor(), text);
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.*;
|
||||
import javax.swing.tree.*;
|
||||
import java.awt.Font;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.*;
|
||||
import java.awt.Dimension;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.TabularData;
|
||||
|
||||
import sun.tools.jconsole.JConsole;
|
||||
import sun.tools.jconsole.Messages;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XMBeanNotifications extends JTable implements NotificationListener {
|
||||
|
||||
private final static String[] columnNames = {
|
||||
Messages.TIME_STAMP,
|
||||
Messages.TYPE,
|
||||
Messages.USER_DATA,
|
||||
Messages.SEQ_NUM,
|
||||
Messages.MESSAGE,
|
||||
Messages.EVENT,
|
||||
Messages.SOURCE
|
||||
};
|
||||
private HashMap<ObjectName, XMBeanNotificationsListener> listeners =
|
||||
new HashMap<ObjectName, XMBeanNotificationsListener>();
|
||||
private volatile boolean subscribed;
|
||||
private XMBeanNotificationsListener currentListener;
|
||||
public final static String NOTIFICATION_RECEIVED_EVENT =
|
||||
"jconsole.xnotification.received";
|
||||
private List<NotificationListener> notificationListenersList;
|
||||
private volatile boolean enabled;
|
||||
private Font normalFont, boldFont;
|
||||
private int rowMinHeight = -1;
|
||||
private TableCellEditor userDataEditor = new UserDataCellEditor();
|
||||
private NotifMouseListener mouseListener = new NotifMouseListener();
|
||||
private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS");
|
||||
private static TableCellEditor editor =
|
||||
new Utils.ReadOnlyTableCellEditor(new JTextField());
|
||||
|
||||
public XMBeanNotifications() {
|
||||
super(new TableSorter(columnNames, 0));
|
||||
setColumnSelectionAllowed(false);
|
||||
setRowSelectionAllowed(false);
|
||||
getTableHeader().setReorderingAllowed(false);
|
||||
ArrayList<NotificationListener> l =
|
||||
new ArrayList<NotificationListener>(1);
|
||||
notificationListenersList = Collections.synchronizedList(l);
|
||||
|
||||
addMouseListener(mouseListener);
|
||||
|
||||
TableColumnModel colModel = getColumnModel();
|
||||
colModel.getColumn(0).setPreferredWidth(45);
|
||||
colModel.getColumn(1).setPreferredWidth(50);
|
||||
colModel.getColumn(2).setPreferredWidth(50);
|
||||
colModel.getColumn(3).setPreferredWidth(40);
|
||||
colModel.getColumn(4).setPreferredWidth(50);
|
||||
colModel.getColumn(5).setPreferredWidth(50);
|
||||
setColumnEditors();
|
||||
addKeyListener(new Utils.CopyKeyAdapter());
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void cancelCellEditing() {
|
||||
TableCellEditor tce = getCellEditor();
|
||||
if (tce != null) {
|
||||
tce.cancelCellEditing();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void stopCellEditing() {
|
||||
TableCellEditor tce = getCellEditor();
|
||||
if (tce != null) {
|
||||
tce.stopCellEditing();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int col) {
|
||||
UserDataCell cell = getUserDataCell(row, col);
|
||||
if (cell != null) {
|
||||
return cell.isMaximized();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
@Override
|
||||
public void setValueAt(Object value, int row, int column) {
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
@Override
|
||||
public synchronized Component prepareRenderer(
|
||||
TableCellRenderer renderer, int row, int column) {
|
||||
//In case we have a repaint thread that is in the process of
|
||||
//repainting an obsolete table, just ignore the call.
|
||||
//It can happen when MBean selection is switched at a very quick rate
|
||||
if (row >= getRowCount()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Component comp = super.prepareRenderer(renderer, row, column);
|
||||
|
||||
if (normalFont == null) {
|
||||
normalFont = comp.getFont();
|
||||
boldFont = normalFont.deriveFont(Font.BOLD);
|
||||
}
|
||||
UserDataCell cell = getUserDataCell(row, 2);
|
||||
if (column == 2 && cell != null) {
|
||||
comp.setFont(boldFont);
|
||||
int size = cell.getHeight();
|
||||
if (size > 0) {
|
||||
if (getRowHeight(row) != size) {
|
||||
setRowHeight(row, size);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
comp.setFont(normalFont);
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
@Override
|
||||
public synchronized TableCellRenderer getCellRenderer(int row, int column) {
|
||||
//In case we have a repaint thread that is in the process of
|
||||
//repainting an obsolete table, just ignore the call.
|
||||
//It can happen when MBean selection is switched at a very quick rate
|
||||
if (row >= getRowCount()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DefaultTableCellRenderer renderer;
|
||||
String toolTip = null;
|
||||
UserDataCell cell = getUserDataCell(row, column);
|
||||
if (cell != null && cell.isInited()) {
|
||||
renderer = (DefaultTableCellRenderer) cell.getRenderer();
|
||||
} else {
|
||||
renderer =
|
||||
(DefaultTableCellRenderer) super.getCellRenderer(row, column);
|
||||
}
|
||||
|
||||
if (cell != null) {
|
||||
toolTip = Messages.DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE+
|
||||
". " + cell.toString();
|
||||
} else {
|
||||
Object val =
|
||||
((DefaultTableModel) getModel()).getValueAt(row, column);
|
||||
if (val != null) {
|
||||
toolTip = val.toString();
|
||||
}
|
||||
}
|
||||
|
||||
renderer.setToolTipText(toolTip);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private UserDataCell getUserDataCell(int row, int column) {
|
||||
Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column);
|
||||
if (obj instanceof UserDataCell) {
|
||||
return (UserDataCell) obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized void dispose() {
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
public long getReceivedNotifications(XMBean mbean) {
|
||||
XMBeanNotificationsListener listener =
|
||||
listeners.get(mbean.getObjectName());
|
||||
if (listener == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return listener.getReceivedNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean clearCurrentNotifications() {
|
||||
emptyTable();
|
||||
if (currentListener != null) {
|
||||
currentListener.clear();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {
|
||||
XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
|
||||
return unregister(mbean.getObjectName());
|
||||
}
|
||||
|
||||
public synchronized void registerListener(DefaultMutableTreeNode node)
|
||||
throws InstanceNotFoundException, IOException {
|
||||
XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
|
||||
if (!subscribed) {
|
||||
try {
|
||||
mbean.getMBeanServerConnection().addNotificationListener(
|
||||
MBeanServerDelegate.DELEGATE_NAME, this, null, null);
|
||||
subscribed = true;
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Error adding listener for delegate:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
XMBeanNotificationsListener listener =
|
||||
listeners.get(mbean.getObjectName());
|
||||
if (listener == null) {
|
||||
listener = new XMBeanNotificationsListener(
|
||||
this, mbean, node, columnNames);
|
||||
listeners.put(mbean.getObjectName(), listener);
|
||||
} else {
|
||||
if (!listener.isRegistered()) {
|
||||
emptyTable();
|
||||
listener.register(node);
|
||||
}
|
||||
}
|
||||
enabled = true;
|
||||
currentListener = listener;
|
||||
}
|
||||
|
||||
public synchronized void handleNotification(
|
||||
Notification notif, Object handback) {
|
||||
try {
|
||||
if (notif instanceof MBeanServerNotification) {
|
||||
ObjectName mbean =
|
||||
((MBeanServerNotification) notif).getMBeanName();
|
||||
if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) {
|
||||
unregister(mbean);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Error unregistering notification:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void disableNotifications() {
|
||||
emptyTable();
|
||||
currentListener = null;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
private synchronized boolean unregister(ObjectName mbean) {
|
||||
XMBeanNotificationsListener listener = listeners.get(mbean);
|
||||
if (listener != null && listener.isRegistered()) {
|
||||
listener.unregister();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void addNotificationsListener(NotificationListener nl) {
|
||||
notificationListenersList.add(nl);
|
||||
}
|
||||
|
||||
public void removeNotificationsListener(NotificationListener nl) {
|
||||
notificationListenersList.remove(nl);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
void fireNotificationReceived(
|
||||
XMBeanNotificationsListener listener, XMBean mbean,
|
||||
DefaultMutableTreeNode node, Object[] rowData, long received) {
|
||||
if (enabled) {
|
||||
DefaultTableModel tableModel = (DefaultTableModel) getModel();
|
||||
if (listener == currentListener) {
|
||||
tableModel.insertRow(0, rowData);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
Notification notif =
|
||||
new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);
|
||||
notif.setUserData(received);
|
||||
for (NotificationListener nl : notificationListenersList) {
|
||||
nl.handleNotification(notif, node);
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void updateModel(List<Object[]> data) {
|
||||
emptyTable();
|
||||
DefaultTableModel tableModel = (DefaultTableModel) getModel();
|
||||
for (Object[] rowData : data) {
|
||||
tableModel.addRow(rowData);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isListenerRegistered(XMBean mbean) {
|
||||
XMBeanNotificationsListener listener =
|
||||
listeners.get(mbean.getObjectName());
|
||||
if (listener == null) {
|
||||
return false;
|
||||
}
|
||||
return listener.isRegistered();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void loadNotifications(XMBean mbean) {
|
||||
XMBeanNotificationsListener listener =
|
||||
listeners.get(mbean.getObjectName());
|
||||
emptyTable();
|
||||
if (listener != null) {
|
||||
enabled = true;
|
||||
List<Object[]> data = listener.getData();
|
||||
updateModel(data);
|
||||
currentListener = listener;
|
||||
validate();
|
||||
repaint();
|
||||
} else {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void setColumnEditors() {
|
||||
TableColumnModel tcm = getColumnModel();
|
||||
for (int i = 0; i < columnNames.length; i++) {
|
||||
TableColumn tc = tcm.getColumn(i);
|
||||
if (i == 2) {
|
||||
tc.setCellEditor(userDataEditor);
|
||||
} else {
|
||||
tc.setCellEditor(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public boolean isTableEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void emptyTable() {
|
||||
DefaultTableModel model = (DefaultTableModel) getModel();
|
||||
//invalidate();
|
||||
while (model.getRowCount() > 0) {
|
||||
model.removeRow(0);
|
||||
}
|
||||
validate();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
synchronized void updateUserDataCell(int row, int col) {
|
||||
Object obj = getModel().getValueAt(row, 2);
|
||||
if (obj instanceof UserDataCell) {
|
||||
UserDataCell cell = (UserDataCell) obj;
|
||||
if (!cell.isInited()) {
|
||||
if (rowMinHeight == -1) {
|
||||
rowMinHeight = getRowHeight(row);
|
||||
}
|
||||
cell.init(super.getCellRenderer(row, col), rowMinHeight);
|
||||
}
|
||||
|
||||
cell.switchState();
|
||||
setRowHeight(row, cell.getHeight());
|
||||
|
||||
if (!cell.isMaximized()) {
|
||||
cancelCellEditing();
|
||||
//Back to simple editor.
|
||||
editCellAt(row, 2);
|
||||
}
|
||||
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
class UserDataCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
Component comp;
|
||||
|
||||
UserDataCellRenderer(Component comp) {
|
||||
this.comp = comp;
|
||||
Dimension d = comp.getPreferredSize();
|
||||
if (d.getHeight() > 200) {
|
||||
comp.setPreferredSize(new Dimension((int) d.getWidth(), 200));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(
|
||||
JTable table,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
boolean hasFocus,
|
||||
int row,
|
||||
int column) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Component getComponent() {
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
class UserDataCell {
|
||||
|
||||
TableCellRenderer minRenderer;
|
||||
UserDataCellRenderer maxRenderer;
|
||||
int minHeight;
|
||||
boolean minimized = true;
|
||||
boolean init = false;
|
||||
Object userData;
|
||||
|
||||
UserDataCell(Object userData, Component max) {
|
||||
this.userData = userData;
|
||||
this.maxRenderer = new UserDataCellRenderer(max);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (userData == null) {
|
||||
return null;
|
||||
}
|
||||
if (userData.getClass().isArray()) {
|
||||
String name =
|
||||
Utils.getArrayClassName(userData.getClass().getName());
|
||||
int length = Array.getLength(userData);
|
||||
return name + "[" + length + "]";
|
||||
}
|
||||
|
||||
if (userData instanceof CompositeData ||
|
||||
userData instanceof TabularData) {
|
||||
return userData.getClass().getName();
|
||||
}
|
||||
|
||||
return userData.toString();
|
||||
}
|
||||
|
||||
boolean isInited() {
|
||||
return init;
|
||||
}
|
||||
|
||||
void init(TableCellRenderer minRenderer, int minHeight) {
|
||||
this.minRenderer = minRenderer;
|
||||
this.minHeight = minHeight;
|
||||
init = true;
|
||||
}
|
||||
|
||||
void switchState() {
|
||||
minimized = !minimized;
|
||||
}
|
||||
|
||||
boolean isMaximized() {
|
||||
return !minimized;
|
||||
}
|
||||
|
||||
void minimize() {
|
||||
minimized = true;
|
||||
}
|
||||
|
||||
void maximize() {
|
||||
minimized = false;
|
||||
}
|
||||
|
||||
int getHeight() {
|
||||
if (minimized) {
|
||||
return minHeight;
|
||||
} else {
|
||||
return (int) maxRenderer.getComponent().
|
||||
getPreferredSize().getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
TableCellRenderer getRenderer() {
|
||||
if (minimized) {
|
||||
return minRenderer;
|
||||
} else {
|
||||
return maxRenderer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NotifMouseListener extends MouseAdapter {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
if (e.getClickCount() >= 2) {
|
||||
int row = XMBeanNotifications.this.getSelectedRow();
|
||||
int col = XMBeanNotifications.this.getSelectedColumn();
|
||||
if (col != 2) {
|
||||
return;
|
||||
}
|
||||
if (col == -1 || row == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
XMBeanNotifications.this.updateUserDataCell(row, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UserDataCellEditor extends XTextFieldEditor {
|
||||
// implements javax.swing.table.TableCellEditor
|
||||
@Override
|
||||
public Component getTableCellEditorComponent(
|
||||
JTable table,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
int row,
|
||||
int column) {
|
||||
Object val = value;
|
||||
if (column == 2) {
|
||||
Object obj = getModel().getValueAt(row, column);
|
||||
if (obj instanceof UserDataCell) {
|
||||
UserDataCell cell = (UserDataCell) obj;
|
||||
if (cell.getRenderer() instanceof UserDataCellRenderer) {
|
||||
UserDataCellRenderer zr =
|
||||
(UserDataCellRenderer) cell.getRenderer();
|
||||
return zr.getComponent();
|
||||
}
|
||||
} else {
|
||||
Component comp = super.getTableCellEditorComponent(
|
||||
table, val, isSelected, row, column);
|
||||
textField.setEditable(false);
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
return super.getTableCellEditorComponent(
|
||||
table,
|
||||
val,
|
||||
isSelected,
|
||||
row,
|
||||
column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopCellEditing() {
|
||||
int editingRow = getEditingRow();
|
||||
int editingColumn = getEditingColumn();
|
||||
if (editingColumn == 2) {
|
||||
Object obj = getModel().getValueAt(editingRow, editingColumn);
|
||||
if (obj instanceof UserDataCell) {
|
||||
UserDataCell cell = (UserDataCell) obj;
|
||||
if (cell.isMaximized()) {
|
||||
cancelCellEditing();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.stopCellEditing();
|
||||
}
|
||||
}
|
||||
|
||||
class XMBeanNotificationsListener implements NotificationListener {
|
||||
|
||||
private XMBean xmbean;
|
||||
private DefaultMutableTreeNode node;
|
||||
private volatile long received;
|
||||
private XMBeanNotifications notifications;
|
||||
private volatile boolean unregistered;
|
||||
private ArrayList<Object[]> data = new ArrayList<Object[]>();
|
||||
|
||||
public XMBeanNotificationsListener(
|
||||
XMBeanNotifications notifications,
|
||||
XMBean xmbean,
|
||||
DefaultMutableTreeNode node,
|
||||
String[] columnNames) {
|
||||
this.notifications = notifications;
|
||||
this.xmbean = xmbean;
|
||||
this.node = node;
|
||||
register(node);
|
||||
}
|
||||
|
||||
public synchronized List<Object[]> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public synchronized void clear() {
|
||||
data.clear();
|
||||
received = 0;
|
||||
}
|
||||
|
||||
public synchronized boolean isRegistered() {
|
||||
return !unregistered;
|
||||
}
|
||||
|
||||
public synchronized void unregister() {
|
||||
try {
|
||||
xmbean.getMBeanServerConnection().removeNotificationListener(
|
||||
xmbean.getObjectName(), this, null, null);
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Error removing listener:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
unregistered = true;
|
||||
}
|
||||
|
||||
public synchronized long getReceivedNotifications() {
|
||||
return received;
|
||||
}
|
||||
|
||||
public synchronized void register(DefaultMutableTreeNode node) {
|
||||
clear();
|
||||
this.node = node;
|
||||
try {
|
||||
xmbean.getMBeanServerConnection().addNotificationListener(
|
||||
xmbean.getObjectName(), this, null, null);
|
||||
unregistered = false;
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Error adding listener:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void handleNotification(
|
||||
final Notification n, Object hb) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
synchronized (XMBeanNotificationsListener.this) {
|
||||
try {
|
||||
if (unregistered) {
|
||||
return;
|
||||
}
|
||||
Date receivedDate = new Date(n.getTimeStamp());
|
||||
String time = timeFormater.format(receivedDate);
|
||||
|
||||
Object userData = n.getUserData();
|
||||
Component comp = null;
|
||||
UserDataCell cell = null;
|
||||
if ((comp = XDataViewer.createNotificationViewer(userData)) != null) {
|
||||
XDataViewer.registerForMouseEvent(comp, mouseListener);
|
||||
cell = new UserDataCell(userData, comp);
|
||||
}
|
||||
|
||||
Object[] rowData = {
|
||||
time,
|
||||
n.getType(),
|
||||
(cell == null ? userData : cell),
|
||||
n.getSequenceNumber(),
|
||||
n.getMessage(),
|
||||
n,
|
||||
n.getSource()
|
||||
};
|
||||
received++;
|
||||
data.add(0, rowData);
|
||||
|
||||
notifications.fireNotificationReceived(
|
||||
XMBeanNotificationsListener.this,
|
||||
xmbean, node, rowData, received);
|
||||
} catch (Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Error handling notification:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import javax.management.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import sun.tools.jconsole.MBeansTab;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XMBeanOperations extends XOperations {
|
||||
|
||||
public XMBeanOperations(MBeansTab mbeansTab) {
|
||||
super(mbeansTab);
|
||||
}
|
||||
|
||||
protected MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations) {
|
||||
//remove get,set and is
|
||||
ArrayList<MBeanOperationInfo> mbeanOperations =
|
||||
new ArrayList<MBeanOperationInfo>(operations.length);
|
||||
for(MBeanOperationInfo operation : operations) {
|
||||
if (!( (operation.getSignature().length == 0 &&
|
||||
operation.getName().startsWith("get") &&
|
||||
!operation.getReturnType().equals("void")) ||
|
||||
(operation.getSignature().length == 1 &&
|
||||
operation.getName().startsWith("set") &&
|
||||
operation.getReturnType().equals("void")) ||
|
||||
(operation.getName().startsWith("is") &&
|
||||
operation.getReturnType().equals("boolean"))
|
||||
) ) {
|
||||
mbeanOperations.add(operation);
|
||||
}
|
||||
}
|
||||
return mbeanOperations.toArray(new MBeanOperationInfo[0]);
|
||||
}
|
||||
|
||||
}
|
||||
77
jdkSrc/jdk8/sun/tools/jconsole/inspector/XNodeInfo.java
Normal file
77
jdkSrc/jdk8/sun/tools/jconsole/inspector/XNodeInfo.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
/**
|
||||
* <p>This class represents the user object of the nodes in the MBean tree.</p>
|
||||
*
|
||||
* <p>It encapsulates the node's info, i.e. the type of the node, the label to
|
||||
* be used when displaying the node in the MBean tree, the node's tool tip text
|
||||
* and arbitrary data which varies depending on the type of the node: an XMBean
|
||||
* reference for MBEAN, ATTRIBUTES, OPERATIONS and NOTIFICATIONS nodes; the
|
||||
* corresponding MBeanInfo for ATTRIBUTE, OPERATION and NOTIFICATION nodes;
|
||||
* it is not used for NONMBEAN nodes.</p>
|
||||
*/
|
||||
public class XNodeInfo {
|
||||
|
||||
public static enum Type {
|
||||
MBEAN, NONMBEAN,
|
||||
ATTRIBUTES, OPERATIONS, NOTIFICATIONS,
|
||||
ATTRIBUTE, OPERATION, NOTIFICATION
|
||||
};
|
||||
|
||||
public XNodeInfo(Type type, Object data, String label, String tooltip) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.label = label;
|
||||
this.tooltip = tooltip;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getToolTipText() {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
|
||||
private Type type;
|
||||
private Object data;
|
||||
private String label;
|
||||
private String tooltip;
|
||||
}
|
||||
113
jdkSrc/jdk8/sun/tools/jconsole/inspector/XObject.java
Normal file
113
jdkSrc/jdk8/sun/tools/jconsole/inspector/XObject.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
// java import
|
||||
import javax.swing.*;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This provides a wrapper to the Object class to allow it to be
|
||||
displayed/manipulated as a GUI object.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class XObject extends JLabel {
|
||||
private Object object;
|
||||
private static boolean useHashCodeRepresentation = true;
|
||||
public final static XObject NULL_OBJECT = new XObject("null");
|
||||
public XObject (Object object, Icon icon) {
|
||||
this(object);
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
public XObject (Object object) {
|
||||
setObject(object);
|
||||
setHorizontalAlignment(SwingConstants.LEFT);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof XObject) {
|
||||
return Objects.equals(object, ((XObject)o).getObject());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return object.hashCode();
|
||||
}
|
||||
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
//if true the the object.hashcode is added to the label
|
||||
public static void
|
||||
useHashCodeRepresentation(boolean useHashCodeRepresentation) {
|
||||
XObject.useHashCodeRepresentation = useHashCodeRepresentation;
|
||||
}
|
||||
|
||||
public static boolean hashCodeRepresentation() {
|
||||
return useHashCodeRepresentation;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.object = object;
|
||||
// if the object is not a swing component,
|
||||
// use default icon
|
||||
try {
|
||||
String text = null;
|
||||
if (object instanceof JLabel) {
|
||||
setIcon(((JLabel)object).getIcon());
|
||||
if (getText() != null) {
|
||||
text = ((JLabel)object).getText();
|
||||
|
||||
}
|
||||
}
|
||||
else if (object instanceof JButton) {
|
||||
setIcon(((JButton)object).getIcon());
|
||||
if (getText() != null) {
|
||||
text = ((JButton)object).getText();
|
||||
}
|
||||
}
|
||||
else if (getText() != null) {
|
||||
text = object.toString();
|
||||
setIcon(IconManager.DEFAULT_XOBJECT);
|
||||
}
|
||||
if (text != null) {
|
||||
if (useHashCodeRepresentation && (this != NULL_OBJECT)) {
|
||||
text = text + " ("+object.hashCode()+")";
|
||||
}
|
||||
setText(text);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error setting XObject object :"+
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
816
jdkSrc/jdk8/sun/tools/jconsole/inspector/XOpenTypeViewer.java
Normal file
816
jdkSrc/jdk8/sun/tools/jconsole/inspector/XOpenTypeViewer.java
Normal file
@@ -0,0 +1,816 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.table.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.*;
|
||||
import java.awt.Dimension;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import javax.management.openmbean.*;
|
||||
|
||||
import sun.tools.jconsole.JConsole;
|
||||
import sun.tools.jconsole.Messages;
|
||||
import sun.tools.jconsole.Resources;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XOpenTypeViewer extends JPanel implements ActionListener {
|
||||
JButton prev, incr, decr, tabularPrev, tabularNext;
|
||||
JLabel compositeLabel, tabularLabel;
|
||||
JScrollPane container;
|
||||
XOpenTypeData current;
|
||||
XOpenTypeDataListener listener = new XOpenTypeDataListener();
|
||||
|
||||
private static final String compositeNavigationSingle =
|
||||
Messages.MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE;
|
||||
private static final String tabularNavigationSingle =
|
||||
Messages.MBEANS_TAB_TABULAR_NAVIGATION_SINGLE;
|
||||
|
||||
private static TableCellEditor editor =
|
||||
new Utils.ReadOnlyTableCellEditor(new JTextField());
|
||||
|
||||
class XOpenTypeDataListener extends MouseAdapter {
|
||||
XOpenTypeDataListener() {
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if(e.getButton() == MouseEvent.BUTTON1) {
|
||||
if(e.getClickCount() >= 2) {
|
||||
XOpenTypeData elem = getSelectedViewedOpenType();
|
||||
if(elem != null) {
|
||||
try {
|
||||
elem.viewed(XOpenTypeViewer.this);
|
||||
}catch(Exception ex) {
|
||||
//Nothing to change, the element
|
||||
//can't be displayed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private XOpenTypeData getSelectedViewedOpenType() {
|
||||
int row = XOpenTypeViewer.this.current.getSelectedRow();
|
||||
int col = XOpenTypeViewer.this.current.getSelectedColumn();
|
||||
Object elem =
|
||||
XOpenTypeViewer.this.current.getModel().getValueAt(row, col);
|
||||
if(elem instanceof XOpenTypeData)
|
||||
return (XOpenTypeData) elem;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static interface Navigatable {
|
||||
public void incrElement();
|
||||
public void decrElement();
|
||||
public boolean canDecrement();
|
||||
public boolean canIncrement();
|
||||
public int getElementCount();
|
||||
public int getSelectedElementIndex();
|
||||
}
|
||||
|
||||
static interface XViewedTabularData extends Navigatable {
|
||||
}
|
||||
|
||||
static interface XViewedArrayData extends Navigatable {
|
||||
}
|
||||
|
||||
static abstract class XOpenTypeData extends JTable {
|
||||
XOpenTypeData parent;
|
||||
protected int col1Width = -1;
|
||||
protected int col2Width = -1;
|
||||
private boolean init;
|
||||
private Font normalFont, boldFont;
|
||||
protected XOpenTypeData(XOpenTypeData parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public XOpenTypeData getViewedParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getToolTip(int row, int col) {
|
||||
if(col == 1) {
|
||||
Object value = getModel().getValueAt(row, col);
|
||||
if (value != null) {
|
||||
if(isClickableElement(value))
|
||||
return Messages.DOUBLE_CLICK_TO_VISUALIZE
|
||||
+ ". " + value.toString();
|
||||
else
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
DefaultTableCellRenderer tcr =
|
||||
(DefaultTableCellRenderer)super.getCellRenderer(row,column);
|
||||
tcr.setToolTipText(getToolTip(row,column));
|
||||
return tcr;
|
||||
}
|
||||
|
||||
public void renderKey(String key, Component comp) {
|
||||
comp.setFont(normalFont);
|
||||
}
|
||||
|
||||
public Component prepareRenderer(TableCellRenderer renderer,
|
||||
int row, int column) {
|
||||
Component comp = super.prepareRenderer(renderer, row, column);
|
||||
|
||||
if (normalFont == null) {
|
||||
normalFont = comp.getFont();
|
||||
boldFont = normalFont.deriveFont(Font.BOLD);
|
||||
}
|
||||
|
||||
Object o = ((DefaultTableModel) getModel()).getValueAt(row, column);
|
||||
if (column == 0) {
|
||||
String key = o.toString();
|
||||
renderKey(key, comp);
|
||||
} else {
|
||||
if (isClickableElement(o)) {
|
||||
comp.setFont(boldFont);
|
||||
} else {
|
||||
comp.setFont(normalFont);
|
||||
}
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
protected boolean isClickableElement(Object obj) {
|
||||
if (obj instanceof XOpenTypeData) {
|
||||
if (obj instanceof Navigatable) {
|
||||
return (((Navigatable) obj).getElementCount() != 0);
|
||||
} else {
|
||||
return (obj instanceof XCompositeData);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void updateColumnWidth() {
|
||||
if (!init) {
|
||||
TableColumnModel colModel = getColumnModel();
|
||||
if (col2Width == -1) {
|
||||
col1Width = col1Width * 7;
|
||||
if (col1Width <
|
||||
getPreferredScrollableViewportSize().getWidth()) {
|
||||
col1Width = (int)
|
||||
getPreferredScrollableViewportSize().getWidth();
|
||||
}
|
||||
colModel.getColumn(0).setPreferredWidth(col1Width);
|
||||
init = true;
|
||||
return;
|
||||
}
|
||||
col1Width = (col1Width * 7) + 7;
|
||||
col1Width = Math.max(col1Width, 70);
|
||||
col2Width = (col2Width * 7) + 7;
|
||||
if (col1Width + col2Width <
|
||||
getPreferredScrollableViewportSize().getWidth()) {
|
||||
col2Width = (int)
|
||||
getPreferredScrollableViewportSize().getWidth() -
|
||||
col1Width;
|
||||
}
|
||||
colModel.getColumn(0).setPreferredWidth(col1Width);
|
||||
colModel.getColumn(1).setPreferredWidth(col2Width);
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void viewed(XOpenTypeViewer viewer) throws Exception;
|
||||
|
||||
protected void initTable(String[] columnNames) {
|
||||
setRowSelectionAllowed(false);
|
||||
setColumnSelectionAllowed(false);
|
||||
getTableHeader().setReorderingAllowed(false);
|
||||
((DefaultTableModel) getModel()).setColumnIdentifiers(columnNames);
|
||||
for (Enumeration<TableColumn> e = getColumnModel().getColumns();
|
||||
e.hasMoreElements();) {
|
||||
TableColumn tc = e.nextElement();
|
||||
tc.setCellEditor(editor);
|
||||
}
|
||||
addKeyListener(new Utils.CopyKeyAdapter());
|
||||
setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
||||
setPreferredScrollableViewportSize(new Dimension(350, 200));
|
||||
}
|
||||
|
||||
protected void emptyTable() {
|
||||
invalidate();
|
||||
while (getModel().getRowCount()>0)
|
||||
((DefaultTableModel) getModel()).removeRow(0);
|
||||
validate();
|
||||
}
|
||||
|
||||
public void setValueAt(Object value, int row, int col) {
|
||||
}
|
||||
}
|
||||
|
||||
static class TabularDataComparator implements Comparator<CompositeData> {
|
||||
|
||||
private final List<String> indexNames;
|
||||
|
||||
public TabularDataComparator(TabularType type) {
|
||||
indexNames = type.getIndexNames();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(CompositeData o1, CompositeData o2) {
|
||||
for (String key : indexNames) {
|
||||
Object c1 = o1.get(key);
|
||||
Object c2 = o2.get(key);
|
||||
if (c1 instanceof Comparable && c2 instanceof Comparable) {
|
||||
int result = ((Comparable<Object>) c1).compareTo(c2);
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static class XTabularData extends XCompositeData
|
||||
implements XViewedTabularData {
|
||||
|
||||
final TabularData tabular;
|
||||
final TabularType type;
|
||||
int currentIndex = 0;
|
||||
final Object[] elements;
|
||||
final int size;
|
||||
private Font normalFont, italicFont;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public XTabularData(XOpenTypeData parent, TabularData tabular) {
|
||||
super(parent, accessFirstElement(tabular));
|
||||
this.tabular = tabular;
|
||||
type = tabular.getTabularType();
|
||||
size = tabular.values().size();
|
||||
if (size > 0) {
|
||||
// Order tabular data elements using index names
|
||||
List<CompositeData> data = new ArrayList<CompositeData>(
|
||||
(Collection<CompositeData>) tabular.values());
|
||||
Collections.sort(data, new TabularDataComparator(type));
|
||||
elements = data.toArray();
|
||||
loadCompositeData((CompositeData) elements[0]);
|
||||
} else {
|
||||
elements = new Object[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static CompositeData accessFirstElement(TabularData tabular) {
|
||||
if(tabular.values().size() == 0) return null;
|
||||
return (CompositeData) tabular.values().toArray()[0];
|
||||
}
|
||||
|
||||
public void renderKey(String key, Component comp) {
|
||||
if (normalFont == null) {
|
||||
normalFont = comp.getFont();
|
||||
italicFont = normalFont.deriveFont(Font.ITALIC);
|
||||
}
|
||||
for(Object k : type.getIndexNames()) {
|
||||
if(key.equals(k))
|
||||
comp.setFont(italicFont);
|
||||
}
|
||||
}
|
||||
|
||||
public int getElementCount() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getSelectedElementIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
public void incrElement() {
|
||||
currentIndex++;
|
||||
loadCompositeData((CompositeData)elements[currentIndex]);
|
||||
}
|
||||
|
||||
public void decrElement() {
|
||||
currentIndex--;
|
||||
loadCompositeData((CompositeData)elements[currentIndex]);
|
||||
}
|
||||
|
||||
public boolean canDecrement() {
|
||||
if(currentIndex == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canIncrement(){
|
||||
if(size == 0 ||
|
||||
currentIndex == size -1)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return type == null ? "" : type.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
static class XCompositeData extends XOpenTypeData {
|
||||
protected final String[] columnNames = {
|
||||
Messages.NAME, Messages.VALUE
|
||||
};
|
||||
CompositeData composite;
|
||||
|
||||
public XCompositeData() {
|
||||
super(null);
|
||||
initTable(columnNames);
|
||||
}
|
||||
|
||||
//In sync with array, no init table.
|
||||
public XCompositeData(XOpenTypeData parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public XCompositeData(XOpenTypeData parent,
|
||||
CompositeData composite) {
|
||||
super(parent);
|
||||
initTable(columnNames);
|
||||
if(composite != null) {
|
||||
this.composite = composite;
|
||||
loadCompositeData(composite);
|
||||
}
|
||||
}
|
||||
|
||||
public void viewed(XOpenTypeViewer viewer) throws Exception {
|
||||
viewer.setOpenType(this);
|
||||
updateColumnWidth();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return composite == null ? "" :
|
||||
composite.getCompositeType().getTypeName();
|
||||
}
|
||||
|
||||
protected Object formatKey(String key) {
|
||||
return key;
|
||||
}
|
||||
|
||||
private void load(CompositeData data) {
|
||||
CompositeType type = data.getCompositeType();
|
||||
Set<String> keys = type.keySet();
|
||||
Iterator<String> it = keys.iterator();
|
||||
Object[] rowData = new Object[2];
|
||||
while (it.hasNext()) {
|
||||
String key = (String) it.next();
|
||||
Object val = data.get(key);
|
||||
rowData[0] = formatKey(key);
|
||||
if (val == null) {
|
||||
rowData[1] = "";
|
||||
} else {
|
||||
OpenType<?> openType = type.getType(key);
|
||||
if (openType instanceof CompositeType) {
|
||||
rowData[1] =
|
||||
new XCompositeData(this, (CompositeData) val);
|
||||
} else if (openType instanceof ArrayType) {
|
||||
rowData[1] =
|
||||
new XArrayData(this, (ArrayType<?>) openType, val);
|
||||
} else if (openType instanceof SimpleType) {
|
||||
rowData[1] = val;
|
||||
} else if (openType instanceof TabularType) {
|
||||
rowData[1] = new XTabularData(this, (TabularData) val);
|
||||
}
|
||||
}
|
||||
// Update column width
|
||||
String str = null;
|
||||
if (rowData[0] != null) {
|
||||
str = rowData[0].toString();
|
||||
if (str.length() > col1Width) {
|
||||
col1Width = str.length();
|
||||
}
|
||||
}
|
||||
if (rowData[1] != null) {
|
||||
str = rowData[1].toString();
|
||||
if (str.length() > col2Width) {
|
||||
col2Width = str.length();
|
||||
}
|
||||
}
|
||||
((DefaultTableModel) getModel()).addRow(rowData);
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadCompositeData(CompositeData data) {
|
||||
composite = data;
|
||||
emptyTable();
|
||||
load(data);
|
||||
DefaultTableModel tableModel = (DefaultTableModel) getModel();
|
||||
tableModel.newDataAvailable(new TableModelEvent(tableModel));
|
||||
}
|
||||
}
|
||||
|
||||
static class XArrayData extends XCompositeData
|
||||
implements XViewedArrayData {
|
||||
|
||||
private int dimension;
|
||||
private int size;
|
||||
private OpenType<?> elemType;
|
||||
private Object val;
|
||||
private boolean isCompositeType;
|
||||
private boolean isTabularType;
|
||||
private int currentIndex;
|
||||
private CompositeData[] elements;
|
||||
private final String[] arrayColumns = {Messages.VALUE};
|
||||
private Font normalFont, boldFont;
|
||||
|
||||
XArrayData(XOpenTypeData parent, ArrayType<?> type, Object val) {
|
||||
this(parent, type.getDimension(), type.getElementOpenType(), val);
|
||||
}
|
||||
|
||||
XArrayData(XOpenTypeData parent, int dimension,
|
||||
OpenType<?> elemType, Object val) {
|
||||
super(parent);
|
||||
this.dimension = dimension;
|
||||
this.elemType = elemType;
|
||||
this.val = val;
|
||||
String[] columns = null;
|
||||
|
||||
if (dimension > 1) return;
|
||||
|
||||
isCompositeType = (elemType instanceof CompositeType);
|
||||
isTabularType = (elemType instanceof TabularType);
|
||||
columns = isCompositeType ? columnNames : arrayColumns;
|
||||
|
||||
initTable(columns);
|
||||
loadArray();
|
||||
}
|
||||
|
||||
public void viewed(XOpenTypeViewer viewer) throws Exception {
|
||||
if (size == 0)
|
||||
throw new Exception(Messages.EMPTY_ARRAY);
|
||||
if (dimension > 1)
|
||||
throw new Exception(Messages.DIMENSION_IS_NOT_SUPPORTED_COLON +
|
||||
dimension);
|
||||
super.viewed(viewer);
|
||||
}
|
||||
|
||||
public int getElementCount() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getSelectedElementIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
public void renderKey(String key, Component comp) {
|
||||
if (normalFont == null) {
|
||||
normalFont = comp.getFont();
|
||||
boldFont = normalFont.deriveFont(Font.BOLD);
|
||||
}
|
||||
if (isTabularType) {
|
||||
comp.setFont(boldFont);
|
||||
}
|
||||
}
|
||||
|
||||
public void incrElement() {
|
||||
currentIndex++;
|
||||
loadCompositeData(elements[currentIndex]);
|
||||
}
|
||||
|
||||
public void decrElement() {
|
||||
currentIndex--;
|
||||
loadCompositeData(elements[currentIndex]);
|
||||
}
|
||||
|
||||
public boolean canDecrement() {
|
||||
if (isCompositeType && currentIndex > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canIncrement() {
|
||||
if (isCompositeType && currentIndex < size - 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void loadArray() {
|
||||
if (isCompositeType) {
|
||||
elements = (CompositeData[]) val;
|
||||
size = elements.length;
|
||||
if (size != 0) {
|
||||
loadCompositeData(elements[0]);
|
||||
}
|
||||
} else {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
Object[] rowData = new Object[1];
|
||||
size = Array.getLength(val);
|
||||
for (int i = 0; i < size; i++) {
|
||||
rowData[0] = isTabularType ?
|
||||
new XTabularData(this, (TabularData) Array.get(val, i)) :
|
||||
Array.get(val, i);
|
||||
String str = rowData[0].toString();
|
||||
if (str.length() > col1Width) {
|
||||
col1Width = str.length();
|
||||
}
|
||||
((DefaultTableModel) getModel()).addRow(rowData);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (dimension > 1) {
|
||||
return Messages.DIMENSION_IS_NOT_SUPPORTED_COLON +
|
||||
dimension;
|
||||
} else {
|
||||
return elemType.getTypeName() + "[" + size + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The supplied value is viewable iff:
|
||||
* - it's a CompositeData/TabularData, or
|
||||
* - it's a non-empty array of CompositeData/TabularData, or
|
||||
* - it's a non-empty Collection of CompositeData/TabularData.
|
||||
*/
|
||||
public static boolean isViewableValue(Object value) {
|
||||
// Check for CompositeData/TabularData
|
||||
//
|
||||
if (value instanceof CompositeData || value instanceof TabularData) {
|
||||
return true;
|
||||
}
|
||||
// Check for non-empty array of CompositeData/TabularData
|
||||
//
|
||||
if (value instanceof CompositeData[] || value instanceof TabularData[]) {
|
||||
return Array.getLength(value) > 0;
|
||||
}
|
||||
// Check for non-empty Collection of CompositeData/TabularData
|
||||
//
|
||||
if (value instanceof Collection) {
|
||||
Collection<?> c = (Collection<?>) value;
|
||||
if (c.isEmpty()) {
|
||||
// Empty Collections are not viewable
|
||||
//
|
||||
return false;
|
||||
} else {
|
||||
// Only Collections of CompositeData/TabularData are viewable
|
||||
//
|
||||
return Utils.isUniformCollection(c, CompositeData.class) ||
|
||||
Utils.isUniformCollection(c, TabularData.class);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Component loadOpenType(Object value) {
|
||||
Component comp = null;
|
||||
if(isViewableValue(value)) {
|
||||
XOpenTypeViewer open =
|
||||
new XOpenTypeViewer(value);
|
||||
comp = open;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
private XOpenTypeViewer(Object value) {
|
||||
XOpenTypeData comp = null;
|
||||
if (value instanceof CompositeData) {
|
||||
comp = new XCompositeData(null, (CompositeData) value);
|
||||
} else if (value instanceof TabularData) {
|
||||
comp = new XTabularData(null, (TabularData) value);
|
||||
} else if (value instanceof CompositeData[]) {
|
||||
CompositeData cda[] = (CompositeData[]) value;
|
||||
CompositeType ct = cda[0].getCompositeType();
|
||||
comp = new XArrayData(null, 1, ct, cda);
|
||||
} else if (value instanceof TabularData[]) {
|
||||
TabularData tda[] = (TabularData[]) value;
|
||||
TabularType tt = tda[0].getTabularType();
|
||||
comp = new XArrayData(null, 1, tt, tda);
|
||||
} else if (value instanceof Collection) {
|
||||
// At this point we know 'value' is a uniform collection, either
|
||||
// Collection<CompositeData> or Collection<TabularData>, because
|
||||
// isViewableValue() has been called before calling the private
|
||||
// XOpenTypeViewer() constructor.
|
||||
//
|
||||
Object e = ((Collection<?>) value).iterator().next();
|
||||
if (e instanceof CompositeData) {
|
||||
Collection<?> cdc = (Collection<?>) value;
|
||||
CompositeData cda[] = cdc.toArray(new CompositeData[0]);
|
||||
CompositeType ct = cda[0].getCompositeType();
|
||||
comp = new XArrayData(null, 1, ct, cda);
|
||||
} else if (e instanceof TabularData) {
|
||||
Collection<?> tdc = (Collection<?>) value;
|
||||
TabularData tda[] = tdc.toArray(new TabularData[0]);
|
||||
TabularType tt = tda[0].getTabularType();
|
||||
comp = new XArrayData(null, 1, tt, tda);
|
||||
}
|
||||
}
|
||||
setupDisplay(comp);
|
||||
try {
|
||||
comp.viewed(this);
|
||||
} catch (Exception e) {
|
||||
// Nothing to change, the element can't be displayed
|
||||
if (JConsole.isDebug()) {
|
||||
System.out.println("Exception viewing openType : " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setOpenType(XOpenTypeData data) {
|
||||
if (current != null) {
|
||||
current.removeMouseListener(listener);
|
||||
}
|
||||
|
||||
current = data;
|
||||
|
||||
// Enable/Disable the previous (<<) button
|
||||
if (current.getViewedParent() == null) {
|
||||
prev.setEnabled(false);
|
||||
} else {
|
||||
prev.setEnabled(true);
|
||||
}
|
||||
|
||||
// Set the listener to handle double-click mouse events
|
||||
current.addMouseListener(listener);
|
||||
|
||||
// Enable/Disable the tabular buttons
|
||||
if (!(data instanceof XViewedTabularData)) {
|
||||
tabularPrev.setEnabled(false);
|
||||
tabularNext.setEnabled(false);
|
||||
tabularLabel.setText(tabularNavigationSingle);
|
||||
tabularLabel.setEnabled(false);
|
||||
} else {
|
||||
XViewedTabularData tabular = (XViewedTabularData) data;
|
||||
tabularNext.setEnabled(tabular.canIncrement());
|
||||
tabularPrev.setEnabled(tabular.canDecrement());
|
||||
boolean hasMoreThanOneElement =
|
||||
tabular.canIncrement() || tabular.canDecrement();
|
||||
if (hasMoreThanOneElement) {
|
||||
tabularLabel.setText(
|
||||
Resources.format(Messages.MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE,
|
||||
String.format("%d", tabular.getSelectedElementIndex() + 1),
|
||||
String.format("%d", tabular.getElementCount())));
|
||||
} else {
|
||||
tabularLabel.setText(tabularNavigationSingle);
|
||||
}
|
||||
tabularLabel.setEnabled(hasMoreThanOneElement);
|
||||
}
|
||||
|
||||
// Enable/Disable the composite buttons
|
||||
if (!(data instanceof XViewedArrayData)) {
|
||||
incr.setEnabled(false);
|
||||
decr.setEnabled(false);
|
||||
compositeLabel.setText(compositeNavigationSingle);
|
||||
compositeLabel.setEnabled(false);
|
||||
} else {
|
||||
XViewedArrayData array = (XViewedArrayData) data;
|
||||
incr.setEnabled(array.canIncrement());
|
||||
decr.setEnabled(array.canDecrement());
|
||||
boolean hasMoreThanOneElement =
|
||||
array.canIncrement() || array.canDecrement();
|
||||
if (hasMoreThanOneElement) {
|
||||
compositeLabel.setText(
|
||||
Resources.format(Messages.MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE,
|
||||
String.format("%d", array.getSelectedElementIndex() + 1),
|
||||
String.format("%d", array.getElementCount())));
|
||||
} else {
|
||||
compositeLabel.setText(compositeNavigationSingle);
|
||||
}
|
||||
compositeLabel.setEnabled(hasMoreThanOneElement);
|
||||
}
|
||||
|
||||
container.invalidate();
|
||||
container.setViewportView(current);
|
||||
container.validate();
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (event.getSource() instanceof JButton) {
|
||||
JButton b = (JButton) event.getSource();
|
||||
if (b == prev) {
|
||||
XOpenTypeData parent = current.getViewedParent();
|
||||
try {
|
||||
parent.viewed(this);
|
||||
} catch (Exception e) {
|
||||
//Nothing to change, the element can't be displayed
|
||||
}
|
||||
} else if (b == incr) {
|
||||
((XViewedArrayData) current).incrElement();
|
||||
try {
|
||||
current.viewed(this);
|
||||
} catch (Exception e) {
|
||||
//Nothing to change, the element can't be displayed
|
||||
}
|
||||
} else if (b == decr) {
|
||||
((XViewedArrayData) current).decrElement();
|
||||
try {
|
||||
current.viewed(this);
|
||||
} catch (Exception e) {
|
||||
//Nothing to change, the element can't be displayed
|
||||
}
|
||||
} else if (b == tabularNext) {
|
||||
((XViewedTabularData) current).incrElement();
|
||||
try {
|
||||
current.viewed(this);
|
||||
} catch (Exception e) {
|
||||
//Nothing to change, the element can't be displayed
|
||||
}
|
||||
} else if (b == tabularPrev) {
|
||||
((XViewedTabularData) current).decrElement();
|
||||
try {
|
||||
current.viewed(this);
|
||||
} catch (Exception e) {
|
||||
//Nothing to change, the element can't be displayed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupDisplay(XOpenTypeData data) {
|
||||
setBackground(Color.white);
|
||||
container =
|
||||
new JScrollPane(data,
|
||||
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
|
||||
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
tabularPrev = new JButton(Messages.LESS_THAN);
|
||||
tabularNext = new JButton(Messages.GREATER_THAN);
|
||||
JPanel tabularButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
tabularButtons.add(tabularPrev);
|
||||
tabularPrev.addActionListener(this);
|
||||
tabularLabel = new JLabel(tabularNavigationSingle);
|
||||
tabularLabel.setEnabled(false);
|
||||
tabularButtons.add(tabularLabel);
|
||||
tabularButtons.add(tabularNext);
|
||||
tabularNext.addActionListener(this);
|
||||
tabularButtons.setBackground(Color.white);
|
||||
|
||||
prev = new JButton(Messages.A_LOT_LESS_THAN);
|
||||
prev.addActionListener(this);
|
||||
buttons.add(prev);
|
||||
|
||||
incr = new JButton(Messages.GREATER_THAN);
|
||||
incr.addActionListener(this);
|
||||
decr = new JButton(Messages.LESS_THAN);
|
||||
decr.addActionListener(this);
|
||||
|
||||
JPanel array = new JPanel();
|
||||
array.setBackground(Color.white);
|
||||
array.add(decr);
|
||||
compositeLabel = new JLabel(compositeNavigationSingle);
|
||||
compositeLabel.setEnabled(false);
|
||||
array.add(compositeLabel);
|
||||
array.add(incr);
|
||||
|
||||
buttons.add(array);
|
||||
setLayout(new BorderLayout());
|
||||
buttons.setBackground(Color.white);
|
||||
|
||||
JPanel navigationPanel = new JPanel(new BorderLayout());
|
||||
navigationPanel.setBackground(Color.white);
|
||||
navigationPanel.add(tabularButtons, BorderLayout.NORTH);
|
||||
navigationPanel.add(buttons, BorderLayout.WEST);
|
||||
add(navigationPanel, BorderLayout.NORTH);
|
||||
|
||||
add(container, BorderLayout.CENTER);
|
||||
Dimension d = new Dimension((int)container.getPreferredSize().
|
||||
getWidth() + 20,
|
||||
(int)container.getPreferredSize().
|
||||
getHeight() + 20);
|
||||
setPreferredSize(d);
|
||||
}
|
||||
}
|
||||
222
jdkSrc/jdk8/sun/tools/jconsole/inspector/XOperations.java
Normal file
222
jdkSrc/jdk8/sun/tools/jconsole/inspector/XOperations.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.management.*;
|
||||
|
||||
import sun.tools.jconsole.MBeansTab;
|
||||
import sun.tools.jconsole.JConsole;
|
||||
import sun.tools.jconsole.Messages;
|
||||
|
||||
public abstract class XOperations extends JPanel implements ActionListener {
|
||||
|
||||
public final static String OPERATION_INVOCATION_EVENT =
|
||||
"jam.xoperations.invoke.result";
|
||||
private java.util.List<NotificationListener> notificationListenersList;
|
||||
private Hashtable<JButton, OperationEntry> operationEntryTable;
|
||||
private XMBean mbean;
|
||||
private MBeanInfo mbeanInfo;
|
||||
private MBeansTab mbeansTab;
|
||||
|
||||
public XOperations(MBeansTab mbeansTab) {
|
||||
super(new GridLayout(1, 1));
|
||||
this.mbeansTab = mbeansTab;
|
||||
operationEntryTable = new Hashtable<JButton, OperationEntry>();
|
||||
ArrayList<NotificationListener> l =
|
||||
new ArrayList<NotificationListener>(1);
|
||||
notificationListenersList =
|
||||
Collections.synchronizedList(l);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void removeOperations() {
|
||||
removeAll();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) {
|
||||
this.mbean = mbean;
|
||||
this.mbeanInfo = mbeanInfo;
|
||||
// add operations information
|
||||
MBeanOperationInfo operations[] = mbeanInfo.getOperations();
|
||||
invalidate();
|
||||
|
||||
// remove listeners, if any
|
||||
Component listeners[] = getComponents();
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
if (listeners[i] instanceof JButton) {
|
||||
((JButton) listeners[i]).removeActionListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
removeAll();
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JButton methodButton;
|
||||
JLabel methodLabel;
|
||||
JPanel innerPanelLeft, innerPanelRight;
|
||||
JPanel outerPanelLeft, outerPanelRight;
|
||||
outerPanelLeft = new JPanel(new GridLayout(operations.length, 1));
|
||||
outerPanelRight = new JPanel(new GridLayout(operations.length, 1));
|
||||
|
||||
for (int i = 0; i < operations.length; i++) {
|
||||
innerPanelLeft = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
String returnType = operations[i].getReturnType();
|
||||
if (returnType == null) {
|
||||
methodLabel = new JLabel("null", JLabel.RIGHT);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println(
|
||||
"WARNING: The operation's return type " +
|
||||
"shouldn't be \"null\". Check how the " +
|
||||
"MBeanOperationInfo for the \"" +
|
||||
operations[i].getName() + "\" operation has " +
|
||||
"been defined in the MBean's implementation code.");
|
||||
}
|
||||
} else {
|
||||
methodLabel = new JLabel(
|
||||
Utils.getReadableClassName(returnType), JLabel.RIGHT);
|
||||
}
|
||||
innerPanelLeft.add(methodLabel);
|
||||
if (methodLabel.getText().length() > 20) {
|
||||
methodLabel.setText(methodLabel.getText().
|
||||
substring(methodLabel.getText().
|
||||
lastIndexOf(".") + 1,
|
||||
methodLabel.getText().length()));
|
||||
}
|
||||
|
||||
methodButton = new JButton(operations[i].getName());
|
||||
methodButton.setToolTipText(operations[i].getDescription());
|
||||
boolean callable = isCallable(operations[i].getSignature());
|
||||
if (callable) {
|
||||
methodButton.addActionListener(this);
|
||||
} else {
|
||||
methodButton.setEnabled(false);
|
||||
}
|
||||
|
||||
MBeanParameterInfo[] signature = operations[i].getSignature();
|
||||
OperationEntry paramEntry = new OperationEntry(operations[i],
|
||||
callable,
|
||||
methodButton,
|
||||
this);
|
||||
operationEntryTable.put(methodButton, paramEntry);
|
||||
innerPanelRight.add(methodButton);
|
||||
if (signature.length == 0) {
|
||||
innerPanelRight.add(new JLabel("( )", JLabel.CENTER));
|
||||
} else {
|
||||
innerPanelRight.add(paramEntry);
|
||||
}
|
||||
|
||||
outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST);
|
||||
outerPanelRight.add(innerPanelRight, BorderLayout.CENTER);
|
||||
}
|
||||
add(outerPanelLeft, BorderLayout.WEST);
|
||||
add(outerPanelRight, BorderLayout.CENTER);
|
||||
validate();
|
||||
}
|
||||
|
||||
private boolean isCallable(MBeanParameterInfo[] signature) {
|
||||
for (int i = 0; i < signature.length; i++) {
|
||||
if (!Utils.isEditableType(signature[i].getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
performInvokeRequest((JButton) e.getSource());
|
||||
}
|
||||
|
||||
void performInvokeRequest(final JButton button) {
|
||||
final OperationEntry entryIf = operationEntryTable.get(button);
|
||||
new SwingWorker<Object, Void>() {
|
||||
@Override
|
||||
public Object doInBackground() throws Exception {
|
||||
return mbean.invoke(button.getText(),
|
||||
entryIf.getParameters(), entryIf.getSignature());
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
Object result = get();
|
||||
// sends result notification to upper level if
|
||||
// there is a return value
|
||||
if (entryIf.getReturnType() != null &&
|
||||
!entryIf.getReturnType().equals(Void.TYPE.getName()) &&
|
||||
!entryIf.getReturnType().equals(Void.class.getName())) {
|
||||
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
|
||||
} else {
|
||||
new ThreadDialog(
|
||||
button,
|
||||
Messages.METHOD_SUCCESSFULLY_INVOKED,
|
||||
Messages.INFO,
|
||||
JOptionPane.INFORMATION_MESSAGE).run();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t = Utils.getActualException(t);
|
||||
if (JConsole.isDebug()) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
new ThreadDialog(
|
||||
button,
|
||||
Messages.PROBLEM_INVOKING + " " +
|
||||
button.getText() + " : " + t.toString(),
|
||||
Messages.ERROR,
|
||||
JOptionPane.ERROR_MESSAGE).run();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
public void addOperationsListener(NotificationListener nl) {
|
||||
notificationListenersList.add(nl);
|
||||
}
|
||||
|
||||
public void removeOperationsListener(NotificationListener nl) {
|
||||
notificationListenersList.remove(nl);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void fireChangedNotification(
|
||||
String type, Object source, Object handback) {
|
||||
Notification n = new Notification(type, source, 0);
|
||||
for (NotificationListener nl : notificationListenersList) {
|
||||
nl.handleNotification(n, handback);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations);
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/tools/jconsole/inspector/XPlotter.java
Normal file
44
jdkSrc/jdk8/sun/tools/jconsole/inspector/XPlotter.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import sun.tools.jconsole.Plotter;
|
||||
import javax.swing.JTable;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XPlotter extends Plotter {
|
||||
JTable table;
|
||||
public XPlotter(JTable table,
|
||||
Plotter.Unit unit) {
|
||||
super(unit,0,false);
|
||||
this.table = table;
|
||||
}
|
||||
@Override
|
||||
public void addValues(long time, long... values) {
|
||||
super.addValues(time, values);
|
||||
table.repaint();
|
||||
}
|
||||
}
|
||||
218
jdkSrc/jdk8/sun/tools/jconsole/inspector/XPlottingViewer.java
Normal file
218
jdkSrc/jdk8/sun/tools/jconsole/inspector/XPlottingViewer.java
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
import java.util.Timer;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import sun.tools.jconsole.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XPlottingViewer extends PlotterPanel implements ActionListener {
|
||||
// TODO: Make number of decimal places customizable
|
||||
private static final int PLOTTER_DECIMALS = 4;
|
||||
|
||||
private JButton plotButton;
|
||||
// The plotter cache holds Plotter instances for the various attributes
|
||||
private static HashMap<String, XPlottingViewer> plotterCache =
|
||||
new HashMap<String, XPlottingViewer>();
|
||||
private static HashMap<String, Timer> timerCache =
|
||||
new HashMap<String, Timer>();
|
||||
private MBeansTab tab;
|
||||
private String attributeName;
|
||||
private String key;
|
||||
private JTable table;
|
||||
private XPlottingViewer(String key,
|
||||
XMBean mbean,
|
||||
String attributeName,
|
||||
Object value,
|
||||
JTable table,
|
||||
MBeansTab tab) {
|
||||
super(null);
|
||||
|
||||
this.tab = tab;
|
||||
this.key = key;
|
||||
this.table = table;
|
||||
this.attributeName = attributeName;
|
||||
Plotter plotter = createPlotter(mbean, attributeName, key, table);
|
||||
setupDisplay(plotter);
|
||||
}
|
||||
|
||||
static void dispose(MBeansTab tab) {
|
||||
Iterator<String> it = plotterCache.keySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
String key = it.next();
|
||||
if(key.startsWith(String.valueOf(tab.hashCode()))) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
//plotterCache.clear();
|
||||
it = timerCache.keySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
String key = (String) it.next();
|
||||
if(key.startsWith(String.valueOf(tab.hashCode()))) {
|
||||
Timer t = timerCache.get(key);
|
||||
t.cancel();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isViewableValue(Object value) {
|
||||
return (value instanceof Number);
|
||||
}
|
||||
|
||||
//Fired by dbl click
|
||||
public static Component loadPlotting(XMBean mbean,
|
||||
String attributeName,
|
||||
Object value,
|
||||
JTable table,
|
||||
MBeansTab tab) {
|
||||
Component comp = null;
|
||||
if(isViewableValue(value)) {
|
||||
String key = String.valueOf(tab.hashCode()) + " " + String.valueOf(mbean.hashCode()) + " " + mbean.getObjectName().getCanonicalName() + attributeName;
|
||||
XPlottingViewer plotter = plotterCache.get(key);
|
||||
if(plotter == null) {
|
||||
plotter = new XPlottingViewer(key,
|
||||
mbean,
|
||||
attributeName,
|
||||
value,
|
||||
table,
|
||||
tab);
|
||||
plotterCache.put(key, plotter);
|
||||
}
|
||||
|
||||
comp = plotter;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
/*public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
setBackground(g.getColor());
|
||||
plotter.paintComponent(g);
|
||||
}*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
plotterCache.remove(key);
|
||||
Timer t = timerCache.remove(key);
|
||||
t.cancel();
|
||||
((XMBeanAttributes) table).collapse(attributeName, this);
|
||||
}
|
||||
|
||||
//Create plotter instance
|
||||
public Plotter createPlotter(final XMBean xmbean,
|
||||
final String attributeName,
|
||||
String key,
|
||||
JTable table) {
|
||||
final Plotter plotter = new XPlotter(table, Plotter.Unit.NONE) {
|
||||
Dimension prefSize = new Dimension(400, 170);
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return prefSize;
|
||||
}
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return prefSize;
|
||||
}
|
||||
};
|
||||
|
||||
plotter.createSequence(attributeName, attributeName, null, true);
|
||||
|
||||
TimerTask timerTask = new TimerTask() {
|
||||
public void run() {
|
||||
tab.workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Number n =
|
||||
(Number) xmbean.getSnapshotMBeanServerConnection().getAttribute(xmbean.getObjectName(), attributeName);
|
||||
long v;
|
||||
if (n instanceof Float || n instanceof Double) {
|
||||
plotter.setDecimals(PLOTTER_DECIMALS);
|
||||
double d = (n instanceof Float) ? (Float)n : (Double)n;
|
||||
v = Math.round(d * Math.pow(10.0, PLOTTER_DECIMALS));
|
||||
} else {
|
||||
v = n.longValue();
|
||||
}
|
||||
plotter.addValues(System.currentTimeMillis(), v);
|
||||
} catch (Exception ex) {
|
||||
// Should have a trace logged with proper
|
||||
// trace mecchanism
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
String timerName = "Timer-" + key;
|
||||
Timer timer = new Timer(timerName, true);
|
||||
timer.schedule(timerTask, 0, tab.getUpdateInterval());
|
||||
timerCache.put(key, timer);
|
||||
return plotter;
|
||||
}
|
||||
|
||||
private void setupDisplay(Plotter plotter) {
|
||||
final JPanel buttonPanel = new JPanel();
|
||||
final GridBagLayout gbl = new GridBagLayout();
|
||||
buttonPanel.setLayout(gbl);
|
||||
setLayout(new BorderLayout());
|
||||
plotButton = new JButton(Messages.DISCARD_CHART);
|
||||
plotButton.addActionListener(this);
|
||||
plotButton.setEnabled(true);
|
||||
|
||||
GridBagConstraints buttonConstraints = new GridBagConstraints();
|
||||
buttonConstraints.gridx = 0;
|
||||
buttonConstraints.gridy = 0;
|
||||
buttonConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
buttonConstraints.anchor = GridBagConstraints.CENTER;
|
||||
gbl.setConstraints(plotButton, buttonConstraints);
|
||||
buttonPanel.add(plotButton);
|
||||
|
||||
if (attributeName != null && attributeName.length()!=0) {
|
||||
final JPanel plotterLabelPanel = new JPanel();
|
||||
final JLabel label = new JLabel(attributeName);
|
||||
final GridBagLayout gbl2 = new GridBagLayout();
|
||||
plotterLabelPanel.setLayout(gbl2);
|
||||
final GridBagConstraints labelConstraints = new GridBagConstraints();
|
||||
labelConstraints.gridx = 0;
|
||||
labelConstraints.gridy = 0;
|
||||
labelConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
labelConstraints.anchor = GridBagConstraints.CENTER;
|
||||
labelConstraints.ipady = 10;
|
||||
gbl2.setConstraints(label, labelConstraints);
|
||||
plotterLabelPanel.add(label);
|
||||
add(plotterLabelPanel, BorderLayout.NORTH);
|
||||
}
|
||||
setPlotter(plotter);
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
repaint();
|
||||
}
|
||||
|
||||
}
|
||||
749
jdkSrc/jdk8/sun/tools/jconsole/inspector/XSheet.java
Normal file
749
jdkSrc/jdk8/sun/tools/jconsole/inspector/XSheet.java
Normal file
@@ -0,0 +1,749 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.management.IntrospectionException;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.ReflectionException;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanOperationInfo;
|
||||
import javax.management.MBeanNotificationInfo;
|
||||
import javax.management.Notification;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
|
||||
import sun.tools.jconsole.*;
|
||||
import sun.tools.jconsole.inspector.XNodeInfo.Type;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XSheet extends JPanel
|
||||
implements ActionListener, NotificationListener {
|
||||
|
||||
private JPanel mainPanel;
|
||||
private JPanel southPanel;
|
||||
// Node being currently displayed
|
||||
private volatile DefaultMutableTreeNode currentNode;
|
||||
// MBean being currently displayed
|
||||
private volatile XMBean mbean;
|
||||
// XMBeanAttributes container
|
||||
private XMBeanAttributes mbeanAttributes;
|
||||
// XMBeanOperations container
|
||||
private XMBeanOperations mbeanOperations;
|
||||
// XMBeanNotifications container
|
||||
private XMBeanNotifications mbeanNotifications;
|
||||
// XMBeanInfo container
|
||||
private XMBeanInfo mbeanInfo;
|
||||
// Refresh JButton (mbean attributes case)
|
||||
private JButton refreshButton;
|
||||
// Subscribe/Unsubscribe/Clear JButton (mbean notifications case)
|
||||
private JButton clearButton, subscribeButton, unsubscribeButton;
|
||||
// Reference to MBeans tab
|
||||
private MBeansTab mbeansTab;
|
||||
|
||||
public XSheet(MBeansTab mbeansTab) {
|
||||
this.mbeansTab = mbeansTab;
|
||||
setupScreen();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
clear();
|
||||
XDataViewer.dispose(mbeansTab);
|
||||
mbeanNotifications.dispose();
|
||||
}
|
||||
|
||||
private void setupScreen() {
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(BorderFactory.createLineBorder(Color.GRAY));
|
||||
// add main panel to XSheet
|
||||
mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
add(mainPanel, BorderLayout.CENTER);
|
||||
// add south panel to XSheet
|
||||
southPanel = new JPanel();
|
||||
add(southPanel, BorderLayout.SOUTH);
|
||||
// create the refresh button
|
||||
refreshButton = new JButton(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON);
|
||||
refreshButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON));
|
||||
refreshButton.setToolTipText(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP);
|
||||
refreshButton.addActionListener(this);
|
||||
// create the clear button
|
||||
clearButton = new JButton(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON);
|
||||
clearButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON));
|
||||
clearButton.setToolTipText(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP);
|
||||
clearButton.addActionListener(this);
|
||||
// create the subscribe button
|
||||
subscribeButton = new JButton(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON);
|
||||
subscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON));
|
||||
subscribeButton.setToolTipText(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);
|
||||
subscribeButton.addActionListener(this);
|
||||
// create the unsubscribe button
|
||||
unsubscribeButton = new JButton(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON);
|
||||
unsubscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON));
|
||||
unsubscribeButton.setToolTipText(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);
|
||||
unsubscribeButton.addActionListener(this);
|
||||
// create XMBeanAttributes container
|
||||
mbeanAttributes = new XMBeanAttributes(mbeansTab);
|
||||
// create XMBeanOperations container
|
||||
mbeanOperations = new XMBeanOperations(mbeansTab);
|
||||
mbeanOperations.addOperationsListener(this);
|
||||
// create XMBeanNotifications container
|
||||
mbeanNotifications = new XMBeanNotifications();
|
||||
mbeanNotifications.addNotificationsListener(this);
|
||||
// create XMBeanInfo container
|
||||
mbeanInfo = new XMBeanInfo();
|
||||
}
|
||||
|
||||
private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
|
||||
return (cn == n);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void showErrorDialog(Object message, String title) {
|
||||
new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();
|
||||
}
|
||||
|
||||
public boolean isMBeanNode(DefaultMutableTreeNode node) {
|
||||
Object userObject = node.getUserObject();
|
||||
if (userObject instanceof XNodeInfo) {
|
||||
XNodeInfo uo = (XNodeInfo) userObject;
|
||||
return uo.getType().equals(Type.MBEAN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void displayNode(DefaultMutableTreeNode node) {
|
||||
clear();
|
||||
displayEmptyNode();
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
currentNode = node;
|
||||
Object userObject = node.getUserObject();
|
||||
if (userObject instanceof XNodeInfo) {
|
||||
XNodeInfo uo = (XNodeInfo) userObject;
|
||||
switch (uo.getType()) {
|
||||
case MBEAN:
|
||||
displayMBeanNode(node);
|
||||
break;
|
||||
case NONMBEAN:
|
||||
displayEmptyNode();
|
||||
break;
|
||||
case ATTRIBUTES:
|
||||
displayMBeanAttributesNode(node);
|
||||
break;
|
||||
case OPERATIONS:
|
||||
displayMBeanOperationsNode(node);
|
||||
break;
|
||||
case NOTIFICATIONS:
|
||||
displayMBeanNotificationsNode(node);
|
||||
break;
|
||||
case ATTRIBUTE:
|
||||
case OPERATION:
|
||||
case NOTIFICATION:
|
||||
displayMetadataNode(node);
|
||||
break;
|
||||
default:
|
||||
displayEmptyNode();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
displayEmptyNode();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayMBeanNode(final DefaultMutableTreeNode node) {
|
||||
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
|
||||
if (!uo.getType().equals(Type.MBEAN)) {
|
||||
return;
|
||||
}
|
||||
mbean = (XMBean) uo.getData();
|
||||
SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
|
||||
@Override
|
||||
public MBeanInfo doInBackground() throws InstanceNotFoundException,
|
||||
IntrospectionException, ReflectionException, IOException {
|
||||
return mbean.getMBeanInfo();
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
MBeanInfo mbi = get();
|
||||
if (mbi != null) {
|
||||
if (!isSelectedNode(node, currentNode)) {
|
||||
return;
|
||||
}
|
||||
mbeanInfo.addMBeanInfo(mbean, mbi);
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
mainPanel.add(mbeanInfo, BorderLayout.CENTER);
|
||||
southPanel.setVisible(false);
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Couldn't get MBeanInfo for MBean [" +
|
||||
mbean.getObjectName() + "]");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.toString(),
|
||||
Messages.PROBLEM_DISPLAYING_MBEAN);
|
||||
}
|
||||
}
|
||||
};
|
||||
sw.execute();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayMetadataNode(final DefaultMutableTreeNode node) {
|
||||
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
|
||||
final XMBeanInfo mbi = mbeanInfo;
|
||||
switch (uo.getType()) {
|
||||
case ATTRIBUTE:
|
||||
SwingWorker<MBeanAttributeInfo, Void> sw =
|
||||
new SwingWorker<MBeanAttributeInfo, Void>() {
|
||||
@Override
|
||||
public MBeanAttributeInfo doInBackground() {
|
||||
Object attrData = uo.getData();
|
||||
mbean = (XMBean) ((Object[]) attrData)[0];
|
||||
MBeanAttributeInfo mbai =
|
||||
(MBeanAttributeInfo) ((Object[]) attrData)[1];
|
||||
mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
|
||||
null, null, new MBeanAttributeInfo[]{mbai},
|
||||
null, null, null));
|
||||
return mbai;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
MBeanAttributeInfo mbai = get();
|
||||
if (!isSelectedNode(node, currentNode)) {
|
||||
return;
|
||||
}
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
JPanel attributePanel =
|
||||
new JPanel(new BorderLayout());
|
||||
JPanel attributeBorderPanel =
|
||||
new JPanel(new BorderLayout());
|
||||
attributeBorderPanel.setBorder(
|
||||
BorderFactory.createTitledBorder(
|
||||
Messages.ATTRIBUTE_VALUE));
|
||||
JPanel attributeValuePanel =
|
||||
new JPanel(new BorderLayout());
|
||||
attributeValuePanel.setBorder(
|
||||
LineBorder.createGrayLineBorder());
|
||||
attributeValuePanel.add(mbeanAttributes.getTableHeader(),
|
||||
BorderLayout.PAGE_START);
|
||||
attributeValuePanel.add(mbeanAttributes,
|
||||
BorderLayout.CENTER);
|
||||
attributeBorderPanel.add(attributeValuePanel,
|
||||
BorderLayout.CENTER);
|
||||
JPanel refreshButtonPanel = new JPanel();
|
||||
refreshButtonPanel.add(refreshButton);
|
||||
attributeBorderPanel.add(refreshButtonPanel,
|
||||
BorderLayout.SOUTH);
|
||||
refreshButton.setEnabled(true);
|
||||
attributePanel.add(attributeBorderPanel,
|
||||
BorderLayout.NORTH);
|
||||
mbi.addMBeanAttributeInfo(mbai);
|
||||
attributePanel.add(mbi, BorderLayout.CENTER);
|
||||
mainPanel.add(attributePanel,
|
||||
BorderLayout.CENTER);
|
||||
southPanel.setVisible(false);
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem displaying MBean " +
|
||||
"attribute for MBean [" +
|
||||
mbean.getObjectName() + "]");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.toString(),
|
||||
Messages.PROBLEM_DISPLAYING_MBEAN);
|
||||
}
|
||||
}
|
||||
};
|
||||
sw.execute();
|
||||
break;
|
||||
case OPERATION:
|
||||
Object operData = uo.getData();
|
||||
mbean = (XMBean) ((Object[]) operData)[0];
|
||||
MBeanOperationInfo mboi =
|
||||
(MBeanOperationInfo) ((Object[]) operData)[1];
|
||||
mbeanOperations.loadOperations(mbean,
|
||||
new MBeanInfo(null, null, null, null,
|
||||
new MBeanOperationInfo[]{mboi}, null));
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
JPanel operationPanel = new JPanel(new BorderLayout());
|
||||
JPanel operationBorderPanel = new JPanel(new BorderLayout());
|
||||
operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
Messages.OPERATION_INVOCATION));
|
||||
operationBorderPanel.add(new JScrollPane(mbeanOperations));
|
||||
operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
|
||||
mbi.addMBeanOperationInfo(mboi);
|
||||
operationPanel.add(mbi, BorderLayout.CENTER);
|
||||
mainPanel.add(operationPanel, BorderLayout.CENTER);
|
||||
southPanel.setVisible(false);
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
break;
|
||||
case NOTIFICATION:
|
||||
Object notifData = uo.getData();
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
mbi.addMBeanNotificationInfo((MBeanNotificationInfo) notifData);
|
||||
mainPanel.add(mbi, BorderLayout.CENTER);
|
||||
southPanel.setVisible(false);
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) {
|
||||
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
|
||||
if (!uo.getType().equals(Type.ATTRIBUTES)) {
|
||||
return;
|
||||
}
|
||||
mbean = (XMBean) uo.getData();
|
||||
final XMBean xmb = mbean;
|
||||
SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() {
|
||||
@Override
|
||||
public MBeanInfo doInBackground() throws InstanceNotFoundException,
|
||||
IntrospectionException, ReflectionException, IOException {
|
||||
MBeanInfo mbi = xmb.getMBeanInfo();
|
||||
return mbi;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
MBeanInfo mbi = get();
|
||||
if (mbi != null && mbi.getAttributes() != null &&
|
||||
mbi.getAttributes().length > 0) {
|
||||
|
||||
mbeanAttributes.loadAttributes(xmb, mbi);
|
||||
|
||||
if (!isSelectedNode(node, currentNode)) {
|
||||
return;
|
||||
}
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
JPanel borderPanel = new JPanel(new BorderLayout());
|
||||
borderPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
Messages.ATTRIBUTE_VALUES));
|
||||
borderPanel.add(new JScrollPane(mbeanAttributes));
|
||||
mainPanel.add(borderPanel, BorderLayout.CENTER);
|
||||
// add the refresh button to the south panel
|
||||
southPanel.removeAll();
|
||||
southPanel.add(refreshButton, BorderLayout.SOUTH);
|
||||
southPanel.setVisible(true);
|
||||
refreshButton.setEnabled(true);
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem displaying MBean " +
|
||||
"attributes for MBean [" +
|
||||
mbean.getObjectName() + "]");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.toString(),
|
||||
Messages.PROBLEM_DISPLAYING_MBEAN);
|
||||
}
|
||||
}
|
||||
};
|
||||
sw.execute();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {
|
||||
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
|
||||
if (!uo.getType().equals(Type.OPERATIONS)) {
|
||||
return;
|
||||
}
|
||||
mbean = (XMBean) uo.getData();
|
||||
SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
|
||||
@Override
|
||||
public MBeanInfo doInBackground() throws InstanceNotFoundException,
|
||||
IntrospectionException, ReflectionException, IOException {
|
||||
return mbean.getMBeanInfo();
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
MBeanInfo mbi = get();
|
||||
if (mbi != null) {
|
||||
if (!isSelectedNode(node, currentNode)) {
|
||||
return;
|
||||
}
|
||||
mbeanOperations.loadOperations(mbean, mbi);
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
JPanel borderPanel = new JPanel(new BorderLayout());
|
||||
borderPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
Messages.OPERATION_INVOCATION));
|
||||
borderPanel.add(new JScrollPane(mbeanOperations));
|
||||
mainPanel.add(borderPanel, BorderLayout.CENTER);
|
||||
southPanel.setVisible(false);
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem displaying MBean " +
|
||||
"operations for MBean [" +
|
||||
mbean.getObjectName() + "]");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.toString(),
|
||||
Messages.PROBLEM_DISPLAYING_MBEAN);
|
||||
}
|
||||
}
|
||||
};
|
||||
sw.execute();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
|
||||
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
|
||||
if (!uo.getType().equals(Type.NOTIFICATIONS)) {
|
||||
return;
|
||||
}
|
||||
mbean = (XMBean) uo.getData();
|
||||
mbeanNotifications.loadNotifications(mbean);
|
||||
updateNotifications();
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
JPanel borderPanel = new JPanel(new BorderLayout());
|
||||
borderPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
Messages.NOTIFICATION_BUFFER));
|
||||
borderPanel.add(new JScrollPane(mbeanNotifications));
|
||||
mainPanel.add(borderPanel, BorderLayout.CENTER);
|
||||
// add the subscribe/unsubscribe/clear buttons to the south panel
|
||||
southPanel.removeAll();
|
||||
southPanel.add(subscribeButton, BorderLayout.WEST);
|
||||
southPanel.add(unsubscribeButton, BorderLayout.CENTER);
|
||||
southPanel.add(clearButton, BorderLayout.EAST);
|
||||
southPanel.setVisible(true);
|
||||
subscribeButton.setEnabled(true);
|
||||
unsubscribeButton.setEnabled(true);
|
||||
clearButton.setEnabled(true);
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void displayEmptyNode() {
|
||||
invalidate();
|
||||
mainPanel.removeAll();
|
||||
southPanel.removeAll();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe button action.
|
||||
*/
|
||||
private void registerListener() {
|
||||
new SwingWorker<Void, Void>() {
|
||||
@Override
|
||||
public Void doInBackground()
|
||||
throws InstanceNotFoundException, IOException {
|
||||
mbeanNotifications.registerListener(currentNode);
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
get();
|
||||
updateNotifications();
|
||||
validate();
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem adding listener");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.getMessage(),
|
||||
Messages.PROBLEM_ADDING_LISTENER);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe button action.
|
||||
*/
|
||||
private void unregisterListener() {
|
||||
new SwingWorker<Boolean, Void>() {
|
||||
@Override
|
||||
public Boolean doInBackground() {
|
||||
return mbeanNotifications.unregisterListener(currentNode);
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
if (get()) {
|
||||
updateNotifications();
|
||||
validate();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem removing listener");
|
||||
t.printStackTrace();
|
||||
}
|
||||
showErrorDialog(t.getMessage(),
|
||||
Messages.PROBLEM_REMOVING_LISTENER);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh button action.
|
||||
*/
|
||||
private void refreshAttributes() {
|
||||
mbeanAttributes.refreshAttributes();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void updateNotifications() {
|
||||
if (mbeanNotifications.isListenerRegistered(mbean)) {
|
||||
long received = mbeanNotifications.getReceivedNotifications(mbean);
|
||||
updateReceivedNotifications(currentNode, received, false);
|
||||
} else {
|
||||
clearNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification node label in MBean tree: "Notifications[received]".
|
||||
*/
|
||||
// Call on EDT
|
||||
private void updateReceivedNotifications(
|
||||
DefaultMutableTreeNode emitter, long received, boolean bold) {
|
||||
String text = Messages.NOTIFICATIONS + "[" + received + "]";
|
||||
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
|
||||
if (bold && emitter != selectedNode) {
|
||||
text = "<html><b>" + text + "</b></html>";
|
||||
}
|
||||
updateNotificationsNodeLabel(emitter, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification node label in MBean tree: "Notifications".
|
||||
*/
|
||||
// Call on EDT
|
||||
private void clearNotifications() {
|
||||
updateNotificationsNodeLabel(currentNode,
|
||||
Messages.NOTIFICATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification node label in MBean tree: "Notifications[0]".
|
||||
*/
|
||||
// Call on EDT
|
||||
private void clearNotifications0() {
|
||||
updateNotificationsNodeLabel(currentNode,
|
||||
Messages.NOTIFICATIONS + "[0]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the label of the supplied MBean tree node.
|
||||
*/
|
||||
// Call on EDT
|
||||
private void updateNotificationsNodeLabel(
|
||||
DefaultMutableTreeNode node, String label) {
|
||||
synchronized (mbeansTab.getTree()) {
|
||||
invalidate();
|
||||
XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
|
||||
XNodeInfo newUserObject = new XNodeInfo(
|
||||
oldUserObject.getType(), oldUserObject.getData(),
|
||||
label, oldUserObject.getToolTipText());
|
||||
node.setUserObject(newUserObject);
|
||||
DefaultTreeModel model =
|
||||
(DefaultTreeModel) mbeansTab.getTree().getModel();
|
||||
model.nodeChanged(node);
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear button action.
|
||||
*/
|
||||
// Call on EDT
|
||||
private void clearCurrentNotifications() {
|
||||
mbeanNotifications.clearCurrentNotifications();
|
||||
if (mbeanNotifications.isListenerRegistered(mbean)) {
|
||||
// Update notifs in MBean tree "Notifications[0]".
|
||||
//
|
||||
// Notification buffer has been cleared with a listener been
|
||||
// registered so add "[0]" at the end of the node label.
|
||||
//
|
||||
clearNotifications0();
|
||||
} else {
|
||||
// Update notifs in MBean tree "Notifications".
|
||||
//
|
||||
// Notification buffer has been cleared without a listener been
|
||||
// registered so don't add "[0]" at the end of the node label.
|
||||
//
|
||||
clearNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void clear() {
|
||||
mbeanAttributes.stopCellEditing();
|
||||
mbeanAttributes.emptyTable();
|
||||
mbeanAttributes.removeAttributes();
|
||||
mbeanOperations.removeOperations();
|
||||
mbeanNotifications.stopCellEditing();
|
||||
mbeanNotifications.emptyTable();
|
||||
mbeanNotifications.disableNotifications();
|
||||
mbean = null;
|
||||
currentNode = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification listener: handles asynchronous reception
|
||||
* of MBean operation results and MBean notifications.
|
||||
*/
|
||||
// Call on EDT
|
||||
public void handleNotification(Notification e, Object handback) {
|
||||
// Operation result
|
||||
if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) {
|
||||
final Object message;
|
||||
if (handback == null) {
|
||||
JTextArea textArea = new JTextArea("null");
|
||||
textArea.setEditable(false);
|
||||
textArea.setEnabled(true);
|
||||
textArea.setRows(textArea.getLineCount());
|
||||
message = textArea;
|
||||
} else {
|
||||
Component comp = mbeansTab.getDataViewer().
|
||||
createOperationViewer(handback, mbean);
|
||||
if (comp == null) {
|
||||
JTextArea textArea = new JTextArea(handback.toString());
|
||||
textArea.setEditable(false);
|
||||
textArea.setEnabled(true);
|
||||
textArea.setRows(textArea.getLineCount());
|
||||
JScrollPane scrollPane = new JScrollPane(textArea);
|
||||
Dimension d = scrollPane.getPreferredSize();
|
||||
if (d.getWidth() > 400 || d.getHeight() > 250) {
|
||||
scrollPane.setPreferredSize(new Dimension(400, 250));
|
||||
}
|
||||
message = scrollPane;
|
||||
} else {
|
||||
if (!(comp instanceof JScrollPane)) {
|
||||
comp = new JScrollPane(comp);
|
||||
}
|
||||
Dimension d = comp.getPreferredSize();
|
||||
if (d.getWidth() > 400 || d.getHeight() > 250) {
|
||||
comp.setPreferredSize(new Dimension(400, 250));
|
||||
}
|
||||
message = comp;
|
||||
}
|
||||
}
|
||||
new ThreadDialog(
|
||||
(Component) e.getSource(),
|
||||
message,
|
||||
Messages.OPERATION_RETURN_VALUE,
|
||||
JOptionPane.INFORMATION_MESSAGE).run();
|
||||
} // Got notification
|
||||
else if (e.getType().equals(
|
||||
XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
|
||||
DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
|
||||
Long received = (Long) e.getUserData();
|
||||
updateReceivedNotifications(emitter, received.longValue(), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action listener: handles actions in panel buttons
|
||||
*/
|
||||
// Call on EDT
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() instanceof JButton) {
|
||||
JButton button = (JButton) e.getSource();
|
||||
// Refresh button
|
||||
if (button == refreshButton) {
|
||||
refreshAttributes();
|
||||
return;
|
||||
}
|
||||
// Clear button
|
||||
if (button == clearButton) {
|
||||
clearCurrentNotifications();
|
||||
return;
|
||||
}
|
||||
// Subscribe button
|
||||
if (button == subscribeButton) {
|
||||
registerListener();
|
||||
return;
|
||||
}
|
||||
// Unsubscribe button
|
||||
if (button == unsubscribeButton) {
|
||||
unregisterListener();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
180
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTable.java
Normal file
180
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTable.java
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
|
||||
public abstract class XTable extends JTable {
|
||||
static final int NAME_COLUMN = 0;
|
||||
static final int VALUE_COLUMN = 1;
|
||||
private Color defaultColor, editableColor, errorColor;
|
||||
private Font normalFont, boldFont;
|
||||
|
||||
public XTable () {
|
||||
super();
|
||||
@SuppressWarnings("serial")
|
||||
final TableSorter sorter = new TableSorter();
|
||||
setModel(sorter);
|
||||
sorter.addMouseListenerToHeaderInTable(this);
|
||||
setRowSelectionAllowed(false);
|
||||
setColumnSelectionAllowed(false);
|
||||
setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||
}
|
||||
|
||||
Color getDefaultColor() {
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
Color getEditableColor() {
|
||||
return editableColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TableSorter if a mouse event requests to sort the rows.
|
||||
* @param column the column against which the rows are sorted
|
||||
*/
|
||||
void sortRequested(int column) {
|
||||
// This is a hook for subclasses
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the select index as the table was at initialization
|
||||
*/
|
||||
public int getSelectedIndex() {
|
||||
return convertRowToIndex(getSelectedRow());
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts the row into index (before sorting)
|
||||
*/
|
||||
public int convertRowToIndex(int row) {
|
||||
if (row == -1) return row;
|
||||
if (getModel() instanceof TableSorter) {
|
||||
return ((TableSorter) getModel()).getIndexOfRow(row);
|
||||
} else {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
public void emptyTable() {
|
||||
DefaultTableModel model = (DefaultTableModel)getModel();
|
||||
while (model.getRowCount()>0)
|
||||
model.removeRow(0);
|
||||
}
|
||||
|
||||
public abstract boolean isTableEditable();
|
||||
public abstract boolean isColumnEditable(int column);
|
||||
public abstract boolean isReadable(int row);
|
||||
public abstract boolean isWritable(int row);
|
||||
public abstract boolean isCellError(int row, int col);
|
||||
public abstract boolean isAttributeViewable(int row, int col);
|
||||
public abstract void setTableValue(Object value,int row);
|
||||
public abstract Object getValue(int row);
|
||||
public abstract String getClassName(int row);
|
||||
public abstract String getValueName(int row);
|
||||
|
||||
public boolean isReadWrite(int row) {
|
||||
return (isReadable(row) && isWritable(row));
|
||||
}
|
||||
|
||||
//JTable re-implementation
|
||||
|
||||
//attribute can be editable even if unavailable
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int col) {
|
||||
return ((isTableEditable() && isColumnEditable(col)
|
||||
&& isWritable(row)
|
||||
&& Utils.isEditableType(getClassName(row))));
|
||||
}
|
||||
|
||||
//attribute can be droppable even if unavailable
|
||||
public boolean isCellDroppable(int row, int col) {
|
||||
return (isTableEditable() && isColumnEditable(col)
|
||||
&& isWritable(row));
|
||||
}
|
||||
|
||||
//returns null, means no tool tip
|
||||
public String getToolTip(int row, int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets read write rows to be blue, and other rows to be their
|
||||
* default rendered colour.
|
||||
*/
|
||||
@Override
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
DefaultTableCellRenderer tcr =
|
||||
(DefaultTableCellRenderer) super.getCellRenderer(row,column);
|
||||
tcr.setToolTipText(getToolTip(row,column));
|
||||
if (defaultColor == null) {
|
||||
defaultColor = tcr.getForeground();
|
||||
editableColor = Color.blue;
|
||||
errorColor = Color.red;
|
||||
// this sometimes happens for some reason
|
||||
if (defaultColor == null) {
|
||||
return tcr;
|
||||
}
|
||||
}
|
||||
if (column != VALUE_COLUMN) {
|
||||
tcr.setForeground(defaultColor);
|
||||
return tcr;
|
||||
}
|
||||
if (isCellError(row,column)) {
|
||||
tcr.setForeground(errorColor);
|
||||
} else if (isCellEditable(row, column)) {
|
||||
tcr.setForeground(editableColor);
|
||||
} else {
|
||||
tcr.setForeground(defaultColor);
|
||||
}
|
||||
return tcr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component prepareRenderer(TableCellRenderer renderer,
|
||||
int row, int column) {
|
||||
Component comp = super.prepareRenderer(renderer, row, column);
|
||||
|
||||
if (normalFont == null) {
|
||||
normalFont = comp.getFont();
|
||||
boldFont = normalFont.deriveFont(Font.BOLD);
|
||||
}
|
||||
|
||||
if (column == VALUE_COLUMN && isAttributeViewable(row, VALUE_COLUMN)) {
|
||||
comp.setFont(boldFont);
|
||||
} else {
|
||||
comp.setFont(normalFont);
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
201
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTextField.java
Normal file
201
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTextField.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
/**
|
||||
* This list implements the drag and drop functionality.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class XTextField extends JPanel
|
||||
implements DocumentListener,
|
||||
ActionListener {
|
||||
|
||||
private XObject selectedObject;
|
||||
protected JTextField textField;
|
||||
|
||||
private static boolean allowNullSelection = false;
|
||||
|
||||
protected final static int COMPATIBLE_VALUE = 1;
|
||||
protected final static int CURRENT_VALUE = 2;
|
||||
protected final static int NULL_VALUE = 3;
|
||||
|
||||
private JButton button;
|
||||
private XOperations operation;
|
||||
|
||||
//used in XTestFieldEditor
|
||||
public XTextField() {
|
||||
super(new BorderLayout());
|
||||
add(textField = new JTextField(),BorderLayout.CENTER);
|
||||
textField.addActionListener(this);
|
||||
//
|
||||
}
|
||||
|
||||
public XTextField(Object value) {
|
||||
this(value,value.toString().length());
|
||||
}
|
||||
|
||||
public XTextField(Object value, int colWidth) {
|
||||
this(value,value.getClass(),colWidth, true, null, null);
|
||||
}
|
||||
|
||||
public XTextField(Object value,
|
||||
Class<?> expectedClass,
|
||||
int colWidth,
|
||||
boolean isCallable,
|
||||
JButton button,
|
||||
XOperations operation) {
|
||||
super(new BorderLayout());
|
||||
this.button = button;
|
||||
this.operation = operation;
|
||||
add(textField = new JTextField(value.toString(),colWidth),
|
||||
BorderLayout.CENTER);
|
||||
if(isCallable)
|
||||
textField.addActionListener(this);
|
||||
|
||||
boolean fieldEditable = Utils.isEditableType(expectedClass.getName());
|
||||
if (fieldEditable && isCallable) {
|
||||
textField.setEditable(true);
|
||||
}
|
||||
else {
|
||||
textField.setEditable(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setNullSelectionAllowed(boolean allowNullSelection) {
|
||||
XTextField.allowNullSelection = allowNullSelection;
|
||||
}
|
||||
|
||||
public static boolean getNullSelectionAllowed() {
|
||||
return allowNullSelection;
|
||||
}
|
||||
|
||||
protected void init(Object value, Class<?> expectedClass) {
|
||||
boolean fieldEditable = Utils.isEditableType(expectedClass.getName());
|
||||
clearObject();
|
||||
if (value != null) {
|
||||
textField.setText(value.toString());
|
||||
}
|
||||
else {
|
||||
//null String value for the moment
|
||||
textField.setText("");
|
||||
}
|
||||
textField.setToolTipText(null);
|
||||
if (fieldEditable) {
|
||||
if (!textField.isEditable()) {
|
||||
textField.setEditable(true);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if (textField.isEditable()) {
|
||||
textField.setEditable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void clearObject() {
|
||||
textField.getDocument().removeDocumentListener(this);
|
||||
selectedObject = null;
|
||||
setDefaultColors();
|
||||
}
|
||||
|
||||
private synchronized void setDefaultColors() {
|
||||
// if (fore != null) textField.setForeground(fore);
|
||||
// if (back != null) textField.setBackground(back);
|
||||
}
|
||||
|
||||
public void setHorizontalAlignment(int h) {
|
||||
textField.setHorizontalAlignment(h);
|
||||
}
|
||||
|
||||
//can be overwritten
|
||||
protected JMenuItem buildJMenuItem(XObject xobject, int valueType) {
|
||||
if (valueType == COMPATIBLE_VALUE) {
|
||||
return new JMenuItem(xobject.getText());
|
||||
}
|
||||
else if (valueType == CURRENT_VALUE) {
|
||||
return new JMenuItem("> "+xobject.getText());
|
||||
}
|
||||
else if (valueType == NULL_VALUE) {
|
||||
return new JMenuItem("null");
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ACTIONLISTENER IMPLEMENTATION
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() instanceof JTextField) {
|
||||
if(operation != null)
|
||||
operation.performInvokeRequest(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns either the user inputted String, or an XObject
|
||||
* if one was dropped on the input field.
|
||||
*/
|
||||
public Object getValue() {
|
||||
if (selectedObject!=null) {
|
||||
if (selectedObject == XObject.NULL_OBJECT) {
|
||||
//null case
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return selectedObject;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return textField.getText();
|
||||
}
|
||||
}
|
||||
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
// the user typed something, so remove references
|
||||
// to the object that was dropped.
|
||||
clearObject();
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
// the user typed something, so remove references
|
||||
// to the object that was dropped.
|
||||
clearObject();
|
||||
}
|
||||
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
// the user typed something, so remove references
|
||||
// to the object that was dropped.
|
||||
clearObject();
|
||||
}
|
||||
|
||||
}
|
||||
156
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTextFieldEditor.java
Normal file
156
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTextFieldEditor.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.util.EventObject;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.CellEditorListener;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XTextFieldEditor extends XTextField implements TableCellEditor {
|
||||
|
||||
protected EventListenerList evtListenerList = new EventListenerList();
|
||||
protected ChangeEvent changeEvent = new ChangeEvent(this);
|
||||
|
||||
private FocusListener editorFocusListener = new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
// fireEditingStopped();
|
||||
// must not call fireEditingStopped() here!
|
||||
}
|
||||
};
|
||||
|
||||
public XTextFieldEditor() {
|
||||
super();
|
||||
textField.addFocusListener(editorFocusListener);
|
||||
}
|
||||
|
||||
//edition stopped ou JMenuItem selection & JTextField selection
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
super.actionPerformed(e);
|
||||
if ((e.getSource() instanceof JMenuItem) ||
|
||||
(e.getSource() instanceof JTextField)) {
|
||||
fireEditingStopped();
|
||||
}
|
||||
}
|
||||
|
||||
//edition stopped on drag & drop success
|
||||
protected void dropSuccess() {
|
||||
fireEditingStopped();
|
||||
}
|
||||
|
||||
//TableCellEditor implementation
|
||||
|
||||
public void addCellEditorListener(CellEditorListener listener) {
|
||||
evtListenerList.add(CellEditorListener.class,listener);
|
||||
}
|
||||
|
||||
public void removeCellEditorListener(CellEditorListener listener) {
|
||||
evtListenerList.remove(CellEditorListener.class, listener);
|
||||
}
|
||||
|
||||
protected void fireEditingStopped() {
|
||||
CellEditorListener listener;
|
||||
Object[] listeners = evtListenerList.getListenerList();
|
||||
for (int i=0;i< listeners.length;i++) {
|
||||
if (listeners[i] == CellEditorListener.class) {
|
||||
listener = (CellEditorListener) listeners[i+1];
|
||||
listener.editingStopped(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void fireEditingCanceled() {
|
||||
CellEditorListener listener;
|
||||
Object[] listeners = evtListenerList.getListenerList();
|
||||
for (int i=0;i< listeners.length;i++) {
|
||||
if (listeners[i] == CellEditorListener.class) {
|
||||
listener = (CellEditorListener) listeners[i+1];
|
||||
listener.editingCanceled(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelCellEditing() {
|
||||
fireEditingCanceled();
|
||||
}
|
||||
|
||||
public boolean stopCellEditing() {
|
||||
fireEditingStopped();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(EventObject event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldSelectCell(EventObject event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
Object object = getValue();
|
||||
|
||||
if (object instanceof XObject) {
|
||||
return ((XObject) object).getObject();
|
||||
}
|
||||
else {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
public Component getTableCellEditorComponent(JTable table,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
int row,
|
||||
int column) {
|
||||
String className;
|
||||
if (table instanceof XTable) {
|
||||
XTable mytable = (XTable) table;
|
||||
className = mytable.getClassName(row);
|
||||
} else {
|
||||
className = String.class.getName();
|
||||
}
|
||||
try {
|
||||
init(value,Utils.getClass(className));
|
||||
}
|
||||
catch(Exception e) {}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
834
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTree.java
Normal file
834
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTree.java
Normal file
@@ -0,0 +1,834 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import javax.management.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.*;
|
||||
import sun.tools.jconsole.JConsole;
|
||||
import sun.tools.jconsole.MBeansTab;
|
||||
import sun.tools.jconsole.Messages;
|
||||
import sun.tools.jconsole.inspector.XNodeInfo;
|
||||
import static sun.tools.jconsole.inspector.XNodeInfo.Type;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XTree extends JTree {
|
||||
|
||||
private static final List<String> orderedKeyPropertyList =
|
||||
new ArrayList<String>();
|
||||
|
||||
static {
|
||||
String keyPropertyList =
|
||||
System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList");
|
||||
if (keyPropertyList == null) {
|
||||
orderedKeyPropertyList.add("type");
|
||||
orderedKeyPropertyList.add("j2eeType");
|
||||
} else {
|
||||
StringTokenizer st = new StringTokenizer(keyPropertyList, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
orderedKeyPropertyList.add(st.nextToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
private MBeansTab mbeansTab;
|
||||
private Map<String, DefaultMutableTreeNode> nodes =
|
||||
new HashMap<String, DefaultMutableTreeNode>();
|
||||
|
||||
public XTree(MBeansTab mbeansTab) {
|
||||
this(new DefaultMutableTreeNode("MBeanTreeRootNode"), mbeansTab);
|
||||
}
|
||||
|
||||
public XTree(TreeNode root, MBeansTab mbeansTab) {
|
||||
super(root, true);
|
||||
this.mbeansTab = mbeansTab;
|
||||
setRootVisible(false);
|
||||
setShowsRootHandles(true);
|
||||
ToolTipManager.sharedInstance().registerComponent(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes the node from its parent
|
||||
*/
|
||||
// Call on EDT
|
||||
private synchronized void removeChildNode(DefaultMutableTreeNode child) {
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
model.removeNodeFromParent(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds the child to the specified parent node
|
||||
* at specific index.
|
||||
*/
|
||||
// Call on EDT
|
||||
private synchronized void addChildNode(
|
||||
DefaultMutableTreeNode parent,
|
||||
DefaultMutableTreeNode child,
|
||||
int index) {
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
model.insertNodeInto(child, parent, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds the child to the specified parent node.
|
||||
* The index where the child is to be added depends on the
|
||||
* child node being Comparable or not. If the child node is
|
||||
* not Comparable then it is added at the end, i.e. right
|
||||
* after the current parent's children.
|
||||
*/
|
||||
// Call on EDT
|
||||
private synchronized void addChildNode(
|
||||
DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
|
||||
int childCount = parent.getChildCount();
|
||||
if (childCount == 0) {
|
||||
addChildNode(parent, child, 0);
|
||||
return;
|
||||
}
|
||||
if (child instanceof ComparableDefaultMutableTreeNode) {
|
||||
ComparableDefaultMutableTreeNode comparableChild =
|
||||
(ComparableDefaultMutableTreeNode) child;
|
||||
for (int i = childCount - 1; i >= 0; i--) {
|
||||
DefaultMutableTreeNode brother =
|
||||
(DefaultMutableTreeNode) parent.getChildAt(i);
|
||||
// expr1: child node must be inserted after metadata nodes
|
||||
// - OR -
|
||||
// expr2: "child >= brother"
|
||||
if ((i <= 2 && isMetadataNode(brother)) ||
|
||||
comparableChild.compareTo(brother) >= 0) {
|
||||
addChildNode(parent, child, i + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// "child < all brothers", add at the beginning
|
||||
addChildNode(parent, child, 0);
|
||||
return;
|
||||
}
|
||||
// "child not comparable", add at the end
|
||||
addChildNode(parent, child, childCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes all the displayed nodes from the tree,
|
||||
* but does not affect actual MBeanServer contents.
|
||||
*/
|
||||
// Call on EDT
|
||||
@Override
|
||||
public synchronized void removeAll() {
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
|
||||
root.removeAllChildren();
|
||||
model.nodeStructureChanged(root);
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void removeMBeanFromView(ObjectName mbean) {
|
||||
// We assume here that MBeans are removed one by one (on MBean
|
||||
// unregistered notification). Deletes the tree node associated
|
||||
// with the given MBean and recursively all the node parents
|
||||
// which are leaves and non XMBean.
|
||||
//
|
||||
DefaultMutableTreeNode node = null;
|
||||
Dn dn = new Dn(mbean);
|
||||
if (dn.getTokenCount() > 0) {
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
Token token = dn.getToken(0);
|
||||
String hashKey = dn.getHashKey(token);
|
||||
node = nodes.get(hashKey);
|
||||
if ((node != null) && (!node.isRoot())) {
|
||||
if (hasNonMetadataNodes(node)) {
|
||||
removeMetadataNodes(node);
|
||||
String label = token.getValue();
|
||||
XNodeInfo userObject = new XNodeInfo(
|
||||
Type.NONMBEAN, label,
|
||||
label, token.getTokenValue());
|
||||
changeNodeValue(node, userObject);
|
||||
} else {
|
||||
DefaultMutableTreeNode parent =
|
||||
(DefaultMutableTreeNode) node.getParent();
|
||||
model.removeNodeFromParent(node);
|
||||
nodes.remove(hashKey);
|
||||
removeParentFromView(dn, 1, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any of the children nodes is a non MBean metadata node.
|
||||
*/
|
||||
private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) {
|
||||
for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
|
||||
DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
|
||||
Object uo = n.getUserObject();
|
||||
if (uo instanceof XNodeInfo) {
|
||||
switch (((XNodeInfo) uo).getType()) {
|
||||
case ATTRIBUTES:
|
||||
case NOTIFICATIONS:
|
||||
case OPERATIONS:
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any of the children nodes is an MBean metadata node.
|
||||
*/
|
||||
public boolean hasMetadataNodes(DefaultMutableTreeNode node) {
|
||||
for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
|
||||
DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
|
||||
Object uo = n.getUserObject();
|
||||
if (uo instanceof XNodeInfo) {
|
||||
switch (((XNodeInfo) uo).getType()) {
|
||||
case ATTRIBUTES:
|
||||
case NOTIFICATIONS:
|
||||
case OPERATIONS:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given node is an MBean metadata node.
|
||||
*/
|
||||
public boolean isMetadataNode(DefaultMutableTreeNode node) {
|
||||
Object uo = node.getUserObject();
|
||||
if (uo instanceof XNodeInfo) {
|
||||
switch (((XNodeInfo) uo).getType()) {
|
||||
case ATTRIBUTES:
|
||||
case NOTIFICATIONS:
|
||||
case OPERATIONS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the metadata nodes associated with a given MBean node.
|
||||
*/
|
||||
// Call on EDT
|
||||
private void removeMetadataNodes(DefaultMutableTreeNode node) {
|
||||
Set<DefaultMutableTreeNode> metadataNodes =
|
||||
new HashSet<DefaultMutableTreeNode>();
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
|
||||
DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
|
||||
Object uo = n.getUserObject();
|
||||
if (uo instanceof XNodeInfo) {
|
||||
switch (((XNodeInfo) uo).getType()) {
|
||||
case ATTRIBUTES:
|
||||
case NOTIFICATIONS:
|
||||
case OPERATIONS:
|
||||
metadataNodes.add(n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (DefaultMutableTreeNode n : metadataNodes) {
|
||||
model.removeNodeFromParent(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes only the parent nodes which are non MBean and leaf.
|
||||
* This method assumes the child nodes have been removed before.
|
||||
*/
|
||||
// Call on EDT
|
||||
private DefaultMutableTreeNode removeParentFromView(
|
||||
Dn dn, int index, DefaultMutableTreeNode node) {
|
||||
if ((!node.isRoot()) && node.isLeaf() &&
|
||||
(!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) {
|
||||
DefaultMutableTreeNode parent =
|
||||
(DefaultMutableTreeNode) node.getParent();
|
||||
removeChildNode(node);
|
||||
String hashKey = dn.getHashKey(dn.getToken(index));
|
||||
nodes.remove(hashKey);
|
||||
removeParentFromView(dn, index + 1, parent);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void addMBeansToView(Set<ObjectName> mbeans) {
|
||||
Set<Dn> dns = new TreeSet<Dn>();
|
||||
for (ObjectName mbean : mbeans) {
|
||||
Dn dn = new Dn(mbean);
|
||||
dns.add(dn);
|
||||
}
|
||||
for (Dn dn : dns) {
|
||||
ObjectName mbean = dn.getObjectName();
|
||||
XMBean xmbean = new XMBean(mbean, mbeansTab);
|
||||
addMBeanToView(mbean, xmbean, dn);
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public synchronized void addMBeanToView(ObjectName mbean) {
|
||||
// Build XMBean for the given MBean
|
||||
//
|
||||
XMBean xmbean = new XMBean(mbean, mbeansTab);
|
||||
// Build Dn for the given MBean
|
||||
//
|
||||
Dn dn = new Dn(mbean);
|
||||
// Add the new nodes to the MBean tree from leaf to root
|
||||
//
|
||||
addMBeanToView(mbean, xmbean, dn);
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private synchronized void addMBeanToView(
|
||||
ObjectName mbean, XMBean xmbean, Dn dn) {
|
||||
|
||||
DefaultMutableTreeNode childNode = null;
|
||||
DefaultMutableTreeNode parentNode = null;
|
||||
|
||||
// Add the node or replace its user object if already added
|
||||
//
|
||||
Token token = dn.getToken(0);
|
||||
String hashKey = dn.getHashKey(token);
|
||||
if (nodes.containsKey(hashKey)) {
|
||||
// Found existing node previously created when adding another node
|
||||
//
|
||||
childNode = nodes.get(hashKey);
|
||||
// Replace user object to reflect that this node is an MBean
|
||||
//
|
||||
Object data = createNodeValue(xmbean, token);
|
||||
String label = data.toString();
|
||||
XNodeInfo userObject =
|
||||
new XNodeInfo(Type.MBEAN, data, label, mbean.toString());
|
||||
changeNodeValue(childNode, userObject);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new leaf node
|
||||
//
|
||||
childNode = createDnNode(dn, token, xmbean);
|
||||
nodes.put(hashKey, childNode);
|
||||
|
||||
// Add intermediate non MBean nodes
|
||||
//
|
||||
for (int i = 1; i < dn.getTokenCount(); i++) {
|
||||
token = dn.getToken(i);
|
||||
hashKey = dn.getHashKey(token);
|
||||
if (nodes.containsKey(hashKey)) {
|
||||
// Intermediate node already present, add new node as child
|
||||
//
|
||||
parentNode = nodes.get(hashKey);
|
||||
addChildNode(parentNode, childNode);
|
||||
return;
|
||||
} else {
|
||||
// Create new intermediate node
|
||||
//
|
||||
if ("domain".equals(token.getTokenType())) {
|
||||
parentNode = createDomainNode(dn, token);
|
||||
DefaultMutableTreeNode root =
|
||||
(DefaultMutableTreeNode) getModel().getRoot();
|
||||
addChildNode(root, parentNode);
|
||||
} else {
|
||||
parentNode = createSubDnNode(dn, token);
|
||||
}
|
||||
nodes.put(hashKey, parentNode);
|
||||
addChildNode(parentNode, childNode);
|
||||
}
|
||||
childNode = parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private synchronized void changeNodeValue(
|
||||
DefaultMutableTreeNode node, XNodeInfo nodeValue) {
|
||||
if (node instanceof ComparableDefaultMutableTreeNode) {
|
||||
// should it stay at the same place?
|
||||
DefaultMutableTreeNode clone =
|
||||
(DefaultMutableTreeNode) node.clone();
|
||||
clone.setUserObject(nodeValue);
|
||||
if (((ComparableDefaultMutableTreeNode) node).compareTo(clone) == 0) {
|
||||
// the order in the tree didn't change
|
||||
node.setUserObject(nodeValue);
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
model.nodeChanged(node);
|
||||
} else {
|
||||
// delete the node and re-order it in case the
|
||||
// node value modifies the order in the tree
|
||||
DefaultMutableTreeNode parent =
|
||||
(DefaultMutableTreeNode) node.getParent();
|
||||
removeChildNode(node);
|
||||
node.setUserObject(nodeValue);
|
||||
addChildNode(parent, node);
|
||||
}
|
||||
} else {
|
||||
// not comparable stays at the same place
|
||||
node.setUserObject(nodeValue);
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
model.nodeChanged(node);
|
||||
}
|
||||
// Load the MBean metadata if type is MBEAN
|
||||
if (nodeValue.getType().equals(Type.MBEAN)) {
|
||||
removeMetadataNodes(node);
|
||||
TreeNode[] treeNodes = node.getPath();
|
||||
TreePath path = new TreePath(treeNodes);
|
||||
if (isExpanded(path)) {
|
||||
addMetadataNodes(node);
|
||||
}
|
||||
}
|
||||
// Clear the current selection and set it
|
||||
// again so valueChanged() gets called
|
||||
if (node == getLastSelectedPathComponent()) {
|
||||
TreePath selectionPath = getSelectionPath();
|
||||
clearSelection();
|
||||
setSelectionPath(selectionPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the domain node.
|
||||
*/
|
||||
private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) {
|
||||
DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
|
||||
String label = dn.getDomain();
|
||||
XNodeInfo userObject =
|
||||
new XNodeInfo(Type.NONMBEAN, label, label, label);
|
||||
node.setUserObject(userObject);
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the node corresponding to the whole Dn, i.e. an MBean.
|
||||
*/
|
||||
private DefaultMutableTreeNode createDnNode(
|
||||
Dn dn, Token token, XMBean xmbean) {
|
||||
DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
|
||||
Object data = createNodeValue(xmbean, token);
|
||||
String label = data.toString();
|
||||
XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label,
|
||||
xmbean.getObjectName().toString());
|
||||
node.setUserObject(userObject);
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the node corresponding to a subDn, i.e. a non-MBean
|
||||
* intermediate node.
|
||||
*/
|
||||
private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) {
|
||||
DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
|
||||
String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
|
||||
XNodeInfo userObject =
|
||||
new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue());
|
||||
node.setUserObject(userObject);
|
||||
return node;
|
||||
}
|
||||
|
||||
private Object createNodeValue(XMBean xmbean, Token token) {
|
||||
String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
|
||||
xmbean.setText(label);
|
||||
return xmbean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the MBean ObjectName comma-separated properties string and puts
|
||||
* the individual key/value pairs into the map. Key order in the properties
|
||||
* string is preserved by the map.
|
||||
*/
|
||||
private static Map<String, String> extractKeyValuePairs(
|
||||
String props, ObjectName mbean) {
|
||||
Map<String, String> map = new LinkedHashMap<String, String>();
|
||||
int eq = props.indexOf("=");
|
||||
while (eq != -1) {
|
||||
String key = props.substring(0, eq);
|
||||
String value = mbean.getKeyProperty(key);
|
||||
map.put(key, value);
|
||||
props = props.substring(key.length() + 1 + value.length());
|
||||
if (props.startsWith(",")) {
|
||||
props = props.substring(1);
|
||||
}
|
||||
eq = props.indexOf("=");
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ordered key property list that will be used to build the
|
||||
* MBean tree. If the "com.sun.tools.jconsole.mbeans.keyPropertyList" system
|
||||
* property is not specified, then the ordered key property list used
|
||||
* to build the MBean tree will be the one returned by the method
|
||||
* ObjectName.getKeyPropertyListString() with "type" as first key,
|
||||
* and "j2eeType" as second key, if present. If any of the keys specified
|
||||
* in the comma-separated key property list does not apply to the given
|
||||
* MBean then it will be discarded.
|
||||
*/
|
||||
private static String getKeyPropertyListString(ObjectName mbean) {
|
||||
String props = mbean.getKeyPropertyListString();
|
||||
Map<String, String> map = extractKeyValuePairs(props, mbean);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// Add the key/value pairs to the buffer following the
|
||||
// key order defined by the "orderedKeyPropertyList"
|
||||
for (String key : orderedKeyPropertyList) {
|
||||
if (map.containsKey(key)) {
|
||||
sb.append(key + "=" + map.get(key) + ",");
|
||||
map.remove(key);
|
||||
}
|
||||
}
|
||||
// Add the remaining key/value pairs to the buffer
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
sb.append(entry.getKey() + "=" + entry.getValue() + ",");
|
||||
}
|
||||
String orderedKeyPropertyListString = sb.toString();
|
||||
orderedKeyPropertyListString = orderedKeyPropertyListString.substring(
|
||||
0, orderedKeyPropertyListString.length() - 1);
|
||||
return orderedKeyPropertyListString;
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
public void addMetadataNodes(DefaultMutableTreeNode node) {
|
||||
XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
|
||||
DefaultTreeModel model = (DefaultTreeModel) getModel();
|
||||
MBeanInfoNodesSwingWorker sw =
|
||||
new MBeanInfoNodesSwingWorker(model, node, mbean);
|
||||
if (sw != null) {
|
||||
sw.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MBeanInfoNodesSwingWorker
|
||||
extends SwingWorker<Object[], Void> {
|
||||
|
||||
private final DefaultTreeModel model;
|
||||
private final DefaultMutableTreeNode node;
|
||||
private final XMBean mbean;
|
||||
|
||||
public MBeanInfoNodesSwingWorker(
|
||||
DefaultTreeModel model,
|
||||
DefaultMutableTreeNode node,
|
||||
XMBean mbean) {
|
||||
this.model = model;
|
||||
this.node = node;
|
||||
this.mbean = mbean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] doInBackground() throws InstanceNotFoundException,
|
||||
IntrospectionException, ReflectionException, IOException {
|
||||
Object result[] = new Object[2];
|
||||
// Retrieve MBeanInfo for this MBean
|
||||
result[0] = mbean.getMBeanInfo();
|
||||
// Check if this MBean is a notification emitter
|
||||
result[1] = mbean.isBroadcaster();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
Object result[] = get();
|
||||
MBeanInfo mbeanInfo = (MBeanInfo) result[0];
|
||||
Boolean isBroadcaster = (Boolean) result[1];
|
||||
if (mbeanInfo != null) {
|
||||
addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call on EDT
|
||||
private void addMBeanInfoNodes(
|
||||
DefaultTreeModel tree, DefaultMutableTreeNode node,
|
||||
XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) {
|
||||
MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
|
||||
MBeanOperationInfo[] oi = mbeanInfo.getOperations();
|
||||
MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
|
||||
|
||||
// Insert the Attributes/Operations/Notifications metadata nodes as
|
||||
// the three first children of this MBean node. This is only useful
|
||||
// when this MBean node denotes an MBean but it's not a leaf in the
|
||||
// MBean tree
|
||||
//
|
||||
int childIndex = 0;
|
||||
|
||||
// MBeanAttributeInfo node
|
||||
//
|
||||
if (ai != null && ai.length > 0) {
|
||||
DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
|
||||
XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
|
||||
Messages.ATTRIBUTES, null);
|
||||
attributes.setUserObject(attributesUO);
|
||||
node.insert(attributes, childIndex++);
|
||||
for (MBeanAttributeInfo mbai : ai) {
|
||||
DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
|
||||
XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
|
||||
new Object[]{mbean, mbai}, mbai.getName(), null);
|
||||
attribute.setUserObject(attributeUO);
|
||||
attribute.setAllowsChildren(false);
|
||||
attributes.add(attribute);
|
||||
}
|
||||
}
|
||||
// MBeanOperationInfo node
|
||||
//
|
||||
if (oi != null && oi.length > 0) {
|
||||
DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
|
||||
XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
|
||||
Messages.OPERATIONS, null);
|
||||
operations.setUserObject(operationsUO);
|
||||
node.insert(operations, childIndex++);
|
||||
for (MBeanOperationInfo mboi : oi) {
|
||||
// Compute the operation's tool tip text:
|
||||
// "operationname(param1type,param2type,...)"
|
||||
//
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (MBeanParameterInfo mbpi : mboi.getSignature()) {
|
||||
sb.append(mbpi.getType() + ",");
|
||||
}
|
||||
String signature = sb.toString();
|
||||
if (signature.length() > 0) {
|
||||
// Remove the trailing ','
|
||||
//
|
||||
signature = signature.substring(0, signature.length() - 1);
|
||||
}
|
||||
String toolTipText = mboi.getName() + "(" + signature + ")";
|
||||
// Create operation node
|
||||
//
|
||||
DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
|
||||
XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
|
||||
new Object[]{mbean, mboi}, mboi.getName(), toolTipText);
|
||||
operation.setUserObject(operationUO);
|
||||
operation.setAllowsChildren(false);
|
||||
operations.add(operation);
|
||||
}
|
||||
}
|
||||
// MBeanNotificationInfo node
|
||||
//
|
||||
if (isBroadcaster != null && isBroadcaster.booleanValue()) {
|
||||
DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
|
||||
XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
|
||||
Messages.NOTIFICATIONS, null);
|
||||
notifications.setUserObject(notificationsUO);
|
||||
node.insert(notifications, childIndex++);
|
||||
if (ni != null && ni.length > 0) {
|
||||
for (MBeanNotificationInfo mbni : ni) {
|
||||
DefaultMutableTreeNode notification =
|
||||
new DefaultMutableTreeNode();
|
||||
XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
|
||||
mbni, mbni.getName(), null);
|
||||
notification.setUserObject(notificationUO);
|
||||
notification.setAllowsChildren(false);
|
||||
notifications.add(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update tree model
|
||||
//
|
||||
model.reload(node);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Tree preferences
|
||||
//
|
||||
private static boolean treeView;
|
||||
private static boolean treeViewInit = false;
|
||||
|
||||
private static boolean isTreeView() {
|
||||
if (!treeViewInit) {
|
||||
treeView = getTreeViewValue();
|
||||
treeViewInit = true;
|
||||
}
|
||||
return treeView;
|
||||
}
|
||||
|
||||
private static boolean getTreeViewValue() {
|
||||
String tv = System.getProperty("treeView");
|
||||
return ((tv == null) ? true : !(tv.equals("false")));
|
||||
}
|
||||
//
|
||||
// MBean key-value preferences
|
||||
//
|
||||
private boolean keyValueView = Boolean.getBoolean("keyValueView");
|
||||
|
||||
private boolean isKeyValueView() {
|
||||
return keyValueView;
|
||||
}
|
||||
|
||||
//
|
||||
// Utility classes
|
||||
//
|
||||
private static class ComparableDefaultMutableTreeNode
|
||||
extends DefaultMutableTreeNode
|
||||
implements Comparable<DefaultMutableTreeNode> {
|
||||
|
||||
public int compareTo(DefaultMutableTreeNode node) {
|
||||
return (this.toString().compareTo(node.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private static class Dn implements Comparable<Dn> {
|
||||
|
||||
private ObjectName mbean;
|
||||
private String domain;
|
||||
private String keyPropertyList;
|
||||
private String hashDn;
|
||||
private List<Token> tokens = new ArrayList<Token>();
|
||||
|
||||
public Dn(ObjectName mbean) {
|
||||
this.mbean = mbean;
|
||||
this.domain = mbean.getDomain();
|
||||
this.keyPropertyList = getKeyPropertyListString(mbean);
|
||||
|
||||
if (isTreeView()) {
|
||||
// Tree view
|
||||
Map<String, String> map =
|
||||
extractKeyValuePairs(keyPropertyList, mbean);
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue()));
|
||||
}
|
||||
} else {
|
||||
// Flat view
|
||||
tokens.add(new Token("key", "properties=" + keyPropertyList));
|
||||
}
|
||||
|
||||
// Add the domain as the first token in the Dn
|
||||
tokens.add(0, new Token("domain", "domain=" + domain));
|
||||
|
||||
// Reverse the Dn (from leaf to root)
|
||||
Collections.reverse(tokens);
|
||||
|
||||
// Compute hash for Dn
|
||||
computeHashDn();
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return mbean;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public String getKeyPropertyList() {
|
||||
return keyPropertyList;
|
||||
}
|
||||
|
||||
public Token getToken(int index) {
|
||||
return tokens.get(index);
|
||||
}
|
||||
|
||||
public int getTokenCount() {
|
||||
return tokens.size();
|
||||
}
|
||||
|
||||
public String getHashDn() {
|
||||
return hashDn;
|
||||
}
|
||||
|
||||
public String getHashKey(Token token) {
|
||||
final int begin = hashDn.indexOf(token.getTokenValue());
|
||||
return hashDn.substring(begin, hashDn.length());
|
||||
}
|
||||
|
||||
private void computeHashDn() {
|
||||
if (tokens.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final StringBuilder hdn = new StringBuilder();
|
||||
for (int i = 0; i < tokens.size(); i++) {
|
||||
hdn.append(tokens.get(i).getTokenValue());
|
||||
hdn.append(",");
|
||||
}
|
||||
hashDn = hdn.substring(0, hdn.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return domain + ":" + keyPropertyList;
|
||||
}
|
||||
|
||||
public int compareTo(Dn dn) {
|
||||
return this.toString().compareTo(dn.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Token {
|
||||
|
||||
private String tokenType;
|
||||
private String tokenValue;
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public Token(String tokenType, String tokenValue) {
|
||||
this.tokenType = tokenType;
|
||||
this.tokenValue = tokenValue;
|
||||
buildKeyValue();
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
public String getTokenValue() {
|
||||
return tokenValue;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private void buildKeyValue() {
|
||||
int index = tokenValue.indexOf("=");
|
||||
if (index < 0) {
|
||||
key = tokenValue;
|
||||
value = tokenValue;
|
||||
} else {
|
||||
key = tokenValue.substring(0, index);
|
||||
value = tokenValue.substring(index + 1, tokenValue.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTreeRenderer.java
Normal file
69
jdkSrc/jdk8/sun/tools/jconsole/inspector/XTreeRenderer.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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 sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.Component;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class XTreeRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
public Component getTreeCellRendererComponent(
|
||||
JTree tree, Object value, boolean selected, boolean expanded,
|
||||
boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(
|
||||
tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
if (userObject instanceof XNodeInfo) {
|
||||
XNodeInfo node = (XNodeInfo) userObject;
|
||||
setToolTipText(node.getToolTipText());
|
||||
switch (node.getType()) {
|
||||
case MBEAN:
|
||||
XMBean xmbean = (XMBean) node.getData();
|
||||
setIcon((ImageIcon) xmbean.getIcon());
|
||||
break;
|
||||
case NONMBEAN:
|
||||
break;
|
||||
case ATTRIBUTES:
|
||||
case OPERATIONS:
|
||||
case NOTIFICATIONS:
|
||||
setIcon(null);
|
||||
break;
|
||||
case ATTRIBUTE:
|
||||
case OPERATION:
|
||||
case NOTIFICATION:
|
||||
setIcon(null);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
setToolTipText(null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user