MegaEntry 网络社区与信息交流平台!
重构是使用一些小变换重新设计代码,但不会改变任何程序行为。就像您构造一个表达式使它更容易理解和修改一样,您重构代码可以使其更容易读,更容易理解,更快更新。就像重构的表达式必须产生相同的效果一样,重构的程序必须与原始源具有相同的功能。
重构代码的一些常见目的包括:
本教程向您介绍如何通过添加附加的重构功能即 Copy Class 来扩展 IDE。Copy Class 功能允许您向相同或不同的包复制类。当您复制类时,您可以更改名称,也可以更改构造方法的名称。如果该类被复制到一个新包,则自动更新包声明。
本教程将介绍以下主题:
有关创建 NetBeans 插件模块的更多信息,请参见 NetBeans 网站上的 NetBeans Development Project 主页。如果有问题,请访问 NetBeans Developer FAQ 或使用本页顶部的反馈链接。
开始编写插件模块之前,必须确保您具备所有必要的软件。此外,您可能想在亲自构建之前使用示例。
开始之前,需要在您的计算机上安装以下软件:
采用以下步骤来安装示例:
将打开 Copy Class 对话框,如下所示:
也可以使用 To Package 下拉菜单选择将 Java 源文件复制到的包。如果没有选择包,则将该文件复制到包含原始文件的包。
现在您了解了 Copy Class Refactoring 插件模块的用户界面,让我们从头开始创建该模块。
开始编写模块前,必须确保正确地设置了项目。
当您使 IDE 的源可用于 NetBeans Platform Manager 时,您可以从 Source Editor 中访问 IDE 的源文件和 Javadoc。这样便简化了插件模块的开发,原因是它使您能够非常快速地查找有关执行的类和方法的信息。整个教程中都提到源和 Javadoc,因此应该在进行下一步前先使它们可用。
IDE 创建 CopyClassRefactoring 项目。该项目包含所有资源和项目元数据,如该项目的 Ant 构建脚本。该项目在 IDE 中打开。您可以在 Projects 窗口 (Ctrl-1) 中查看其逻辑结构,在 Files 窗口 (Ctrl-2) 中查看其文件结构。
您需要将几个属于 NetBeans API 的类设为子类。每个类都将被声明为 Module 依存关系。使用 Project Properties 对话框来执行此操作。
<?xml version= "1.0 " encoding= "UTF-8 "?>
<project xmlns= "http://www.netbeans.org/ns/project/1 ">
<type>org.netbeans.modules.apisupport.project</type>
<configuration>
<data xmlns= "http://www.netbeans.org/ns/nb-module-project/2 ">
<code-name-base>org.netbeans.modules.refactoring.copyclass</code-name-base>
<standalone/>
<module-dependencies>
<dependency>
<code-name-base>javax.jmi.reflect</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.6</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.api.mdr</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.jmi.javamodel</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>2</release-version>
<specification-version>1.19.0</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.java</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.24.0.2.2.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.java.project</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.7</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.javacore</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.16.0.2.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.jmiutils</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.4.0.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.projectapi</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.refactoring</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<implementation-version/>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.awt</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.6</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.filesystems</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.loaders</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>5.4</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.nodes</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.text</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.2</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.5</specification-version>
</run-dependency>
</dependency>
</module-dependencies>
<public-packages/>
</data>
</configuration>
</project>
重构的非可视部分执行重构逻辑。基本上它由两个类组成,即“refactoring”类和“refactoring plugin”类。
refactoring 类作为用于调用重构的 API。此外,refactoring plugin 类使用它来确定重构参数。refactoring 类本身几乎不执行任何工作,所有工作都由 refactoring plugin 类来完成。refactoring 类通常只包含重构参数的获取方法和设置方法。参数为 newName、targetFolder 和 targetPackageName。它们在 Copy Class 对话框中使用:
执行以下操作:
package org.netbeans.modules.refactoring.copyclass; import org.netbeans.jmi.javamodel.Resource; import org.netbeans.modules.refactoring.api.AbstractRefactoring; import org.netbeans.modules.refactoring.classpath.Util; import org.openide.filesystems.FileObject; public final class CopyClassRefactoring extends AbstractRefactoring { private Resource resource; private FileObject targetFolder; private String targetPackageName; private String newName; /** Creates a new instance of CopyClassRefactoring * */ public CopyClassRefactoring(Resource resource) { this.resource = resource; } protected void setClassPath() { // leave the complete classpath Util.setDefaultClassPath(); } public Resource getResource() { return resource; } // --- START PARAMETERS ---------------------------------------------------------- public FileObject getTargetClassPathRoot() { return targetFolder; } public void setTargetClassPathRoot(FileObject targetFolder) { this.targetFolder = targetFolder; } public String getTargetPackageName() { return targetPackageName; } public void setTargetPackageName(String newName) { this.targetPackageName = newName; } public String getNewName() { return newName; } public void setNewName(String newName) { this.newName = newName; } // --- END PARAMETERS ---------------------------------------------------------- }
单击该链接。AbstractRefactoring 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其 CopyClassRefactoring 实现相关。
每个重构都应该至少有一个执行所有工作的插件类。重构模块本身应该提供进行 J2SE 重构的基本插件类。其他模块可以添加其他插件,这允许它们参与重构。例如,当重命名一个方法时,J2EE 插件类需要重命名 EJB(如有必要)的其他界面中的相关方法,并且更改部署描述符。下面介绍的插件类是执行所有基本 J2SE 工作的基本插件类。
插件类需要实现的四个方法为:
由 prepare() 方法实例化重构元素并将其添加到作为输出参数的 RefactoringElementsBag 的实例。
所有上面的方法都返回名为 Problem 的类的实例。该类的实例代表对于执行重构来说可能是致命的或非致命的问题。这些方法执行各种检查(如给定重构的规范中所述)并返回它们发现的问题作为提到的 Problem 类的实例。可以将这些问题链接起来(使用 Problem.setNext() 方法),这有可能返回单次操作中的几个问题。注意致命问题必须位于链首。使用 JavaRefactoringPlugin.createProblem() 方法创建问题将自动确保此要求。所有方法(除 fastCheckParameters() 之外)都应该激发进度事件,因为它们正在执行潜在的耗费时间的操作。
执行以下操作:
package org.netbeans.modules.refactoring.copyclass;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.netbeans.jmi.javamodel.Element;
import org.netbeans.jmi.javamodel.Import;
import org.netbeans.jmi.javamodel.ImportClass;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.JavaModelPackage;
import org.netbeans.jmi.javamodel.Resource;
import org.netbeans.modules.javacore.JMManager;
import org.netbeans.modules.javacore.api.JavaModel;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.javacore.internalapi.JavaModelUtil;
import org.netbeans.modules.refactoring.CheckUtils;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.api.MoveClassRefactoring;
import org.netbeans.modules.refactoring.api.Problem;
import org.netbeans.modules.refactoring.api.RenameRefactoring;
import org.netbeans.modules.refactoring.plugins.JavaRefactoringPlugin;
import org.netbeans.modules.refactoring.plugins.MoveClassRefactoringPlugin;
import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImpl;
import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.text.PositionBounds;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
/** Plugin that implements the core functionality of Copy Class Refactoring.
*/
public class CopyClassRefactoringPlugin extends JavaRefactoringPlugin {
/** Reference to the parent refactoring instance */
private final CopyClassRefactoring refactoring;
/** Creates a new instance of PullUpRefactoringPlugin
* @param refactoring Parent refactoring instance.
*/
CopyClassRefactoringPlugin(CopyClassRefactoring refactoring) {
this.refactoring = refactoring;
}
/** Checks pre-conditions of the refactoring.
* @return Problems found or null.
*/
public Problem preCheck() {
fireProgressListenerStart(AbstractRefactoring.PRE_CHECK, 4);
try {
Resource resource = refactoring.getResource();
// check whether the element is valid
Problem result = isElementAvail(resource);
if (result != null) {
// fatal error -> don 't continue with further checks
return result;
}
if (!CheckUtils.isElementInOpenProject(resource)) {
return new Problem(true, NbBundle.getMessage(JavaRefactoringPlugin.class, "ERR_ProjectNotOpened "));
}
// increase progress (step 1)
fireProgressListenerStep();
// increase progress (step 2)
fireProgressListenerStep();
// increase progress (step 3)
fireProgressListenerStep();
// all checks passed -> return null
return null;
} finally {
// fire operation end on the registered progress listeners
fireProgressListenerStop();
}
}
public Problem fastCheckParameters() {
if (!Utilities.isJavaIdentifier(refactoring.getNewName())) {
String msg = new MessageFormat(NbBundle.getMessage(RenameRefactoring.class, "ERR_InvalidIdentifier ")).format(
new Object[] {refactoring.getNewName()}
);
return createProblem(null, true, msg);
}
if (!isValidPackageName(refactoring.getTargetPackageName())) {
String msg = new MessageFormat(NbBundle.getMessage(RenameRefactoring.class, "ERR_InvalidPackage ")).format(
new Object[] {refactoring.getTargetPackageName()}
);
return createProblem(null, true, msg);
}
String name = refactoring.getTargetPackageName().replace( '. ', '/ ') + '/ ' + refactoring.getNewName() + ".java ";
if (refactoring.getTargetClassPathRoot().getFileObject(name) != null)
return createProblem(null, true,
new MessageFormat(NbBundle.getMessage(MoveClassRefactoring.class,
"ERR_ClassToMoveClashes ")).format(new Object[]{refactoring.getNewName()}));
return null;
}
private static boolean isValidPackageName(String name) {
StringTokenizer tokenizer = new StringTokenizer(name, ". "); // NOI18N
while (tokenizer.hasMoreTokens()) {
if (!Utilities.isJavaIdentifier(tokenizer.nextToken())) {
return false;
}
}
return true;
}
public Problem checkParameters() {
return null;
}
public Problem prepare(RefactoringElementsBag refactoringElements) {
refactoringElements.add(refactoring,
new CopyClass(
refactoring.getResource(),
refactoring.getTargetClassPathRoot(),
refactoring.getTargetPackageName(),
refactoring.getNewName()
));
return null;
}
}
单击该链接。JavaRefactoringPlugin 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其 CopyClassRefactoringPlugin 实现相关。
private static class CopyClass extends SimpleRefactoringElementImpl implements RefactoringElementImplementation{ private DataObject source; private FileObject targetRoot; private String targetPackageName; private String newName; private Resource resource; public CopyClass (Resource resource, FileObject targetRoot, String packageName, String newName) { this.source = ((JMManager) JMManager.getManager()).getDataObject(resource); this.resource = resource; this.targetRoot = targetRoot; this.targetPackageName = packageName; this.newName = newName; } public String getText() { return getDisplayText (); } public String getDisplayText() { return new MessageFormat (NbBundle.getMessage(CopyClassRefactoringPlugin.class, "TXT_CopyClassToPackage ")).format ( // NOI18N new Object[] {newName, targetPackageName, resource.getName()} ); } public Element getJavaElement() { return null; } public PositionBounds getPosition() { return null; } public void performChange() { String nameAfterCopy = null; try { FileObject fo = FileUtil.createFolder(targetRoot, targetPackageName.replace( '. ', '/ ')); DataFolder folder = DataFolder.findFolder(fo); objectToDelete = source.copy(folder); nameAfterCopy = objectToDelete.getName(); objectToDelete.rename(newName); } catch (IOException ioe) { ErrorManager.getDefault().notify(ioe); } Resource r = JavaModel.getResource(objectToDelete.getPrimaryFile()); String name = resource.getPackageName(); ImportClass proxy = ((JavaModelPackage) r.refOutermostPackage()).getImport(); Import addedImport = proxy.createImport(name, null, false, true); r.addImport(addedImport); for (Iterator i = r.getClassifiers().iterator(); i.hasNext(); ) { JavaClass c = (JavaClass) i.next(); if (c.getSimpleName().equals(nameAfterCopy)) { c.setSimpleName(newName); } } } private DataObject objectToDelete = null; public FileObject getParentFile() { return source.getPrimaryFile(); } }
单击该链接。RefactoringElementImplementation 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其内部 CopyClass 实现相关。
插件类的实例化由插件工厂执行。通过重构调用调用的 META-INF/services 文件夹中的一个条目,插件工厂在 NetBeans 查询中注册。为了确保调用给定重构时实例化插件类,您需要在工厂的 createInstance() 方法的开始部分为您的插件类添加以下实例化代码:
if (refactoring instanceof YourRefactoring) {
return new YourRefactoringPlugin((YourRefactoring) refactoring);
}
从上面可以看出,createInstance() 方法将父重构视为参数。每个插件类应该参考父重构以便能够从中获得重构参数。这就是插件类通常将重构作为构造方法参数的原因。
执行以下操作:
package org.netbeans.modules.refactoring.copyclass;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.spi.RefactoringPlugin;
import org.netbeans.modules.refactoring.spi.RefactoringPluginFactory;
public class PluginsFactory implements RefactoringPluginFactory {
/** Factory method called by a refactoring. Creates and returns a new plugin
* instance for a given refactoring. If no plugin for a given refactoring
* is present, this method returns null.
* @param refactoring Parent refactoring for which a plugin should be created.
* @return New instance of a refactoring plugin for the provided refactoring
* or null.
*/
public RefactoringPlugin createInstance(AbstractRefactoring refactoring) {
if (refactoring instanceof CopyClassRefactoring) {
return new CopyClassRefactoringPlugin((CopyClassRefactoring) refactoring);
}
return null;
}
}
单击该链接。RefactoringPluginFactory 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其 PluginsFactory 实现相关。
org.netbeans.modules.refactoring.copyclass.PluginsFactory
此时,Projects 窗口应该如下所示:
用户界面由三个组件组成:
要实现重构操作,您需要创建 org.netbeans.modules.refactoring.spi.ui.AbstractRefactoringAction 的子类。感兴趣的部分是 enabled() 和 createRefactoringUI() 方法:
执行以下操作:
package org.netbeans.modules.refactoring.copyclass.ui;
import org.netbeans.jmi.javamodel.Element;
import org.netbeans.modules.java.JavaDataObject;
import org.netbeans.modules.javacore.JMManager;
import org.netbeans.modules.javacore.api.JavaModel;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.refactoring.spi.ui.AbstractRefactoringAction;
import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
public class CopyClassAction extends AbstractRefactoringAction {
/** Creates a new instance of PullUpAction
*/
public CopyClassAction() {
super(NbBundle.getMessage(CopyClassAction.class, "LBL_CopyClass_Action "), null); // NOI18N
putValue( "noIconInMenu ", Boolean.TRUE); // NOI18N
}
/** Method responsible for creating RefactoringUI object.
* @param nodes Active nodes to perform the refactoring on.
* @param selectedElement Element to perform the refactoring on or null if the action
* was not invoked from the editor - in that case the active nodes take
* the precedence.
* @return RefactoringUI object for Copy Class refactoring.
*/
protected RefactoringUI createRefactoringUI(Node[] nodes, Element selectedElement) {
if (selectedElement == null) {
// selected element is null -> action was invoked on nodes
JavaDataObject ob = (JavaDataObject) nodes[0].getCookie(JavaDataObject.class);
selectedElement = JavaModel.getResource(ob.getPrimaryFile());
}
return new CopyClassRefactoringUI(selectedElement.getResource());
}
/** Method that determines whether this action is enabled for the active nodes.
* @param activatedNodes Active nodes.
* @return Boolean indicating whether the action is enabled.
*/
protected boolean enabled(Node[] activatedNodes) {
// if no nodes are active, the action should be disabled
if (activatedNodes.length != 1) return false;
// the action should be enabled only if all selected nodes are associated
// with the same JavaDataObject (i.e. they are all declared in the same Java file)
// so, let 's get dataobject from the first activated node
DataObject dobj = (DataObject) activatedNodes[0].getCookie(DataObject.class);
// check if the dataobject is instance of JavaDataObejct and that it represents a file
// that is on the IDE classpath (belongs to one of open projects)
if ((dobj instanceof JavaDataObject) && ((JMManager) JavaMetamodel.getManager()).mergedCPContains(dobj.getPrimaryFile())) {
return true;
} else {
return false;
}
}
protected String iconResource () {
return "org/netbeans/modules/refactoring/resources/refactoring.gif "; // NOI18N
}
}
单击该链接。AbstractRefactoringAction 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其 CopyClassAction 实现相关。
要将该模块插入到重构框架中,您需要创建 org.netbeans.modules.refactoring.spi.ui.RefactoringUI 的子类。感兴趣的部分是 getPanel() 和 checkParameters() 方法:
执行以下操作:
package org.netbeans.modules.refactoring.copyclass.ui;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.Resource;
import org.netbeans.modules.javacore.api.JavaModel;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.api.Problem;
import org.netbeans.modules.refactoring.copyclass.CopyClassRefactoring;
import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
import org.netbeans.modules.refactoring.spi.ui.ParametersPanel;
import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
import org.netbeans.modules.refactoring.ui.PullUpRefactoringUI;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
public class CopyClassRefactoringUI implements RefactoringUI {
// reference to pull up refactoring this UI object corresponds to
private final CopyClassRefactoring refactoring;
// UI panel for collecting parameters
private CopyClassPanel panel;
public CopyClassRefactoringUI(Resource resource) {
refactoring = new CopyClassRefactoring(resource);
}
// --- IMPLEMENTATION OF RefactoringUI INTERFACE ---------------------------
public boolean isQuery() {
return false;
}
public CustomRefactoringPanel getPanel(ParametersPanel parent) {
if (panel == null) {
panel = new CopyClassPanel(parent, getName()
+ " - " + ((JavaClass) refactoring.getResource().getClassifiers().get(0)).getName(),
refactoring.getResource().getPackageName(), JavaModel.getFileObject(refactoring.getResource()));
}
return panel;
}
public Problem setParameters() {
setupRefactoring();
return refactoring.checkParameters();
}
public Problem checkParameters() {
if (panel==null)
return null;
setupRefactoring();
return refactoring.fastCheckParameters();
}
private void setupRefactoring() {
refactoring.setTargetClassPathRoot(panel.getRootFolder());
refactoring.setTargetPackageName(panel.getPackageName().replace( '/ ', '. '));
refactoring.setNewName(panel.getNewName());
}
public AbstractRefactoring getRefactoring() {
return refactoring;
}
public String getDescription() {
return NbBundle.getMessage(CopyClassAction.class, "DSC_CopyClass ", refactoring.getNewName()); // NOI18N
}
public String getName() {
return NbBundle.getMessage(CopyClassAction.class, "LBL_CopyClass "); // NOI18N
}
public boolean hasParameters() {
return true;
}
public HelpCtx getHelpCtx() {
return new HelpCtx(PullUpRefactoringUI.class.getName());
}
}
单击该链接。RefactoringUI 类在 Source Editor 中打开。熟悉一下源文件并理解它如何与其内部 CopyClassRefactoringUI 实现相关。
执行以下操作:
package org.netbeans.modules.refactoring.copyclass.ui;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectInformation;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.Sources;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
import org.netbeans.modules.refactoring.spi.ui.ParametersPanel;
import org.netbeans.spi.java.project.support.ui.PackageView;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
public class CopyClassPanel extends CustomRefactoringPanel implements ActionListener, DocumentListener {
private static final ListCellRenderer GROUP_CELL_RENDERER = new GroupCellRenderer();
private static final ListCellRenderer PROJECT_CELL_RENDERER = new ProjectCellRenderer();
private Project project;
private ParametersPanel parent;
private FileObject fo;
private SourceGroup[] groups;
public CopyClassPanel(final ParametersPanel parent, String title, String startPackage, FileObject f) {
setName(title);
this.fo = f;
this.parent = parent;
initComponents();
setCombosEnabled(true);
setThisClassVisible(true);
rootComboBox.setRenderer(GROUP_CELL_RENDERER);
packageComboBox.setRenderer(PackageView.listRenderer());
projectsComboBox.setRenderer( PROJECT_CELL_RENDERER );
rootComboBox.addActionListener( this );
packageComboBox.addActionListener( this );
projectsComboBox.addActionListener( this );
Object textField = packageComboBox.getEditor().getEditorComponent();