1 /* 2 * Copyright (c) 2008, 2016, 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 */ 24 package com.sun.hotspot.igv.coordinator; 25 26 import com.sun.hotspot.igv.connection.Server; 27 import com.sun.hotspot.igv.coordinator.actions.*; 28 import com.sun.hotspot.igv.data.GraphDocument; 29 import com.sun.hotspot.igv.data.Group; 30 import com.sun.hotspot.igv.data.services.GroupCallback; 31 import java.awt.BorderLayout; 32 import java.io.IOException; 33 import java.io.ObjectInput; 34 import java.io.ObjectOutput; 35 import java.io.Serializable; 36 import javax.swing.UIManager; 37 import javax.swing.border.Border; 38 import org.openide.ErrorManager; 39 import org.openide.actions.GarbageCollectAction; 40 import org.openide.awt.Toolbar; 41 import org.openide.awt.ToolbarPool; 42 import org.openide.explorer.ExplorerManager; 43 import org.openide.explorer.ExplorerUtils; 44 import org.openide.explorer.view.BeanTreeView; 45 import org.openide.util.LookupEvent; 46 import org.openide.util.LookupListener; 47 import org.openide.util.NbBundle; 48 import org.openide.util.actions.NodeAction; 49 import org.openide.windows.TopComponent; 50 import org.openide.windows.WindowManager; 51 52 /** 53 * 54 * @author Thomas Wuerthinger 55 */ 56 public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener { 57 58 public static OutlineTopComponent instance; 59 public static final String PREFERRED_ID = "OutlineTopComponent"; 60 private ExplorerManager manager; 61 private GraphDocument document; 62 private FolderNode root; 63 private Server server; 64 private Server binaryServer; 65 66 private OutlineTopComponent() { 67 initComponents(); 68 69 setName(NbBundle.getMessage(OutlineTopComponent.class, "CTL_OutlineTopComponent")); 70 setToolTipText(NbBundle.getMessage(OutlineTopComponent.class, "HINT_OutlineTopComponent")); 71 72 document = new GraphDocument(); 73 initListView(); 74 initToolbar(); 75 initReceivers(); 76 } 77 78 private void initListView() { 79 manager = new ExplorerManager(); 80 root = new FolderNode(document); 81 manager.setRootContext(root); 82 ((BeanTreeView) this.treeView).setRootVisible(false); 83 84 associateLookup(ExplorerUtils.createLookup(manager, getActionMap())); 85 } 86 87 private void initToolbar() { 88 89 Toolbar toolbar = new Toolbar(); 90 Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N 91 toolbar.setBorder(b); 92 this.add(toolbar, BorderLayout.NORTH); 93 94 toolbar.add(ImportAction.get(ImportAction.class)); 95 96 toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup())); 97 toolbar.add(SaveAllAction.get(SaveAllAction.class)); 98 99 toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup())); 100 toolbar.add(RemoveAllAction.get(RemoveAllAction.class)); 101 102 toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter()); 103 104 for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) { 105 tb.setVisible(false); 106 } 107 } 108 109 private void initReceivers() { 110 111 final GroupCallback callback = new GroupCallback() { 112 113 @Override 114 public void started(Group g) { 115 synchronized(OutlineTopComponent.this) { 116 getDocument().addElement(g); 117 } 118 } 119 }; 120 121 server = new Server(getDocument(), callback, false); 122 binaryServer = new Server(getDocument(), callback, true); 123 } 124 125 public void clear() { 126 document.clear(); 127 root = new FolderNode(document); 128 manager.setRootContext(root); 129 } 130 131 @Override 132 public ExplorerManager getExplorerManager() { 133 return manager; 134 } 135 136 public GraphDocument getDocument() { 137 return document; 138 } 139 140 /** 141 * Gets default instance. Do not use directly: reserved for *.settings files only, 142 * i.e. deserialization routines; otherwise you could get a non-deserialized instance. 143 * To obtain the singleton instance, use {@link findInstance}. 144 */ 145 public static synchronized OutlineTopComponent getDefault() { 146 if (instance == null) { 147 instance = new OutlineTopComponent(); 148 } 149 return instance; 150 } 151 152 /** 153 * Obtain the OutlineTopComponent instance. Never call {@link #getDefault} directly! 154 */ 155 public static synchronized OutlineTopComponent findInstance() { 156 TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); 157 if (win == null) { 158 ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find Outline component. It will not be located properly in the window system."); 159 return getDefault(); 160 } 161 if (win instanceof OutlineTopComponent) { 162 return (OutlineTopComponent) win; 163 } 164 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."); 165 return getDefault(); 166 } 167 168 @Override 169 public int getPersistenceType() { 170 return TopComponent.PERSISTENCE_ALWAYS; 171 } 172 173 @Override 174 public void componentOpened() { 175 this.requestActive(); 176 } 177 178 @Override 179 public void componentClosed() { 180 } 181 182 @Override 183 protected String preferredID() { 184 return PREFERRED_ID; 185 } 186 187 @Override 188 public void requestActive() { 189 super.requestActive(); 190 treeView.requestFocus(); 191 } 192 193 @Override 194 public boolean requestFocus(boolean temporary) { 195 treeView.requestFocus(); 196 return super.requestFocus(temporary); 197 } 198 199 @Override 200 protected boolean requestFocusInWindow(boolean temporary) { 201 treeView.requestFocus(); 202 return super.requestFocusInWindow(temporary); 203 } 204 205 @Override 206 public void resultChanged(LookupEvent lookupEvent) { 207 } 208 209 @Override 210 public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException { 211 // Not called when user starts application for the first time 212 super.readExternal(objectInput); 213 ((BeanTreeView) this.treeView).setRootVisible(false); 214 } 215 216 @Override 217 public void writeExternal(ObjectOutput objectOutput) throws IOException { 218 super.writeExternal(objectOutput); 219 } 220 221 static final class ResolvableHelper implements Serializable { 222 223 private static final long serialVersionUID = 1L; 224 225 public Object readResolve() { 226 return OutlineTopComponent.getDefault(); 227 } 228 } 229 230 /** This method is called from within the constructor to 231 * initialize the form. 232 * WARNING: Do NOT modify this code. The content of this method is 233 * always regenerated by the Form Editor. 234 */ 235 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents 236 private void initComponents() { 237 238 treeView = new BeanTreeView(); 239 240 setLayout(new java.awt.BorderLayout()); 241 add(treeView, java.awt.BorderLayout.CENTER); 242 }// </editor-fold>//GEN-END:initComponents 243 244 // Variables declaration - do not modify//GEN-BEGIN:variables 245 private javax.swing.JScrollPane treeView; 246 // End of variables declaration//GEN-END:variables 247 }