I’m writing an Eclipse plug-in in which the user can interact with another process via the Console view (in this case, an interpreter), for example, evaluate expressions and so on.
Sometimes the program needs to ask the interpreter for certain values. These interactions however, shouldn’t be shown in the console view to the user.
I have following instances:
private IProcess process;
private ILaunch launch;
private IStreamsProxy proxy;
the queries my program do are made via adding an IStreamListener to the proxy:
proxy.getOutputStreamMonitor().addListener(new IStreamListener(){
@Override
public void streamAppended(String response, IStreamMonitor arg1) {
doSomeStuffWiththeRepsonse(response);
}
});
while the listener is listening to the OutputStreamMonitor of the proxy, I don’t want the response to pop up in the console view of the plugin.
How can I do that?
Okay, here is how I did it.
The launch system of Eclipse works as follows:
1. Implement a
ILaunchConfigurationDelegate, the only method in this interface islaunch, which recieves anILaunchConfiguration, a mode, anILaunchand anIProgressMonitor.In my program, launch starts an inferiorProcess using
DebugPlugin.exec()using a commandline argument. Then a new Process is created by callingDebugPlugin.newProcess()with theILaunch, the inferiorProcess, the name for the interpreter and some attributes.This method creates a new
RuntimeProcessand adds it to the ILaunch and vice versa.2. Define a
LaunchConfigurationTypeby using the extension pointorg.eclipse.debug.core.launchConfigurationTypesand add it to theplugin.xml:The extension point gives the exact path to the
ILaunchConfigurationDelegateclass created as above (1) and an unqiue identifier (2) to retrieve the instance ofILaunchConfigurationTypefrom the LaunchManager used to launch the program. (3) defines the modes it can run as,runanddebug. The name (4) is later shown in the top bar of the console view. If you only want to access and launch your external program programmatically in your plug-in (and not via the Run drop-down menu) (5) must be set to false.3. Create a class that stores the Instances of
IProcess,ILaunchandIStreamsProxyand which calls apropiate methods to start the process and to write onto the streamsproxy. A method for starting the process could look like this:Now to the initial problem of the question
The
IStreamsListenerof the console view, which listens to theOutputStreamMonitorof theIStreamsProxycould not be retrieved and thus not being stopped of listening. Prints to the console could not be prevented.OutputStreamMonitordoesn’t provide methods to get the current listeners. It is not possible to just subclass it and override/add some methods, because the important fields and methods are private.http://www.java2s.com/Open-Source/Java-Document/IDE-Eclipse/debug/org/eclipse/debug/internal/core/OutputStreamMonitor.java.htm
Just copy the code and add a get-method for the fListeners field and change some method modifiers to public.
In order to get your own OutputStreamMonitor into the system, you need to create your own IStreamsProxy. Again only subclassing wont work, you need to copy the code again and make some changes.
http://www.java2s.com/Open-Source/Java-Document/IDE-Eclipse/debug/org/eclipse/debug/internal/core/StreamsProxy.java.htm
Important:
The only thing remaining is providing your own
IProcessthat uses yourIStreamsProxy. This time subclassingRuntimeProcessand overriding the methodcreateStreamsProxy()is enough:MyProcessis integrated by creating a new instance of it in the launch method in theILaunchConfigurationDelegateinstead of usingDebugPlugin.newProcess().Now it is possible to hide and expose the output of the console view.
The hide and expose methods have to be called before any other listeners are added. There might be a better solution, however, this works.