2014-02-06 146 views
1

一般來說,我想創建一個創建多個文件的Netbeans(7.4)文件嚮導。創建多個文件的Netbeans模板

在我的情況下,我希望它在加載fxml文件時創建JavaFX相關文件以使用約定而不是配置方法。 (我從亞當邊這個想​​法:http://www.youtube.com/watch?v=mawFd4h1Or4

更具體:我要進入一個String定義了Basename,並希望向導創建3個不同的文件,位於包在點擊右鍵 - >「新建「嚮導被用戶調用。

  1. Basename.fxml
  2. BasenameController.java
  3. BasenameView.java

我試着寫我自己的嚮導快3天了,這是行不通的。我研究(薄)的NetBeans API,並仔細閱讀所有這些教程(及以上):

我嘗試更多的東西,然後我可以在這裏列舉,但這些都是一些令人高興的事情:

  • 我從來沒有得到它與一個單一的@TemplateRegistration和多個content條目。
  • 所以我註冊了多個模板@TemplateRegistrations,每個文件我想創建一個模板。
  • 這會創建多個文件,但只有第一個文件具有正確的屬性,例如$ {package}爲freemarker腳本設置。 (另外這種方式我結束了多個模板...但我可以忍受這一點)
  • 然後我試着用其他屬性名稱並手動設置這些,但我無法弄清楚如何找到包嚮導被調用。

相關問題,它並沒有真正幫助我:

任何建議是非常值得歡迎的。提前致謝!

UPDATE:

我設法創建所需的文件。問題是你使用稀疏記錄的命名約定。如果要正確創建Basename.java文件,則必須命名模板文件:Basename.java(這會使編譯器不高興,因爲模板文件不是有效的java類)或Basename.java.template。如果您將其命名爲:Basename.java.templ(並自行管理文件的正確命名),它將不會爲您設置${package}變量。

所以現在我非常接近我想要的東西,但仍然存在正確註冊嚮導的問題。

目前我使用@TemplateRegistrations來註冊3個模板(每個文件一個)。但由於「文件夾」屬性是強制性的,我現在在Netbeans的「新建」嚮導中有3個條目。當我調用其中一個時,它會根據需要創建所有3個文件,但我想在「新建」嚮導中只有1個條目。

@TemplateRegistrations({ 
    @TemplateRegistration(content = "FXML.fxml.template", scriptEngine = "freemarker", folder = "ASpecial", displayName = "#TemplateName", iconBase = "de/ekrnrw/fxmlview/view.png", description = "newFXMLView.html"), 
    @TemplateRegistration(content = "View.java.template", scriptEngine = "freemarker", folder = "ASpecial"), 
    @TemplateRegistration(content = "Controller.java.template", scriptEngine = "freemarker", folder = "ASpecial") 
}) 

我試圖用一個單一的@TemplateRegistration與多個內容項目,但這並不與本教程的代碼工作。似乎只有fxml文件被處理爲freemarker,並且這兩個java文件只是模板文件的普通副本。

@TemplateRegistration(content = {"FXML.fxml.template","View.java.template","Controller.java.template"}, scriptEngine = "freemarker", folder = "ASpecial", displayName = "#TemplateName", iconBase = "de/ekrnrw/fxmlview/view.png", description = "newFXMLView.html") 

我將此問題發佈到NetBeans郵件列表here。這裏是相關的代碼片段:

package de.ekrnrw.fxmlview; 

import java.awt.Component; 
... 
import org.openide.util.NbBundle.Messages; 

@TemplateRegistrations({ 
    @TemplateRegistration(content = "FXML.fxml.template", scriptEngine = "freemarker", folder = "ASpecial", displayName = "#TemplateName", iconBase = "de/ekrnrw/fxmlview/view.png", description = "newFXMLView.html"), 
    @TemplateRegistration(content = "View.java.template", scriptEngine = "freemarker", folder = "ASpecial"), 
    @TemplateRegistration(content = "Controller.java.template", scriptEngine = "freemarker", folder = "ASpecial") 
}) 

// Would like to use this, but i can't make it work. 
//@TemplateRegistration(content = {"FXML.fxml.template","View.java.template","Controller.java.template"}, scriptEngine = "freemarker", folder = "ASpecial", displayName = "#TemplateName", iconBase = "de/ekrnrw/fxmlview/view.png", description = "newFXMLView.html") 

@Messages("TemplateName=FXMLView4") 

public final class NewFXMLViewWizardIterator implements WizardDescriptor.InstantiatingIterator<WizardDescriptor> { 

    private int index; 

    private WizardDescriptor wizard; 
    private List<WizardDescriptor.Panel<WizardDescriptor>> panels; 

    private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() { 
     if (panels == null) { 
      panels = new ArrayList<>(); 

      // Change to default new file panel and add our panel at bottom 
      Project p = Templates.getProject(wizard); 
      SourceGroup[] groups = ProjectUtils.getSources(p).getSourceGroups(Sources.TYPE_GENERIC); 

      // SimpleTargetChooser is the default new file panel 
      WizardDescriptor.Panel<WizardDescriptor> advNewFilePanel = Templates.buildSimpleTargetChooser(p, groups).create(); 
      panels.add(advNewFilePanel); 

      String[] steps = createSteps(); 
      for (int i = 0; i < panels.size(); i++) { 
       Component c = panels.get(i).getComponent(); 
       if (steps[i] == null) { 
        // Default step name to component name of panel. Mainly 
        // useful for getting the name of the target chooser to 
        // appear in the list of steps. 
        steps[i] = c.getName(); 
       } 
       if (c instanceof JComponent) { // assume Swing components 
        JComponent jc = (JComponent) c; 
        jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i); 
        jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps); 
        jc.putClientProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, true); 
        jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, true); 
        jc.putClientProperty(WizardDescriptor.PROP_CONTENT_NUMBERED, true); 
       } 
      } 
     } 
     return panels; 
    } 

    @Override 
    public Set<?> instantiate() throws IOException { 

     //Get the folder: 
     FileObject dir = Templates.getTargetFolder(wizard); 
     DataFolder df = DataFolder.findFolder(dir); 

     //Get TargetName from File Wizard 
     String targetName = Templates.getTargetName(wizard); 

     // Read Title from wizard 
     String viewName = targetName + "View"; 
     String controllerName = targetName + "Controller"; 

     // FreeMarker Template will get its variables from HashMap. 
     // HashMap key is the variable name. 
     Map args = new HashMap(); 
     args.put("controllerName", controllerName); 
     args.put("viewName", viewName); 

     //Get Templates 
     FileObject[] templates = Templates.getTemplate(wizard).getParent().getChildren(); 

     // Create all Files 
     Set<DataObject> createdObjects = new HashSet<>(); 

     for (FileObject fileObject : templates) { 

      DataObject dTemplate = DataObject.find(fileObject); 
      String templateName = dTemplate.getName(); 

      // Sepcial treatment for the .fxml file. 
      if (templateName.equals("FXML")) { 
       templateName = ""; 
      } 

      // Create file 
      createdObjects.add(dTemplate.createFromTemplate(df, targetName + templateName , args)); 
     } 
     return createdObjects; 
    }  
    ... 
} 
+0

您是否設法爲每個模板只顯示一個條目? – Groben

回答

1

請向郵件列表[email protected]並提供非工作的樣品,所以這個問題可以重現。

+0

謝謝你指點我。我更新了我的問題,因爲我設法解決了我的問題的一部分。這次用代碼;)。 – Sheba

1

我試過你的樣品,我查了一下。您不需要使用@TemplateRegistration註釋使用的FreeMarker也不使用Templates.getTemplate(wizard).getParent().getChildren()

  1. 通過 FileObject template1 = FileUtil.getConfigFile("CustomerSalesTemplates/project1.txt"); DataObject dTemplate1 = DataObject.find(template1);
  2. ,然後讓你的每一個模板使用 dTemplate1.createFromTemplate調用freemarker的

見文章 * https://blogs.oracle.com/geertjan/entry/how_to_visually_diff_multiple * https://blogs.oracle.com/geertjan/entry/freemarker_baked_into_netbeans_ide1

+0

嗯,但我仍然需要以某種方式註冊WizardIterator,否則它不會顯示在Netbeans的「新建文件」嚮導中,或者我錯過了什麼? – Sheba

+0

您可以嘗試通過註釋僅註冊模板,以便您仍然可以進行嚮導集成。但是通過上面的代碼創建的其他instanciated模板 – Ben

0

所有@TemplateRegistration註釋將在構建時轉換爲名爲layer.xml的文件中的文件條目。在layer.xml,文件模板如下表示:

<filesystem> 
    <folder name="Templates"> 
     <folder name="javafx"> 
      <file name="FxmlNode.java" url="nbresloc:/tuupertunut/fxmltemplates/FxmlNode.java.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="displayName" bundlevalue="tuupertunut.fxmltemplates.Bundle#FxmlNode_displayName"/> 
       <attr name="iconBase" stringvalue="org/netbeans/spi/java/project/support/ui/templates/class.png"/> 
       <attr name="instantiatingWizardURL" urlvalue="nbresloc:/tuupertunut/fxmltemplates/FxmlNodeDescription.html"/> 
       <attr name="instantiatingIterator" newvalue="tuupertunut.fxmltemplates.FxmlNodeIterator"/> 
       <attr name="requireProject" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
      </file> 
     </folder> 
    </folder> 
</filesystem> 

你可以看到,有attr屬性的file條目。有關您的問題的相關屬性是templatejavax.script.ScriptEngine

  • <attr name="template" boolvalue="true"/>file條目將被顯示爲「新 文件」對話框中單獨列項。
  • 每個file<attr name="javax.script.ScriptEngine" stringvalue="freemarker"/>的條目將會在創建文件之前由freemarker處理過 。

案例1:多@TemplateRegistration小號

@TemplateRegistrations({ 
    @TemplateRegistration(content = "FXML.fxml.template", scriptEngine = "freemarker", folder = "ASpecial", ...), 
    @TemplateRegistration(content = "View.java.template", scriptEngine = "freemarker", folder = "ASpecial"), 
    @TemplateRegistration(content = "Controller.java.template", scriptEngine = "freemarker", folder = "ASpecial") 
}) 

將轉換爲

<filesystem> 
    <folder name="Templates"> 
     <folder name="ASpecial"> 
      <file name="FXML.fxml" url="nbresloc:/yourpackage/FXML.fxml.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
      <file name="View.java" url="nbresloc:/yourpackage/View.java.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
      <file name="Controller.java" url="nbresloc:/yourpackage/Controller.java.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
     </folder> 
    </folder> 
</filesystem> 

正如你所看到的,所有三個模板將顯示在 「新建文件」 對話框,所有三個模板都將由freemarker處理。


案例2:在單@TemplateRegistration

@TemplateRegistration(content = {"FXML.fxml.template","View.java.template","Controller.java.template"}, scriptEngine = "freemarker", folder = "ASpecial", ...) 

content將轉換爲

<filesystem> 
    <folder name="Templates"> 
     <folder name="ASpecial"> 
      <file name="FXML.fxml" url="nbresloc:/yourpackage/FXML.fxml.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
      <file name="View.java" url="nbresloc:/yourpackage/View.java.template"> 
       ... 
      </file> 
      <file name="Controller.java" url="nbresloc:/yourpackage/Controller.java.template"> 
       ... 
      </file> 
     </folder> 
    </folder> 
</filesystem> 

這裏只有第一個模板將在 「新建文件」 對話框中顯示,也只有首先將由freemarker處理。


解決方案

由於註釋不會產生預期的layer.xml,你必須自己創建一個。您應該能夠從項目的build/classes/META-INF目錄中找到自動生成的generated-layer.xml。從「新建文件」對話框爲您的項目創建一個新的layer.xml文件,並將所有內容複製粘貼到其中。然後您可以手動編輯這些templatejavax.script.ScriptEngine屬性。

最後,它應該是這個樣子:

<filesystem> 
    <folder name="Templates"> 
     <folder name="ASpecial"> 
      <file name="FXML.fxml" url="nbresloc:/yourpackage/FXML.fxml.template"> 
       <attr name="template" boolvalue="true"/> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
      <file name="View.java" url="nbresloc:/yourpackage/View.java.template"> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
      <file name="Controller.java" url="nbresloc:/yourpackage/Controller.java.template"> 
       <attr name="javax.script.ScriptEngine" stringvalue="freemarker"/> 
       ... 
      </file> 
     </folder> 
    </folder> 
</filesystem> 

其中,第一項是國內唯一一家擁有template但個個都javax.script.ScriptEngine

不要忘記刪除您@TemplateRegistration註釋,因爲模板現在由您的layer.xml管理。