2011-10-15 3 views
2

사용자가 콘솔보기 (이 경우 인터프리터)를 통해 다른 프로세스와 상호 작용할 수있는 Eclipse 플러그인을 작성하고 있습니다 (예 : 표현식 평가 등).콘솔보기의 출력을 숨기는 방법은 무엇입니까?

때때로 프로그램은 인터프리터에 특정 값을 요청해야합니다. 그러나 이러한 상호 작용은 콘솔보기에서 사용자에게 표시하면 안됩니다.

나는 다음 한 경우 :

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을 듣고있는 동안, 플러그인의 콘솔보기에 응답을 표시하고 싶지 않습니다.

어떻게하면됩니까?

답변

3

좋아요, 여기 제가 어떻게했는지 설명합니다. 다음

일식의 실행 시스템의 작동 :

1ILaunchConfigurationDelegate 구현이 인터페이스에서 유일한 방법은 ILaunchConfiguration하는 모드, ILaunchIProgressMonitor을 접수에있는 launch이다.

내 프로그램에서 launch는 명령 행 인수를 사용하여 DebugPlugin.exec()을 사용하여 inferiorProcess를 시작합니다. 그런 다음 ILaunch, inferiorProcess, 인터프리터의 이름 및 일부 속성을 사용하여 DebugPlugin.newProcess()을 호출하여 새 프로세스를 만듭니다. 이 메서드는 새로운 RuntimeProcess을 만들고 ILaunch에 ILaunch를 추가하며 그 반대의 경우도 마찬가지입니다.

2 확장 점 org.eclipse.debug.core.launchConfigurationTypes를 사용하여 LaunchConfigurationType을 정의하고 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)와 상기에서 작성한 ILaunchConfigurationDelegate 클래스에 대한 정확한 경로를 제공 unqiue 식별자 (2)를 사용하여 프로그램 시작에 사용되는 LaunchManager에서 ILaunchConfigurationType의 인스턴스를 검색합니다. (3)은 실행할 수있는 모드를 rundebug으로 정의합니다. 이름 (4)은 나중에 콘솔보기의 상단 표시 줄에 표시됩니다. 플러그인에서 (실행 드롭 다운 메뉴를 통하지 않고) 프로그래밍 방식으로 외부 프로그램에 액세스하고 실행하려는 경우 (5)를 false로 설정해야합니다.

3.

는 apropiate 방법 프로세스를 시작하고 streamsproxy에 쓰기를 호출 IProcess, ILaunchIStreamsProxy와의 인스턴스를 저장하는 클래스를 만듭니다.과정을 시작하는 방법은 다음과 같을 수 있습니다 :

// 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(); 
      } 
    } 

을 지금 IStreamsProxyOutputStreamMonitor를 검색 할 수 없습니다에 수신하는 질문 콘솔보기
IStreamsListener의 초기 문제 따라서 듣기를 멈추지 않습니다. 콘솔에 인쇄하는 것을 막을 수 없었습니다. OutputStreamMonitor은 현재 리스너를 가져 오는 메소드를 제공하지 않습니다. 중요한 필드와 메소드는 private이기 때문에 하위 클래스로 만들고 일부 메소드를 재정의/추가하는 것은 불가능합니다.

http://www.java2s.com/Open-Source/Java-Document/IDE-Eclipse/debug/org/eclipse/debug/internal/core/OutputStreamMonitor.java.htm

그냥 코드를 복사하고 fListeners 필드에 대한 GET 메소드를 추가하고 대중에게 몇 가지 방법 수정을 변경합니다. 자신의 OutputStreamMonitor를 시스템에 가져 오려면 자신 만의 IStreamsProxy를 만들어야합니다. 다시 서브 클래 싱 만 작동하지 않으면 코드를 다시 복사하고 약간 변경해야합니다. 중요

http://www.java2s.com/Open-Source/Java-Document/IDE-Eclipse/debug/org/eclipse/debug/internal/core/StreamsProxy.java.htm

:

유일한 것은 당신의 IStreamsProxy 사용하여 자신의 IProcess를 제공하고 나머지
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(); 
    } 

. 이 시간 RuntimeProcess를 서브 클래스 및 방법 createStreamsProxy()를 오버라이드 (override)는 충분하다 :

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 대신 DebugPlugin.newProcess()을 사용하는 ILaunchConfigurationDelegate에서 발사 방법에의 새로운 인스턴스를 생성하여 통합됩니다.

이제 콘솔보기의 출력을 숨기거나 노출 할 수 있습니다.

/** 
    * Storage field for the console listener 
    */ 
    private IStreamListener oldListener; 


    /** 
    * Hides the output coming from the process so the user doesn't see it. 
    */ 
    protected void hideConsoleOutput() { 
     MyOutputStreamMonitor out 
      = (MyOutputStreamMonitor) this.process.getStreamsProxy().getOutputStreamMonitor(); 
     List<IStreamListener> listeners = out.getListeners(); 
     // the console listener 
     this.oldListener = listeners.get(0); 
     out.removeListener(this.oldListener); 

    } 

    /** 
    * Reverts the changes made by hideConsoleOutput() so the user sees the response from the process again. 
    */ 
    protected void exposeConsoleOutput() { 
     MyOutputStreamMonitor out 
     = (MyOutputStreamMonitor) this.process.getStreamsProxy().getOutputStreamMonitor(); 
     out.addListener(oldListener); 
     this.oldListener = null; 

    } 

다른 수신기가 추가되기 전에 hide 및 expose 메서드를 호출해야합니다. 그러나 더 좋은 해결책이있을 수도 있습니다.

1

이전 답변은 트릭을 수행하며이 문제를 해결하기 위해 몇 시간 만에 비슷한 질문을했습니다. 마지막으로 나는 조금 간단하게 뭔가를하고 결국뿐만 아니라, 다소 지저분하고 ... 기본적으로 :

... 
ILaunch launch = launcconf.launch(
     ILaunchManager.RUN_MODE, monitor); 
DebugUIPlugin.getDefault(). 
     getProcessConsoleManager().launchRemoved(launch); 
... 

그래서, 나는 기본적으로이 미사일이 이미 제거 된 콘솔 관리자 리스너 방법을 말하고 그것은 콘솔을 제거 . 적어도 나를 위해 속임수를 쓰는 것 같습니다.

0

플러그인의 콘솔보기에 응답을 표시하고 싶지 않습니다. 내가 어떻게 할 수 있니?

그럼 실제 관심사이므로 "표준 출력이 변경되면 콘솔 표시"라는 콘솔보기의 단추를 토글하십시오. 이 모든 것보다 더 단순한 접근 방식으로, 다시 켜고 끌 수 있습니다.

관련 문제