Getting Started Extending VisualVM (Part 7)

Update on 30 May 2008: The code and steps in this blog entry have been updated to reflect the VisualVM 1.0 APIs. If you want to download the complete sources of the sample discussed here, get the VisualVM Sample Collection from the Plugin Portal.

I've made some significant strides in my understanding of the VisualVM APIs. I've been following some discussions around this tool and people were asking if a single tab could be displayed to compare multiple instances of the same type of data source. Or, that's what they meant, in API terms. So as a prototype, I made two new tabs on "Local Host" level, showing the system properties and JVM arguments of ALL the running instances at the same time:

Above you see the system properties of all the running Java applications on my local system, while below you see all their JVM arguments:

That's pretty cool, I reckon. One really nice thing is that you can also see the icons in the tabs above. Those icons match the icons of the application in the explorer view. Really useful.

Something I had to do—less than ideal but it works—was to copy the JVMArgumentsViewSupport and the SystemPropertiesViewSupport from the sources. I'm hoping those two will become public when the APIs are officially released. Until then, this solution works.

Here's a screenshot of all the classes that went into the creation of the above two tabs:

It ended up being relatively simple. My key learnings were the following:

  • A reaffirmation that I don't need to create separate menu items for the Open action. Simply return "true" from DataSourceViewProvider.supportsViewFor and then you will automatically have your view open together with the other views opened from the related node in the explorer view.

  • There are some very handy classes for getting things, such as properties, from the JVM (or should that now be "VM"):

    • com.sun.tools.visualvm.core.model.jvm.JVM
    • com.sun.tools.visualvm.core.model.jvm.JVMFactory

    The final snippet below shows how the above two are used.

  • In the SystemPropertiesViewSupport and JVMArgumentsViewSupport, I created the icon like this, using the final argument of DataViewComponent.DetailsView to return the label with the icon, which is then put into the tabs that you see above:

    private Application app;
    private int count;
    private String name;
    
    public SystemPropertiesViewSupport(Properties properties, Application app, 
            int count, String name) {
        initComponents(properties);
        this.app = app;
        this.count = count;
        this.name = name;
    }
    String cleanedUserDir = "";
    
    public DataViewComponent.DetailsView getDetailsView() {
        Image icon = DataSourceDescriptorFactory.getDescriptor(app).getIcon();
        JLabel label = wrap(icon);
        JComponent[] options = {label};
        String title = count + ": " + name + " (pid " + app.getPid() + ")";
        return new DataViewComponent.DetailsView(title, null, this, options);
    }
    
    private JLabel wrap(Image image) {
        ImageIcon icon = new ImageIcon(image);
        JLabel label = new JLabel(icon, JLabel.CENTER);
        return label;
    }
    ...
    ...
    ...

Finally, for what it's worth, both DataViewComponents in my DataSourceViews look like this:

private DataViewComponent createViewComponent() {

    //Data area for master view:
    JEditorPane generalDataArea = new JEditorPane();
    generalDataArea.setText("Below you see the system properties of" +
            " all running apps!");
    generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));

    //Master view:
    DataViewComponent.MasterView masterView =
            new DataViewComponent.MasterView("All System Properties",
            null, generalDataArea);

    //Configuration of master view:
    DataViewComponent.MasterViewConfiguration masterConfiguration =
            new DataViewComponent.MasterViewConfiguration(false);

    //Add the master view and configuration view to the component:
    dvc = new DataViewComponent(masterView, masterConfiguration);

    //Get all the applications deployed to the host:
    Set apps = host.getApplications();

    //Get the iterator:
    Iterator it = apps.iterator();

    //Set count to zero:
    int count = 0;

    //Iterate through our applications:
    while (it.hasNext()) {

        //Increase the count:
        count = count + 1;

        //Now we have our application:
        Application app = it.next();

        //Get the process id:
        String pid = count + ": " + (String.valueOf(app.getPid()));

        //Get the system properties:
        Properties jvmProperties = null;
        JVM jvm = JVMFactory.getJVMFor(app);
        if (jvm.isGetSystemPropertiesSupported()) {
            jvmProperties = jvm.getSystemProperties();
        }

        //Extrapolate the name from the type:
        ApplicationType appType = ApplicationTypeFactory.
                getApplicationTypeFor(app);
        String appName = appType.getName();

        //Put the first application top left:
        if (count == 1) {
            dvc.addDetailsView(new SystemPropertiesViewSupport(
                    jvmProperties, app, count, appName).getDetailsView(), 
                    DataViewComponent.TOP_LEFT);
            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(
                    pid, true), DataViewComponent.TOP_LEFT);

        //Put the second application top right:
        } else if (count == 2) {
            dvc.addDetailsView(new SystemPropertiesViewSupport(
                    jvmProperties, app, count, appName).getDetailsView(), 
                    DataViewComponent.TOP_RIGHT);
            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(
                    pid, true), DataViewComponent.TOP_RIGHT);

        //Put the third application bottom left:    
        } else if (count == 3) {
            dvc.addDetailsView(new SystemPropertiesViewSupport(
                    jvmProperties, app, count, appName).getDetailsView(), 
                    DataViewComponent.BOTTOM_LEFT);
            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(
                    pid, true), DataViewComponent.BOTTOM_LEFT);

        //Put the fourth application bottom right:        
        } else if (count == 4) {
            dvc.addDetailsView(new SystemPropertiesViewSupport(
                    jvmProperties, app, count, appName).getDetailsView(), 
                    DataViewComponent.BOTTOM_RIGHT);
            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(
                    pid, true), DataViewComponent.BOTTOM_RIGHT);

        //Put all other applications bottom right, 
        //which creates tabs within the bottom right tab    
        } else {
            dvc.addDetailsView(new SystemPropertiesViewSupport(
                    jvmProperties, app, count, appName).getDetailsView(), 
                    DataViewComponent.BOTTOM_RIGHT);
            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(
                    pid, true), DataViewComponent.BOTTOM_RIGHT);
        }

    }

    return dvc;

}

And here's the result again, this time with org.openide.awt.DropDownButtonFactory:

Update on 28 May 2008: The code and steps in this blog entry have been updated to reflect the VisualVM 1.0 APIs. If you want to download the complete sources of the sample discussed here, get the VisualVM Sample Collection from the Plugin Portal.

Comments:

thanks.

Posted by Komik Video on March 06, 2008 at 06:00 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today