2009-09-06 13 views
26

Esiste un plug-in per eclipse che mi consente di generare rapidamente una nuova classe da un'interfaccia?Crea rapidamente classe da un'interfaccia in eclissi

Invece di dover fare la digitazione nella nuova finestra di dialogo

Idealmente avermi permesso di scegliere un nome standard come Impl per poter generare

+1

la finestra di dialogo "nuova classe" non è abbastanza veloce per voi? – skaffman

+5

pigro su scala epica – laurie

+2

Chiaramente, ma non vedo come potrebbe essere più veloce di quello che è già ... si digita il nome della classe, selezionare l'interfaccia e la procedura guidata genererà un'implementazione predefinita di tale interfaccia. .. come potrebbe essere più veloce? – skaffman

risposta

4

Non ho visto nessun plug-in che faccia questo, ma mi sembra un collegamento ragionevole.

Quanto segue potrebbe costituire la base per un plugin per generare una classe direttamente da un'interfaccia selezionata. Funziona sulla mia scatola (TM).

Attualmente si presuppone che la classe abbia il nome dell'interfaccia suffisso con "Impl" e non riesca (registrando il motivo) se tale tipo esiste già.

Alcuni miglioramenti mi viene in mente:

  • consentono la selezione di più interfacce
  • definire una pagina delle preferenze per l'attuazione suffisso e il pacchetto nome
  • aprire un dialogo con i valori popolati se il "default "l'implementazione esiste già

Il plugin aggiunge un comando al menu di scelta rapida per editor, viste e selezioni di testo, disabilitando l'elemento se il sel ection non si risolve in un'interfaccia. Può anche essere attivato con ctrl-6 (ovviamente puoi cambiare i collegamenti dei tasti nel plugin.xml per adattarlo al tuo umore).

Il codice del plugin è la seguente:

package name.seller.rich.classwizard.actions; 

import java.util.Collections; 

import org.eclipse.core.commands.AbstractHandler; 
import org.eclipse.core.commands.ExecutionEvent; 
import org.eclipse.core.commands.ExecutionException; 
import org.eclipse.core.expressions.EvaluationContext; 
import org.eclipse.core.resources.IFile; 
import org.eclipse.core.resources.IResource; 
import org.eclipse.core.runtime.CoreException; 
import org.eclipse.core.runtime.NullProgressMonitor; 
import org.eclipse.jdt.core.ICompilationUnit; 
import org.eclipse.jdt.core.IJavaElement; 
import org.eclipse.jdt.core.IType; 
import org.eclipse.jdt.core.JavaModelException; 
import org.eclipse.jdt.internal.ui.JavaPlugin; 
import org.eclipse.jdt.internal.ui.actions.SelectionConverter; 
import org.eclipse.jdt.ui.wizards.NewClassWizardPage; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.ui.IWorkbenchPage; 
import org.eclipse.ui.IWorkbenchPart; 
import org.eclipse.ui.IWorkbenchWindow; 
import org.eclipse.ui.PartInitException; 
import org.eclipse.ui.handlers.HandlerUtil; 
import org.eclipse.ui.ide.IDE; 
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; 

public class GenerateClassHandler extends AbstractHandler { 

    public GenerateClassHandler() { 
    } 

    public Object execute(ExecutionEvent event) throws ExecutionException { 
     NewClassWizardPage page = new NewClassWizardPage(); 

     EvaluationContext evaluationContext = (EvaluationContext) event 
       .getApplicationContext(); 

     IWorkbenchPart activePart = (IWorkbenchPart) evaluationContext 
       .getVariable("activePart"); 
     try { 
      IStructuredSelection selection = SelectionConverter 
        .getStructuredSelection(activePart); 

      IType type = getFirstType(selection); 

      if (type != null && type.exists() && type.isInterface()) { 
       page.init(selection); 

       String typeName = type.getElementName() + "Impl"; 
       // TODO handle existing type 
       page.setTypeName(typeName, true); 

       // generate constructors and methods, allow modification 
       page.setMethodStubSelection(false, true, true, true); 

       page.setSuperInterfaces(Collections.singletonList(type 
         .getFullyQualifiedName()), true); 
       try { 
        page.createType(new NullProgressMonitor()); 

        IResource resource = page.getModifiedResource(); 
        if (resource != null) { 
         IWorkbenchWindow window = HandlerUtil 
           .getActiveWorkbenchWindowChecked(event); 
         BasicNewResourceWizard 
           .selectAndReveal(resource, window); 
         openResource((IFile) resource, window); 
        } 
       } catch (CoreException e) { 
        // TODO if we get this the type already exists, open a 
        // dialogue to allow the type name to be modified or give 
        // up? 
        logException(e); 
       } 

      } 
     } catch (JavaModelException e) { 
      logException(e); 
     } catch (InterruptedException e) { 
      logException(e); 
     } 
     return null; 
    } 

    protected void openResource(final IFile resource, 
      IWorkbenchWindow window) { 
     final IWorkbenchPage activePage = window.getActivePage(); 
     if (activePage != null) { 
      final Display display = window.getShell().getDisplay(); 
      if (display != null) { 
       display.asyncExec(new Runnable() { 
        public void run() { 
         try { 
          IDE.openEditor(activePage, resource, true); 
         } catch (PartInitException e) { 
          logException(e); 
         } 
        } 
       }); 
      } 
     } 
    } 

    @Override 
    public void setEnabled(Object context) { 
     if (context != null && context instanceof EvaluationContext) { 
      EvaluationContext evaluationContext = (EvaluationContext) context; 

      IWorkbenchPart activePart = (IWorkbenchPart) evaluationContext 
        .getVariable("activePart"); 

      try { 
       IStructuredSelection selection = SelectionConverter 
         .getStructuredSelection(activePart); 

       IType type = getFirstType(selection); 

       if (type != null) { 
        setBaseEnabled(type.isInterface()); 
        return; 
       } 
      } catch (JavaModelException e) { 
       logException(e); 
      } 
     } 

     setBaseEnabled(false); 
    } 

    private IType getFirstType(IStructuredSelection selection) { 
     IJavaElement[] elements = SelectionConverter.getElements(selection); 

     if (elements != null && elements.length > 0) { 
      if (elements[0] != null && elements[0] instanceof IType) { 
       return (IType) elements[0]; 
      } 

      try { 
       if (elements[0] != null 
         && elements[0] instanceof ICompilationUnit) { 
        IType[] types = ((ICompilationUnit) elements[0]) 
          .getAllTypes(); 

        if (types != null && types.length > 0) { 
         return types[0]; 
        } 
       } 
      } catch (JavaModelException e) { 
       logException(e); 
      } 
     } 
     return null; 
    } 

    protected void logException(Exception e) { 
     JavaPlugin.log(e); 
    } 
} 

La plugin.xml contribuire il comando è:

<?xml version="1.0" encoding="UTF-8"?> 
<?eclipse version="3.0"?> 
<plugin> 
    <extension 
    point="org.eclipse.ui.commands"> 
     <command 
     name="Generate Class" 
     categoryId="name.seller.rich.classwizard.category" 
     id="name.seller.rich.classwizard.generateClassCommand"> 
     </command> 
    </extension> 
    <extension 
    point="org.eclipse.ui.handlers"> 
     <handler 
     commandId="name.seller.rich.classwizard.generateClassCommand" 
     class="name.seller.rich.classwizard.actions.GenerateClassHandler"> 
     </handler> 
    </extension> 
    <extension 
    point="org.eclipse.ui.bindings"> 
     <key 
     commandId="name.seller.rich.classwizard.generateClassCommand" 
     contextId="org.eclipse.ui.contexts.window" 
     sequence="M1+6" 
     schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"> 
     </key> 
    </extension> 
    <extension 
    point="org.eclipse.ui.menus"> 
     <menuContribution 
     locationURI="popup:org.eclipse.ui.popup.any?after=additions"> 
    <command 
      commandId="name.seller.rich.classwizard.generateClassCommand" 
      mnemonic="G"> 
    </command> 
     </menuContribution> 
    </extension> 
</plugin> 

e manifest.mf si presenta così:

Manifest-Version: 1.0 
Bundle-ManifestVersion: 2 
Bundle-Name: Classwizard 
Bundle-SymbolicName: name.seller.rich.classwizard; singleton:=true 
Bundle-Version: 1.0.0 
Require-Bundle: org.eclipse.ui, 
org.eclipse.core.runtime, 
org.eclipse.jdt.core;bundle-version="3.5.0", 
org.eclipse.core.expressions;bundle-version="3.4.100", 
org.eclipse.jface.text;bundle-version="3.5.0", 
org.eclipse.jdt.ui;bundle-version="3.5.0", 
org.eclipse.ui.ide;bundle-version="3.5.0", 
org.eclipse.ui.editors;bundle-version="3.5.0", 
org.eclipse.core.resources;bundle-version="3.5.0" 
Eclipse-AutoStart: true 
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 
36

Havn't visto niente di altra classe di: tasto destro del mouse il tipo di interfaccia nel pacchetto explorer, scegli New-> Class e questa interfaccia verrà implementata automaticamente. Devi ancora nominare la nuova classe da solo.

+0

Non funziona. Tui hai torto. – user710818

+30

@ user710818 Forse stai facendo clic con il pulsante destro del mouse sul file .java in Esplora pacchetti, non sul tipo (ad esempio, espandi il file .java contenente l'interfaccia e fai clic con il pulsante destro del mouse sul tipo di interfaccia, seleziona Nuovo-> Classe). Questo funziona perfettamente in Indigo e Helios almeno. – nos

+2

@nos Grazie, ha funzionato anche su Luna –

7

In realtà è stato chiesto non appena as 2002

Il refactoring dovrebbe estrarre tutti (interruttore per "tutti i pubblici") metodi da una classe, creare un'interfaccia e rinominare la vecchia classe a Classname Impl .

... ed è entrato come un feature request, "risolta" in ticket 9798, perché il Nuovo-> classe avrà l'opzione 'metodo astratto ereditato' (almeno dal Eclipse SDK 2.1 2003) per voi a scegliere, al fine di implementa automaticamente quei metodi astratti pubblici.

alt text

+0

Sei un contributore? Sembra davvero che tu ne sappia parecchio :) – javamonkey79

+0

@ javamonkey79: no, ma alcuni contributori di eclissi rispondono a domande SO: vedi ad esempio questa risposta (e il suo commento): http://stackoverflow.com/questions/1363584/eclipse-improve-debugging-and-display-vairable-values-on-mouseover/1363640 # 1363640 – VonC

+2

Quello che mi piacerebbe vedere è la finestra di dialogo Nuova classe precompilata con la mia interfaccia selezionata nell'elenco "implementa". – Arkadiy

3

Se si crea una classe, lasciarlo implementare un'interfaccia.

Si verificano errori, perché i metodi non sono definiti. Basta Ctrl-1, o fai clic destro, e puoi creare tutti i metodi, con TODO, commenti javadoc e così via secondo necessità (a seconda del modo in cui Eclipse è configurato).

0

Metodo 1: fare clic con il pulsante destro del mouse sul nome della classe, quindi scegliere "Correzione rapida", un d poi apparirà un piccolo menu, all'interno del quale scegli: "Aggiungi metodi non implementati".

Metodo 2: Fare clic destro sul nome della classe, andare a "Source", quindi scegliere "Override/implementare metodi"