2014-11-11 4 views
1

Я пытаюсь разработать плагин eclipse. Я знаю об этом.Разработка плагина Eclipse: как прослушивать события в редакторе Eclipse

В шаблоне пример плагина, когда мы нажмем пункт меню (или кнопку со значком затмения в изображении ниже в данном случае) в тестировании, например затмения, выполнить метод sampleHandler.java выполняется и поп- показанный на изображении ниже.

enter image description here

Я хочу, чтобы вызвать «выполнить» метод всякий раз, когда я нажимаю некоторые клавиши (позволяет сказать, что забой) в редакторе кода вместо нажатия любой пункт меню (или кнопки).

SampleHandler.java

public class SampleHandler extends AbstractHandler { 

    public SampleHandler() { 
    } 

    /** 
    * the command has been executed, so extract extract the needed information 
    * from the application context. 
    */ 
    public Object execute(ExecutionEvent event) throws ExecutionException { 
     IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); 
     MessageDialog.openInformation(
       window.getShell(), 
       "Sdfsdfsadf", 
       "Hello, Eclipse world"); 
     return null; 
    } 
    } 

Я попытался предложения, приведенные в other posts, но я не в состоянии достичь желаемой функциональности.

Согласно моему пониманию из ссылочного пост в строке выше, я попытался ниже код -

package eventlisten.handlers; 

import org.eclipse.core.commands.AbstractHandler; 
import org.eclipse.core.commands.ExecutionEvent; 
import org.eclipse.core.commands.ExecutionException; 
import org.eclipse.ui.IEditorInput; 
import org.eclipse.ui.IEditorPart; 
import org.eclipse.ui.IWorkbenchPage; 
import org.eclipse.ui.IWorkbenchWindow; 
import org.eclipse.ui.PlatformUI; 


import org.eclipse.ui.handlers.HandlerUtil; 
import org.eclipse.ui.texteditor.ITextEditor; 
import org.eclipse.jface.dialogs.MessageDialog; 
import org.eclipse.jface.text.DocumentEvent; 
import org.eclipse.jface.text.IDocument; 
import org.eclipse.jface.text.IDocumentListener; 

/** 
* Our sample handler extends AbstractHandler, an IHandler base class. 
* @see org.eclipse.core.commands.IHandler 
* @see org.eclipse.core.commands.AbstractHandler 
*/ 
public class SampleHandler extends AbstractHandler { 
    /** 
    * The constructor. 
    */ 
    public SampleHandler() { 
    } 

    /** 
    * the command has been executed, so extract extract the needed information 
    * from the application context. 
    */ 
    public Object execute(ExecutionEvent event) throws ExecutionException { 

     IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); 
     MessageDialog.openInformation(window.getShell(),"EventListen","Trying event listen"); 
     IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 
     IEditorPart editor = page.getActiveEditor(); 
     IEditorInput input = editor.getEditorInput(); 
     IDocument document=(((ITextEditor)editor).getDocumentProvider()).getDocument(IDocument.class); 

     document.addDocumentListener(new IDocumentListener() //**this is line 45** 
     { 
      @Override 
      public void documentAboutToBeChanged(DocumentEvent event) { 
       // TODO Auto-generated method stub 
       System.out.println("Hello"); 
      } 

      @Override 
      public void documentChanged(DocumentEvent event) { 
       // TODO Auto-generated method stub 
       System.out.println("Hello second"); 

      } 
     }); 

     return null; 
    } 
} 

Но после показа всплывающего окна, он бросает исключение -

java.lang.NullPointerException 
at eventlisten.handlers.SampleHandler.execute(SampleHandler.java:45) 
at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:290) 
at org.eclipse.core.commands.Command.executeWithChecks(Command.java:499) 
at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508) 
at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169) 
at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241) 
at org.eclipse.ui.menus.CommandContributionItem.handleWidgetSelection(CommandContributionItem.java:829) 
at org.eclipse.ui.menus.CommandContributionItem.access$19(CommandContributionItem.java:815) 
at org.eclipse.ui.menus.CommandContributionItem$5.handleEvent(CommandContributionItem.java:805) 
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) 
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1276) 
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3562) 
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3186) 
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701) 
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665) 
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499) 
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679) 
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) 
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668) 
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) 
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124) 
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) 
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) 
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) 
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353) 
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629) 
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584) 
at org.eclipse.equinox.launcher.Main.run(Main.java:1438) 
at org.eclipse.equinox.launcher.Main.main(Main.java:1414) 

Может кто-то руководство меня через процесс? Дайте мне знать, если потребуется дополнительная информация.

+0

Вы ссылаетесь на другой вопрос и ответ, но что конкретно вы пытались и какие результаты вы достигли или не смогли достичь? –

+0

Обновлено сообщение. Я даже не знаю, как продолжить использовать код этого сообщения. – User42

+0

Действительно ли вы хотите запускать выполнение каждый раз, когда пользователь нажимает клавишу или только если содержимое изменяется (или это достаточно даже, когда файл сохраняется)? Является ли 'document == null'? Вы можете проверить это, установив точку останова на linek 43, запустите плагин в режиме отладки и запустите строку 43 (F6 или перейдите на панель инструментов), а затем наведите указатель мыши на 'document'. Или вы можете сказать конкретно, какой экземпляр «null»? – bugybunny

ответ

3

Ваша первая проблема заключается в том, что вы только взаимодействуете с документами, когда пользователь нажимает кнопку. Есть лучшие способы установить это.
Насколько я могу судить, вы хотите либо определить, когда пользователь изменяет документ (возможно, путем ввода), любая клавиша вводится в любом месте, либо когда изменяется код AST. Вероятно, вы найдете только подходящих или полезных вопросов.

Прослушивание документа Изменения

Решение вы пытались ближе к первому, так что я начну там. Я сделал что-то вроде этого (в сообщении, которое вы связали, как выясняется). Начните с того, что ваш плагин расширяет org.eclipse.ui.запуск точки расширения, и определить класс, чтобы переопределить IStartup

Это earlyStartup() будет выглядеть примерно так:

@Override 
public void earlyStartup() { 
    IWorkbench wb = PlatformUI.getWorkbench(); 
    wb.addWindowListener(generateWindowListener()); 
} 

Мы будем слушать для окон, чтобы открыть, и когда они делают,

private IWindowListener generateWindowListener() 
{ 
    return new IWindowListener() { 
     @Override 
     public void windowOpened(IWorkbenchWindow window) { 
      IWorkbenchPage activePage = window.getActivePage(); 
      activePage.addPartListener(generateIPartListener2()); 
     } 

     @Override 
     public void windowDeactivated(IWorkbenchWindow window) {} 

     @Override 
     public void windowClosed(IWorkbenchWindow window) {} 

     @Override 
     public void windowActivated(IWorkbenchWindow window) {} 
    }; 
} 

Этот слушатель этой части должен получить EditorPart, что означает, что вы можете добавить слушателя документа:

private IPartListener2 generateIPartListener2() 
{ 
    return new IPartListener2() { 

     private void checkPart(IWorkbenchPartReference partRef) { 
     IWorkbenchPart part = partRef.getPart(false); 
      if (part instanceof IEditorPart) 
      { 
       IEditorPart editor = (IEditorPart) part; 
       IEditorInput input = editor.getEditorInput(); 
       if (editor instanceof ITextEditor && input instanceof FileEditorInput) //double check. Error Editors can also bring up this call 
       { 
        IDocument document=(((ITextEditor)editor).getDocumentProvider()).getDocument(input); 
        document.addDocumentListener(/* your listener from above*/); 
       } 
      } 
     } 

     @Override 
     public void partOpened(IWorkbenchPartReference partRef) { 
      checkPart(partRef); 
     } 

     @Override 
     public void partInputChanged(IWorkbenchPartReference partRef) 
     { 
      checkPart(partRef); 
     }   

     @Override 
     public void partVisible(IWorkbenchPartReference partRef){} 

     @Override 
     public void partHidden(IWorkbenchPartReference partRef) {} 

     @Override 
     public void partDeactivated(IWorkbenchPartReference partRef) {} 

     @Override 
     public void partClosed(IWorkbenchPartReference partRef) {} 

     @Override 
     public void partBroughtToTop(IWorkbenchPartReference partRef) {} 

     @Override 
     public void partActivated(IWorkbenchPartReference partRef) {} 
    }; 
} 

Слушая просто keypressess

Это заканчивает тем, что проще в реализации, но может быть очень шумным. Мы рассмотрим Display и Listener, которые попадают прямо в цикл событий SWT.

Вы хотите сделать расширение earlyStartup() еще раз, и есть что-то вроде:

@Override 
public void earlyStartup() { 
    Display display = Display.getDefault(); 
    display.setFilter(SWT.KeyUp, new Listener() { 
     @Override 
     public void handleEvent(Event event) { 
      //do stuff here. Be careful, this may cause lag 
     } 
    }); 
} 

Слушая Java AST изменения Окончательный один имеет простоту исходного KeyUp подхода, но вероятно, будет семантически полезен в качестве первой, которую я предложил. Мы будем непосредственно слушать JavaCore.

Опять же, в методе earlyStartup()

JavaCore.addElementChangedListener(new IElementChangedListener() { 

     @Override 
     public void elementChanged(ElementChangedEvent event) 
     { 
      //do stuff with the event 
     } 
    }); 

Заключение: С удачи, один из этих трех методов является полезным для вас. У меня были причины использовать их в своей карьере развития Eclipse - каждый из них полезен по-своему.

Надеюсь, это поможет.

Смежные вопросы