1/* 2 * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24package com.sun.hotspot.igv.bytecodes; 25 26import com.sun.hotspot.igv.data.Group; 27import com.sun.hotspot.igv.data.InputGraph; 28import com.sun.hotspot.igv.data.services.InputGraphProvider; 29import com.sun.hotspot.igv.util.LookupHistory; 30import java.awt.BorderLayout; 31import java.io.Serializable; 32import javax.swing.SwingUtilities; 33import org.openide.ErrorManager; 34import org.openide.explorer.ExplorerManager; 35import org.openide.explorer.ExplorerUtils; 36import org.openide.explorer.view.BeanTreeView; 37import org.openide.util.*; 38import org.openide.windows.TopComponent; 39import org.openide.windows.WindowManager; 40 41/** 42 * @author Thomas Wuerthinger 43 */ 44final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener { 45 46 private static BytecodeViewTopComponent instance; 47 private static final String PREFERRED_ID = "BytecodeViewTopComponent"; 48 private ExplorerManager manager; 49 private BeanTreeView treeView; 50 private Lookup.Result result = null; 51 private MethodNode rootNode; 52 53 private BytecodeViewTopComponent() { 54 initComponents(); 55 setName(NbBundle.getMessage(BytecodeViewTopComponent.class, "CTL_BytecodeViewTopComponent")); 56 setToolTipText(NbBundle.getMessage(BytecodeViewTopComponent.class, "HINT_BytecodeViewTopComponent")); 57 58 manager = new ExplorerManager(); 59 rootNode = new MethodNode(null, null, ""); 60 manager.setRootContext(rootNode); 61 62 setLayout(new BorderLayout()); 63 64 treeView = new BeanTreeView(); 65 treeView.setRootVisible(false); 66 this.add(BorderLayout.CENTER, treeView); 67 associateLookup(ExplorerUtils.createLookup(manager, getActionMap())); 68 } 69 70 /** This method is called from within the constructor to 71 * initialize the form. 72 * WARNING: Do NOT modify this code. The content of this method is 73 * always regenerated by the Form Editor. 74 */ 75 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents 76 private void initComponents() { 77 78 org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); 79 this.setLayout(layout); 80 layout.setHorizontalGroup( 81 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 82 .add(0, 400, Short.MAX_VALUE) 83 ); 84 layout.setVerticalGroup( 85 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 86 .add(0, 300, Short.MAX_VALUE) 87 ); 88 }// </editor-fold>//GEN-END:initComponents 89 // Variables declaration - do not modify//GEN-BEGIN:variables 90 // End of variables declaration//GEN-END:variables 91 92 /** 93 * Gets default instance. Do not use directly: reserved for *.settings files only, 94 * i.e. deserialization routines; otherwise you could get a non-deserialized instance. 95 * To obtain the singleton instance, use {@link findInstance}. 96 */ 97 public static synchronized BytecodeViewTopComponent getDefault() { 98 if (instance == null) { 99 instance = new BytecodeViewTopComponent(); 100 } 101 return instance; 102 } 103 104 /** 105 * Obtain the BytecodeViewTopComponent instance. Never call {@link #getDefault} directly! 106 */ 107 public static synchronized BytecodeViewTopComponent findInstance() { 108 TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); 109 if (win == null) { 110 ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find BytecodeView component. It will not be located properly in the window system."); 111 return getDefault(); 112 } 113 if (win instanceof BytecodeViewTopComponent) { 114 return (BytecodeViewTopComponent) win; 115 } 116 ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior."); 117 return getDefault(); 118 } 119 120 @Override 121 public int getPersistenceType() { 122 return TopComponent.PERSISTENCE_ALWAYS; 123 } 124 125 @Override 126 public void componentOpened() { 127 Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class); 128 result = Utilities.actionsGlobalContext().lookup(tpl); 129 result.addLookupListener(this); 130 } 131 132 @Override 133 public void componentClosed() { 134 result.removeLookupListener(this); 135 result = null; 136 } 137 138 @Override 139 public Object writeReplace() { 140 return new ResolvableHelper(); 141 } 142 143 @Override 144 protected String preferredID() { 145 return PREFERRED_ID; 146 } 147 148 @Override 149 public ExplorerManager getExplorerManager() { 150 return manager; 151 } 152 153 @Override 154 public void requestActive() { 155 super.requestActive(); 156 this.treeView.requestFocus(); 157 } 158 159 @Override 160 public boolean requestFocus(boolean temporary) { 161 this.treeView.requestFocus(); 162 return super.requestFocus(temporary); 163 } 164 165 @Override 166 protected boolean requestFocusInWindow(boolean temporary) { 167 this.treeView.requestFocus(); 168 return super.requestFocusInWindow(temporary); 169 } 170 171 @Override 172 public void resultChanged(LookupEvent lookupEvent) { 173 final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class); 174 SwingUtilities.invokeLater(new Runnable() { 175 @Override 176 public void run() { 177 if (p != null) { 178 InputGraph graph = p.getGraph(); 179 if (graph != null) { 180 Group g = graph.getGroup(); 181 rootNode.update(graph, g.getMethod()); 182 return; 183 } 184 } 185 rootNode.update(null, null); 186 } 187 }); 188 189 } 190 191 final static class ResolvableHelper implements Serializable { 192 193 private static final long serialVersionUID = 1L; 194 195 public Object readResolve() { 196 return BytecodeViewTopComponent.getDefault(); 197 } 198 } 199} 200