feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
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