我正在编写一个Eclipse插件,用户可以通过Console视图(在本例中为解释器)与另一个进程交互,例如,计算表达式等等。
有时程序需要向口译员询问某些值。但是,这些交互不应在控制台视图中显示给用户。
我有以下实例:
private IProcess process;
private ILaunch launch;
private IStreamsProxy proxy;
我的程序执行的查询是通过向代理添加IStreamListener
来完成的:
proxy.getOutputStreamMonitor().addListener(new IStreamListener(){
@Override
public void streamAppended(String response, IStreamMonitor arg1) {
doSomeStuffWiththeRepsonse(response);
}
});
当侦听器正在侦听代理的OutputStreamMonitor
时,我不希望响应在插件的控制台视图中弹出。
我该怎么做?
答案 0 :(得分:3)
好的,我就是这样做的。
Eclipse的启动系统的工作原理如下:
1。实施ILaunchConfigurationDelegate
,此界面中唯一的方法是launch
,它接收ILaunchConfiguration
,模式,{{1}和ILaunch
。
在我的程序中,使用命令行参数使用IProgressMonitor
启动inferiorProcess。然后通过使用DebugPlugin.exec()
,inferiorProcess,解释器的名称和一些属性调用DebugPlugin.newProcess()
来创建新的Process。
此方法创建一个新的ILaunch
并将其添加到ILaunch,反之亦然。
2。使用扩展点RuntimeProcess
定义LaunchConfigurationType
并将其添加到org.eclipse.debug.core.launchConfigurationTypes
:
plugin.xml
扩展点给出了如上创建的<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
delegate="myplugin.MyLaunchConfigurationDelegate" (1)
id="myplugin.myExternalProgram" (2)
modes="run" (3)
name="MyExternalProgram" (4)
public="false"> (5)
</launchConfigurationType>
</extension>
类的确切路径(1)和unqiue标识符(2),用于从用于启动程序的LaunchManager中检索ILaunchConfigurationDelegate
的实例。 (3)定义它可以运行的模式,ILaunchConfigurationType
和run
。稍后将在控制台视图的顶部栏中显示名称(4)。如果您只想在插件中以编程方式访问和启动外部程序(而不是通过“运行”下拉菜单),则必须将(5)设置为false。
3。创建一个存储debug
,IProcess
和ILaunch
实例的类,并调用适当的方法启动进程并写入streamsproxy。启动流程的方法可能如下所示:
IStreamsProxy
现在问题的初始问题
无法检索监听// is the process already running?
public boolean isRunning() {
boolean result = false;
try {
if (this.process != null) {
result = true;
this.process.getExitValue();
result = false;
}
}
catch (DebugException exception) {
}
return result;
}
// start the process
public void start() {
try {
if (!isRunning()) {
// get the ILaunchConfigurationType from the platform
ILaunchConfigurationType configType = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(myplugin.myExternalProgram);
// the ILaunchConfigurationType can't be changed or worked with, so get a WorkingCopy
ILaunchConfigurationWorkingCopy copy = configType.newInstance(null, "myExternalProgram");
this.launch = copy.launch(ILaunchManager.RUN_MODE, new NullProgressMonitor());
IProcess[] processes = this.launch.getProcesses();
if (processes.length > 0) {
// get the IProcess instance from the launch
this.process = this.launch.getProcesses()[0];
// get the streamsproxy from the process
this.proxy = this.process.getStreamsProxy();
}
}
}
catch (CoreException exception) {
}
if (isRunning())
// bring up the console and show it in the workbench
showConsole();
}
public void showConsole() {
if (this.process != null && this.process.getLaunch() != null) {
IConsole console = DebugUITools.getConsole(this.process);
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IViewPart view = page.findView("org.eclipse.ui.console.ConsoleView");
if (view != null)
view.setFocus();
}
}
IStreamsListener
的控制台视图的OutputStreamMonitor
,因此不会停止监听。无法阻止打印到控制台。 IStreamsProxy
不提供获取当前侦听器的方法。不可能只是将其子类化并覆盖/添加一些方法,因为重要的字段和方法是私有的。
只需复制代码并为fListeners字段添加get方法,并将一些方法修饰符更改为public。 为了将您自己的OutputStreamMonitor放入系统,您需要创建自己的IStreamsProxy。再次只是子类化不能工作,你需要再次复制代码并进行一些更改。
重要的:
OutputStreamMonitor
唯一剩下的就是提供使用public class MyStreamsProxy implements IStreamsProxy, IStreamsProxy2 {
/**
* The monitor for the output stream (connected to standard out of the process)
*/
private MyOutputStreamMonitor fOutputMonitor;
/**
* The monitor for the error stream (connected to standard error of the process)
*/
private MyOutputStreamMonitor fErrorMonitor;
(...)
public MyStreamsProxy(Process process) {
if (process == null) {
return;
}
fOutputMonitor = new MyOutputStreamMonitor(process
.getInputStream());
fErrorMonitor = new MyOutputStreamMonitor(process
.getErrorStream());
fInputMonitor = new InputStreamMonitor(process
.getOutputStream());
fOutputMonitor.startMonitoring();
fErrorMonitor.startMonitoring();
fInputMonitor.startMonitoring();
}
的{{1}}。这次子类化{{1}}并覆盖方法IProcess
就足够了:
IStreamsProxy
RuntimeProcess
是通过在createStreamsProxy()
中的启动方法中创建新实例而不是使用public class MyProcess extends RuntimeProcess {
public MyProcess(ILaunch launch, Process process, String name,
Map attributes) {
super(launch, process, name, attributes);
}
@Override
protected IStreamsProxy createStreamsProxy() {
String encoding = getLaunch().getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING);
return new MyStreamsProxy(getSystemProcess());
}
}
来集成的。
现在可以隐藏和公开控制台视图的输出。
MyProcess
在添加任何其他侦听器之前,必须调用hide和expose方法。可能有更好的解决方案,但是,这有效。
答案 1 :(得分:1)
以前的答案可以解决这个问题,而且在尝试解决这个问题后,我会先尝试类似的事情。最后我最终做了一些更简单的事情,但也有些麻烦...基本上:
...
ILaunch launch = launcconf.launch(
ILaunchManager.RUN_MODE, monitor);
DebugUIPlugin.getDefault().
getProcessConsoleManager().launchRemoved(launch);
...
所以,我基本上告诉控制台管理器监听器方法已经删除了这个lauch并删除了控制台。似乎至少为我做了诀窍。
答案 2 :(得分:0)
我不希望在插件的控制台视图中弹出响应。我怎么能这样做?
那么,这是您的实际问题,然后只需在控制台视图上切换一个名为“标准输出更改时显示控制台”的按钮。比所有这些更简单的方法,它可以打开/关闭。