/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.netbeans.editor.navigation; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.TimeUnit; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.text.Document; import org.antlr.netbeans.editor.text.VersionedDocument; import org.antlr.netbeans.editor.text.VersionedDocumentUtilities; import org.antlr.netbeans.parsing.spi.ParseContext; import org.antlr.netbeans.parsing.spi.ParserDataDefinition; import org.antlr.netbeans.parsing.spi.ParserTaskManager; import org.antlr.netbeans.parsing.spi.ParserTaskScheduler; import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.spi.navigator.NavigatorPanel; import org.openide.cookies.EditorCookie; import org.openide.loaders.DataObject; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.LookupEvent; import org.openide.util.LookupListener; import org.openide.util.Parameters; /** * * @author Sam Harwell * @param <PanelUI> */ public abstract class AbstractNavigatorPanel<PanelUI extends JComponent> implements NavigatorPanel { private final Lookup.Template<DataObject> TEMPLATE = new Lookup.Template<>(DataObject.class); @NonNull private final String _mimeType; @NonNull private final Collection<? extends ParserDataDefinition<?>> _dataDefinitions; private PanelUI component; private final LookupListener _listener = new LookupListener() { @Override public void resultChanged(LookupEvent ev) { Lookup.Result<DataObject> result = _result; if (result == null) { return; } for (DataObject instance : result.allInstances()) { scheduleTaskManagerUpdate(instance); // only schedule for the first item break; } } }; private Lookup _context; private Lookup.Result<DataObject> _result = Lookup.EMPTY.lookup(TEMPLATE); protected AbstractNavigatorPanel(@NonNull String mimeType, @NonNull ParserDataDefinition<?>... dataDefinitions) { Parameters.notNull("mimeType", mimeType); Parameters.notNull("dataDefinitions", dataDefinitions); this._mimeType = mimeType; this._dataDefinitions = new ArrayList<>(Arrays.asList(dataDefinitions)); } @Override public void panelActivated(Lookup context) { _context = context; _result = context.lookup(TEMPLATE); _result.addLookupListener(_listener); scheduleTaskManagerUpdate(context.lookup(DataObject.class)); } @Override public void panelDeactivated() { _context = null; _result.removeLookupListener(_listener); _result = Lookup.EMPTY.lookup(TEMPLATE); scheduleTaskManagerUpdate(null); } public boolean isExpectedContext(DataObject context) { return _result.allInstances().contains(context); } @NonNull @Override public final PanelUI getComponent() { if (this.component == null) { Runnable panelFactory = new Runnable() { @Override public void run() { if (component == null) { component = createPanelUI(); } } }; if (SwingUtilities.isEventDispatchThread()) { panelFactory.run(); } else { try { SwingUtilities.invokeAndWait(panelFactory); } catch (InterruptedException | InvocationTargetException ex) { Exceptions.printStackTrace(ex); } } } return this.component; } @NonNull protected abstract PanelUI createPanelUI(); protected void scheduleTaskManagerUpdate(@NullAllowed DataObject dataObject) { Document document = null; if (dataObject != null) { EditorCookie editorCookie = dataObject.getLookup().lookup(EditorCookie.class); document = editorCookie != null ? editorCookie.getDocument() : null; } VersionedDocument versionedDocument; if (document != null) { versionedDocument = VersionedDocumentUtilities.getVersionedDocument(document); } else if (dataObject != null) { versionedDocument = VersionedDocumentUtilities.getVersionedDocument(dataObject.getPrimaryFile()); } else { return; } if (!_mimeType.equals(versionedDocument.getMimeType())) { return; } ParseContext context = new ParseContext(ParserTaskScheduler.MANUAL_TASK_SCHEDULER, versionedDocument); Lookup.getDefault().lookup(ParserTaskManager.class).scheduleData(context, _dataDefinitions, 0, TimeUnit.MILLISECONDS); } }