Quickly create class from an interface in eclipse

后端 未结 5 941
时光取名叫无心
时光取名叫无心 2020-12-29 20:16

Is there a plugin for eclipse which allows me to quickly generate a new class from an interface?

Rather than having to do the typing in the new class dialog

相关标签:
5条回答
  • 2020-12-29 20:38

    I've not seen any plugins that do this, but it seems a reasonable shortcut to me.

    The following could form the basis for a plugin to generate a class directly from a selected interface. It works on my box(TM).

    It currently assumes the class will take the interface name suffixed with "Impl" and fails (logging the reason) if that type already exists.

    Some enhancements I can think of:

    • allow selection of multiple interfaces
    • define a preference page for the implementation suffix and package name
    • open a dialogue with the values populated if the "default" implementation already exists

    The plugin adds a command to the context menu for editors, views and text selections, disabling the item if the selection doesn't resolve to an interface. It can also be activated with ctrl-6 (you can obviously change the key-bindings in the plugin.xml to suit your mood).

    The plugin code is as follows:

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

    The plugin.xml to contribute the command is:

    <?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>
    

    and the manifest.mf looks like this:

    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
    
    0 讨论(0)
  • 2020-12-29 20:38

    Havn't seen anything other than: right click the interface type in the package explorer, chose New->Class and it will automatically implement that interface. You still have to name the new class yourself.

    0 讨论(0)
  • 2020-12-29 20:43

    Method 1: Right click on the class name, then choose "Quick Fix", and then a small menu will appear, within which you choose: "Add unimplemented methods".

    Method 2: Right click on the class name, go to "Source", then choose "Override/Implement Methods"

    0 讨论(0)
  • 2020-12-29 20:49

    If you create a class, let it implement an interface.

    You get errors, because the methods are not defined. Just Ctrl-1, or right clic, and you can create all methods, with TODOs, javadoc comments and so on as needed (depending on the way your Eclipse is configured).

    0 讨论(0)
  • 2020-12-29 20:55

    It was actually asked as soon as 2002

    The refactoring should extract all (switch for "all public") methods from a class, create an interface and rename the old class to ClassnameImpl.

    ... and entered as a feature request, "resolved "in ticket 9798, because the New->Class will have the option "Inherited abstract method" (since at least Eclipse SDK 2.1 2003) for you to choose in order to automatically implement those public abstract methods.

    alt text

    0 讨论(0)
提交回复
热议问题