@Override protected JComponent createExtComponent() { JTextComponent component = getComponent(); // Add the scroll-pane with the component to the center JScrollPane scroller = new JScrollPane(component); scroller.getViewport().setMinimumSize(new Dimension(4, 4)); // remove default scroll-pane border, winsys will handle borders itself Border empty = BorderFactory.createEmptyBorder(); // Important: Do not delete or use null instead, will cause // problems on GTK L&F. Must set both scroller border & viewport // border! - Tim scroller.setBorder(empty); scroller.setViewportBorder(empty); if (component.getClientProperty("nbeditorui.vScrollPolicy") != null) { scroller.setVerticalScrollBarPolicy( (Integer) component.getClientProperty("nbeditorui.vScrollPolicy")); } if (component.getClientProperty("nbeditorui.hScrollPolicy") != null) { scroller.setHorizontalScrollBarPolicy( (Integer) component.getClientProperty("nbeditorui.hScrollPolicy")); } // extComponent will be a panel JComponent ec = new JPanel(new BorderLayout()); ec.putClientProperty(JTextComponent.class, component); ec.add(scroller); // Initialize sidebars // Need to clear the cache - it's null at this point when opening file but the sidebars // would be reused during L&F change (see BaseTextUI.UIWatcher) which would not work properly. CustomizableSideBar.resetSideBars(component); Map<SideBarPosition, JComponent> sideBars = CustomizableSideBar.getSideBars(component); processSideBars(sideBars, ec); if (listener == null) { listener = new SideBarsListener(component); CustomizableSideBar.addChangeListener(NbEditorUtilities.getMimeType(component), listener); } // Initialize the corner component initGlyphCorner(scroller); return ec; }
/** Not private because of the tests. */ static Lookup createActionContext(JTextComponent c) { Lookup nodeLookup = null; DataObject dobj = (c != null) ? NbEditorUtilities.getDataObject(c.getDocument()) : null; if (dobj != null && dobj.isValid()) { nodeLookup = dobj.getNodeDelegate().getLookup(); } Lookup ancestorLookup = null; for (java.awt.Component comp = c; comp != null; comp = comp.getParent()) { if (comp instanceof Lookup.Provider) { Lookup lookup = ((Lookup.Provider) comp).getLookup(); if (lookup != null) { ancestorLookup = lookup; break; } } } Lookup componentLookup = Lookups.singleton(c); if (nodeLookup == null && ancestorLookup == null) { return componentLookup; } else if (nodeLookup == null) { return new ProxyLookup(new Lookup[] {ancestorLookup, componentLookup}); } else if (ancestorLookup == null) { return new ProxyLookup(new Lookup[] {nodeLookup, componentLookup}); } assert nodeLookup != null && ancestorLookup != null; Node node = (Node) nodeLookup.lookup(Node.class); boolean ancestorLookupContainsNode = ancestorLookup.lookup(new Lookup.Template(Node.class)).allInstances().contains(node); if (ancestorLookupContainsNode) { return new ProxyLookup(new Lookup[] {ancestorLookup, componentLookup}); } else { return new ProxyLookup(new Lookup[] {nodeLookup, ancestorLookup, componentLookup}); } }
/** * Add the presenters (usually buttons) for the contents of the toolbar contained in the base and * mime folders. * * @param baseFolder folder that corresponds to "text/base" * @param mimeFolder target mime type folder. * @param toolbar toolbar being constructed. */ private void addPresenters() { JTextComponent c = getComponent(); String mimeType = c == null ? null : NbEditorUtilities.getMimeType(c); if (mimeType == null) { return; // Probably no component or it's not loaded properly } List<? extends MultiKeyBinding> keybindings = null; Lookup actionContext = null; List items = ToolbarActionsProvider.getToolbarItems(mimeType); // COMPAT: The ToolbarsActionsProvider treats 'text/base' in a special way. It // will list only items registered for this particular mime type, but won't // inherit anything else. The 'text/base' is normally empty, but could be // used by some legacy code. List oldTextBaseItems = ToolbarActionsProvider.getToolbarItems("text/base"); // NOI18N if (oldTextBaseItems.size() > 0) { items = new ArrayList(items); items.add(new JSeparator()); items.addAll(oldTextBaseItems); } for (Object item : items) { LOG.log(Level.FINE, "Adding item {0}", item); // NOI18N if (item == null || item instanceof JSeparator) { addSeparator(); continue; } if (item instanceof String) { EditorKit kit = c.getUI().getEditorKit(c); if (kit instanceof BaseKit) { Action a = ((BaseKit) kit).getActionByName((String) item); if (a != null) { if (LOG.isLoggable(Level.FINE)) { LOG.log( Level.FINE, "Item {0} converted to an editor action {1}", new Object[] {item, s2s(a)}); // NOI18N } item = a; } else { // unknown action continue; } } } if (item instanceof ContextAwareAction) { if (actionContext == null) { Lookup context = createActionContext(c); actionContext = context == null ? NO_ACTION_CONTEXT : context; } if (actionContext != NO_ACTION_CONTEXT) { Action caa = ((ContextAwareAction) item).createContextAwareInstance(actionContext); // use the context aware instance only if it implements Presenter.Toolbar // or is a Component else fall back to the original object if (caa instanceof Presenter.Toolbar || caa instanceof Component) { if (LOG.isLoggable(Level.FINE)) { LOG.log( Level.FINE, "Item {0} converted to a context-aware Action {1}", new Object[] {s2s(item), s2s(caa)}); // NOI18N } item = caa; } } } if (item instanceof Presenter.Toolbar) { Component presenter = ((Presenter.Toolbar) item).getToolbarPresenter(); if (presenter != null) { if (LOG.isLoggable(Level.FINE)) { LOG.log( Level.FINE, "Item {0} converted to a Presenter.Toolbar {1}", new Object[] {s2s(item), s2s(presenter)}); // NOI18N } item = presenter; } } if (item instanceof Component) { add((Component) item); if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Adding component {0}", s2s(item)); // NOI18N } } else if (item instanceof Action) { // Wrap action to execute on the proper text component // because the default fallback in TextAction.getTextComponent() // might not work properly if the focus was switched // to e.g. a JTextField and then toolbar was clicked. Action a = new WrapperAction(componentRef, (Action) item); // Try to find an icon if not present updateIcon(a); // Add the action and let the JToolbar to creat a presenter for it item = add(a); if (LOG.isLoggable(Level.FINE)) { LOG.log( Level.FINE, "Adding action {0} as {1}", new Object[] {s2s(a), s2s(item)}); // NOI18N } } else { // Some sort of crappy item -> ignore if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Ignoring item {0}", s2s(item)); // NOI18N } continue; } if (item instanceof AbstractButton) { AbstractButton button = (AbstractButton) item; processButton(button); if (keybindings == null) { List<? extends MultiKeyBinding> l = getKeyBindingList(); keybindings = l == null ? Collections.<MultiKeyBinding>emptyList() : l; } updateTooltip(button, keybindings); if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Special treatment for button {0}", s2s(item)); // NOI18N } } } }