扩展NetBeans IDE 6.0中的C/C++编辑器以提供标志实例的高亮
当前位置:以往代写 > C/C++ 教程 >扩展NetBeans IDE 6.0中的C/C++编辑器以提供标志实例的高亮
2019-06-13

扩展NetBeans IDE 6.0中的C/C++编辑器以提供标志实例的高亮

扩展NetBeans IDE 6.0中的C/C++编辑器以提供标志实例的高亮

副标题#e#

教程需求

在继承前,请确保您从头查抄了本节的需求。

先决条件

本 教程假设您已经有一些利用 IDE 的根基常识和 Java 编程履历。

本教程所需的软 件

在开始前,您需要安装 NetBeans 6.0。您将同时需要 C/C++ 和 Java SE 支持,所 以最佳选择是选择“下载全部”选项并在安装时解除 Base IDE、Java SE 和 C/C++ 包之外的所有模块。

筹备项目

对本教程,我们需要两个项目。一个是管 理我们的插件的源代码的 NetBeans 模块。另一个是用来测试它的 C++ 项目。

创 建 NetBeans 插件模块

选择“文件”>“新建项目”。在 “新建项目”领导中,选择“种别”下的“NetBeans 模块 ”和“项目”下的“模块”。单击“下一步”。

在“名称和位置”页,在“项目名称”字段中键入 MarkOccurrences,并把“项目位置”配置到磁盘上一个适当的文件夹里。请 选中“独立模块”和“配置为主项目”,假如没有选中的话。单击 “下一步”。

在“根基模块设置”页,在“代码名称 基”字段中键入 org.netbeans.modules.markoccurrences。单击“完成 ”。

在本项目中,我们需要一些依赖干系。在“项目”窗口,右 键单击“库”节点并在“添加模块依赖干系”对话框中选择 “库”,然后添加屏幕快照里列出的各个库。C/C++ 模块 API 正处于开拓中 ,所以您需要在对话框中选择“显示非-API 模块”,以便在模块列表中看到 它们。

扩展NetBeans IDE 6.0中的C/C++编辑器以提供符号实例的高亮

右键 单击各个 C/C++ 模块,选择“编辑”,然后选择“实现版本”。

建设测试应用措施

选择“文件”>“新建项目”。选 择“样例”>“C/C++”>“C/C++”种别下的 Args 项目。单击“下一步”。

在“项目名称和位置”页, 把“项目位置”配置到磁盘上一个适当的文件夹里。单击“完成” 。

现已建设了 Args_1 项目。在编辑器中打开 arg.c 源文件。我们将利用这个文 件来测试我们的模块。

建设高亮基本布局

此刻我们将利用 NetBeans API 来向 C/C++ 编辑器添加高亮显示。


#p#副标题#e#

建设高亮提供者

在标志实例项目标“源包 ”节点中右键单击包 org.netbeans.modules.markoccurrences,然后选择“ 新建”>“Java 类”。

将新类定名为 MarkOccurrencesHighlighter 并单击“完成”。

用下面的代码替换新 类中的代码:package org.netbeans.modules.markoccurrences;
import java.awt.Color;
import java.lang.ref.WeakReference;
import javax.swing.JEditorPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.Document;
import javax.swing.text.StyleConstants;
import org.netbeans.api.editor.settings.AttributesUtilities;
import org.netbeans.modules.cnd.modelutil.CsmUtilities;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.spi.editor.highlighting.support.OffsetsBag;
import org.openide.cookies.EditorCookie;
import org.openide.loaders.DataObject;
public class MarkOccurrencesHighlighter implements CaretListener {
  private static final AttributeSet defaultColors = AttributesUtilities.createImmutable(StyleConstants.Background, new Color(236, 235, 163));
  public void caretUpdate(CaretEvent e) {
    bag.clear();
    bag.addHighlight(0, 5, defaultColors);
  }

  private final WeakReference<Document> weakDoc;
  public MarkOccurrencesHighlighter(Document doc) {
    bag = new OffsetsBag(doc);
    weakDoc = new WeakReference<Document> ((Document) doc);
    DataObject dobj = NbEditorUtilities.getDataObject(weakDoc.get());
    JEditorPane[] panes = CsmUtilities.getOpenedPanesInEQ(dobj.getCookie (EditorCookie.class));
    if (panes != null && panes.length > 0) {
      panes[0].addCaretListener(this);
    }
  }
  private final OffsetsBag bag;
  public OffsetsBag getHighlightsBag() {
    return bag;
  }
}本类尚未 提供任何智能成果。它只是向光标事件注册了一个侦听器,并高亮显示文档开头的标记。

建设并注册 HighlightsLayerFactory

此刻我们建设 HighlightsLayerFactory ,来让 NetBeans 知道我们的高亮显示提供者。

向项目源文件添加一个新的 Java 类,并将其定名为 MarkOccurrencesHighlightsLayerFactory。

#p#分页标题#e#

用下面的代码替 换新类中的代码:package org.netbeans.modules.markoccurrences;
import javax.swing.text.Document;
import org.netbeans.spi.editor.highlighting.HighlightsLayer;
import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory;
import org.netbeans.spi.editor.highlighting.ZOrder;
public class MarkOccurrencesHighlightsLayerFactory implements HighlightsLayerFactory {

  public static MarkOccurrencesHighlighter getMarkOccurrencesHighlighter(Document doc) {
     MarkOccurrencesHighlighter highlighter = (MarkOccurrencesHighlighter) doc.getProperty(MarkOccurrencesHighlighter.class);
    if (highlighter == null) {
      doc.putProperty (MarkOccurrencesHighlighter.class, highlighter = new MarkOccurrencesHighlighter(doc));
    }
    return highlighter;
  }
  public HighlightsLayer[] createLayers(Context context) {
    return new HighlightsLayer[] {
       HighlightsLayer.create(
           MarkOccurrencesHighlighter.class.getName(),
           ZOrder.CARET_RACK.forPosition(2000),
          true,
           getMarkOccurrencesHighlighter(context.getDocument ()).getHighlightsBag())
    };
  }
}

#p#副标题#e#

我们已 经提供了一个 HighlightsLayerFactory 的实现,它用 MarkOccurrencesHighlighte类提 供的数据建设了一个高亮显示层。此刻我们需要在 layer.xml 中注册这个类。打开 org.netbeans.modules.markoccurrences 包中的 layer.xml,并将其内容变动为以下内 容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem- 1_1.dtd">
<filesystem>
  <folder name="Editors">
    <folder name="text">
      <folder name="x- c++">
        <file name="org-netbeans-modules- markoccurrences-MarkOccurrencesHighlightsLayerFactory.instance" />
      </folder>
      <folder name="x- c">
        <file name="org-netbeans-modules- markoccurrences-MarkOccurrencesHighlightsLayerFactory.instance" />
      </folder>
    </folder>
   </folder>
</filesystem>

此刻我们已经筹备好第一次 运行我们的高亮显示器了。

生成项目。

项目乐成生成后,运行它。

打开我们在前一节中建设的 Args 项目。

在编辑器中打开 args.c 文件, 并单击文件中的任一位置。高亮显示看起来就会像下面的例子一样:

扩展NetBeans IDE 6.0中的C/C++编辑器以提供符号实例的高亮

太棒 了。我们的高亮显示事情了。此刻我们来教它变得更有用。

从 C/C++ 语言模子收 集信息

在 MarkOccurrencesHighlighter.java 类中,删除我们大致实现的 caretUpdate() ,并添加以下代码:private WeakReference<CsmFile> weakFile;
public void caretUpdate(CaretEvent e) {
  bag.clear ();
  CsmFile file = getCsmFile();
  if (file != null) {
     CsmReference ref = CsmReferenceResolver.getDefault().findReference(file, e.getDot());
    if (ref != null && ref.getReferencedObject() != null) {
      Collection<CsmReference> out = CsmReferenceRepository.getDefault().getReferences(ref.getReferencedObject(), file, true);
      for (CsmReference csmReference : out) {
         bag.addHighlight(csmReference.getStartOffset(), csmReference.getEndOffset(), defaultColors);
      }
     }
  }
}
private CsmFile getCsmFile() {
  if (weakFile == null || weakFile.get() == null) {
    if (weakDoc == null || weakDoc.get() == null) {
      return null;
    }
    DataObject dobj = NbEditorUtilities.getDataObject(weakDoc.get ());
    CsmFile file = CsmUtilities.getCsmFile(dobj, false);
     if (file != null) {
      weakFile = new WeakReference<CsmFile>(file);
    } else {
       return null;
    }
  }
  return weakFile.get();
}

#p#副标题#e#

#p#分页标题#e#

在 caretUpdate() 要领中,我们利用 CsmReferenceResolver 来查找光标下对语 言实体的引用。假如存在有效的实体,我们就向 CsmReferenceRepository 询问文件中所 有沟通实体的呈现位置并存储它们的偏移量。getCsmFile() 要领是一段跟尾代码,用来 确保我们不保存任何语言模子数据。

按下 Ctrl-Shift-I 以修复导入(可能右键 单击,然后选择“修复导入”)。

生成并运行项目。

假如把鼠 标放到 main() 的 argc 参数上,您就将看到如下的高亮显示:

扩展NetBeans IDE 6.0中的C/C++编辑器以提供符号实例的高亮

单击 文件的差异位置以查察标志实例是奈何事情的。您也许想实验更巨大的项目中以查察它怎 样与类、宏等等协同事情。

提高机能

对静态文原来说,我们当前的代码足够好 了,但将在编辑文件的进程中发生严重的延迟。呈现延迟的原因是我们每按下一个键,就 当即开始搜索。要办理这个问题,我们将推迟任务以阐明代码,假如鼠标位置在任务开始 前改变了,我们就打消并从头打算任务。

在 MarkOccurrencesHighlighter.java 类中,把先前的 caretUpdate() 实现变动为以下代码:

public void caretUpdate(CaretEvent e) {
  bag.clear();
  lastCaret = e.getDot();
  scheduleUpdate();
}
private int lastCaret;
private RequestProcessor.Task task = null;
private final static int DELAY = 1000;

public void scheduleUpdate() {
  if (task==null) {
    task = RequestProcessor.getDefault().create(new Runnable() {
      public void run() {
        CsmFile file = getCsmFile();
        if (file != null) {
           CsmReference ref = CsmReferenceResolver.getDefault().findReference (file, lastCaret);
          if (ref!=null && ref.getReferencedObject()!=null) {
             Collection<CsmReference> out = CsmReferenceRepository.getDefault ().getReferences(ref.getReferencedObject(), file, true);
             for (CsmReference csmReference : out) {
               bag.addHighlight(csmReference.getStartOffset(), csmReference.getEndOffset (), defaultColors);
            }
          }
        }
      }
    }, true);
     task.setPriority(Thread.MIN_PRIORITY);
  }
  task.cancel();
  task.schedule(DELAY);
}

在这个代码块中,我们利用 org.openide.util.RequestProcessor 来处理惩罚代码阐明任务。假如获得几个光标更新,我 们就打消先前的任务,记着鼠标位置,然后在稍后的时间从头打算任务。

修复导 入,然后生成并运行项目。

此刻您将留意到,在键入大块代码时没有延迟了。

    关键字:

在线提交作业