瀏覽代碼

- add first version of font creator (use via New File..)

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7109 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
nor..67 14 年之前
父節點
當前提交
9749fd9f3d

+ 8 - 0
jme3-angelfont/build.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.jme3.gde.angelfont" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.jme3.gde.angelfont.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>

+ 6 - 0
jme3-angelfont/manifest.mf

@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.jme3.gde.angelfont
+OpenIDE-Module-Layer: com/jme3/gde/angelfont/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/jme3/gde/angelfont/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+

+ 45 - 0
jme3-angelfont/nbproject/build-impl.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.jme3.gde.angelfont-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>

+ 8 - 0
jme3-angelfont/nbproject/genfiles.properties

@@ -0,0 +1,8 @@
+build.xml.data.CRC32=3d57892f
+build.xml.script.CRC32=03444ead
[email protected]
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=3d57892f
+nbproject/build-impl.xml.script.CRC32=8812c775
+nbproject/[email protected]

+ 2 - 0
jme3-angelfont/nbproject/project.properties

@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial

+ 80 - 0
jme3-angelfont/nbproject/project.xml

@@ -0,0 +1,80 @@
+<?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/3">
+            <code-name-base>com.jme3.gde.angelfont</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.jme3.gde.core</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>0.12</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.jme3.gde.core.baselibs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>0.8.1</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>
+                        <specification-version>1.35</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>

+ 1 - 0
jme3-angelfont/nbproject/suite.properties

@@ -0,0 +1 @@
+suite.dir=${basedir}/..

+ 67 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel1.form

@@ -0,0 +1,67 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="jScrollPane1" min="-2" pref="154" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jLabel1" pref="236" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jScrollPane1" alignment="0" pref="300" max="32767" attributes="0"/>
+          <Component id="jLabel1" alignment="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JList" name="jList1">
+          <Properties>
+            <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
+              <StringArray count="5">
+                <StringItem index="0" value="Item 1"/>
+                <StringItem index="1" value="Item 2"/>
+                <StringItem index="2" value="Item 3"/>
+                <StringItem index="3" value="Item 4"/>
+                <StringItem index="4" value="Item 5"/>
+              </StringArray>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="updateFont"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/angelfont/Bundle.properties" key="AngelFontVisualPanel1.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>

+ 80 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel1.java

@@ -0,0 +1,80 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import java.awt.GraphicsEnvironment;
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+
+public final class AngelFontVisualPanel1 extends JPanel {
+
+    /** Creates new form AngelFontVisualPanel1 */
+    public AngelFontVisualPanel1() {
+        initComponents();
+        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        String[] fontNames = ge.getAvailableFontFamilyNames();
+        jList1.setListData(fontNames);
+    }
+
+    @Override
+    public String getName() {
+        return "Select Font";
+    }
+
+    public String getSelectedFont(){
+        return (String)jList1.getSelectedValue();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jList1 = new javax.swing.JList();
+        jLabel1 = new javax.swing.JLabel();
+
+        jList1.setModel(new javax.swing.AbstractListModel() {
+            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
+            public int getSize() { return strings.length; }
+            public Object getElementAt(int i) { return strings[i]; }
+        });
+        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
+            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
+                updateFont(evt);
+            }
+        });
+        jScrollPane1.setViewportView(jList1);
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AngelFontVisualPanel1.class, "AngelFontVisualPanel1.jLabel1.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 236, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
+            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void updateFont(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_updateFont
+        jLabel1.setIcon(new ImageIcon(FontCreator.buildFont((String)jList1.getSelectedValue())));
+    }//GEN-LAST:event_updateFont
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JList jList1;
+    private javax.swing.JScrollPane jScrollPane1;
+    // End of variables declaration//GEN-END:variables
+}

+ 28 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.form

@@ -0,0 +1,28 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="360" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="256" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>

+ 42 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.java

@@ -0,0 +1,42 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import javax.swing.JPanel;
+
+public final class AngelFontVisualPanel2 extends JPanel {
+
+    /** Creates new form AngelFontVisualPanel2 */
+    public AngelFontVisualPanel2() {
+        initComponents();
+    }
+
+    @Override
+    public String getName() {
+        return "Step #2";
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 360, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 256, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+}

+ 210 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontWizardIterator.java

@@ -0,0 +1,210 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import java.awt.Component;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.imageio.ImageIO;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeListener;
+import org.netbeans.api.project.Project;
+import org.openide.WizardDescriptor;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Exceptions;
+
+public final class AngelFontWizardIterator implements WizardDescriptor.InstantiatingIterator {
+
+    private int index;
+    private WizardDescriptor wizard;
+    private WizardDescriptor.Panel[] panels;
+
+    /**
+     * Initialize panels representing individual wizard's steps and sets
+     * various properties for them influencing wizard appearance.
+     */
+    private WizardDescriptor.Panel[] getPanels() {
+        if (panels == null) {
+            panels = new WizardDescriptor.Panel[]{
+                        new AngelFontWizardPanel1(),
+                        new AngelFontWizardPanel2()
+                    };
+            String[] steps = createSteps();
+            for (int i = 0; i < panels.length; i++) {
+                Component c = panels[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;
+                    // Sets step number of a component
+                    // TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
+                    jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
+                    // Sets steps names for a panel
+                    jc.putClientProperty("WizardPanel_contentData", steps);
+                    // Turn on subtitle creation on each step
+                    jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
+                    // Show steps on the left side with the image on the background
+                    jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
+                    // Turn on numbering of all steps
+                    jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
+                }
+            }
+        }
+        return panels;
+    }
+
+    public Set<FileObject> instantiate() throws IOException {
+        String name = (String) wizard.getProperty("font_name");
+        Project project = (Project) wizard.getProperty("project");
+        ProjectAssetManager pm = project.getLookup().lookup(ProjectAssetManager.class);
+        if (pm == null) {
+            Logger.getLogger(AngelFontWizardIterator.class.getName()).log(Level.WARNING, "No ProjectAssetManager found!");
+            return Collections.EMPTY_SET;
+        }
+        BufferedImage fontImage = FontCreator.buildFont(name);
+        ByteBuffer scratch = ByteBuffer.allocateDirect(4 * fontImage.getWidth() * fontImage.getHeight());
+        byte[] data = (byte[]) fontImage.getRaster().getDataElements(0, 0,
+                fontImage.getWidth(), fontImage.getHeight(), null);
+        scratch.clear();
+        scratch.put(data);
+        scratch.rewind();
+        File outputFile;
+        try {
+            if (pm.getAssetFolder().getFileObject("Interface") == null) {
+                pm.getAssetFolder().createFolder("Interface");
+            }
+            if (pm.getAssetFolder().getFileObject("Interface/Fonts") == null) {
+                pm.getAssetFolder().getFileObject("Interface").createFolder("Fonts");
+            }
+            outputFile = FileUtil.toFile(pm.getAssetFolder().getFileObject("Interface/Fonts"));
+            if (!outputFile.getName().endsWith(".png")) {
+                outputFile = new File(outputFile.getAbsoluteFile() + File.separator + name + ".png");
+            }
+            // write png file
+            ImageIO.write(fontImage, "PNG", outputFile);
+        } catch (Exception e) {
+            Exceptions.printStackTrace(e);
+            return Collections.EMPTY_SET;
+        }
+        return Collections.singleton(FileUtil.toFileObject(outputFile));
+    }
+
+    public void initialize(WizardDescriptor wizard) {
+        this.wizard = wizard;
+        System.out.println("FOLDERRRR:" + wizard.getProperty("folder"));
+        for (Iterator<Entry<String, Object>> it = wizard.getProperties().entrySet().iterator(); it.hasNext();) {
+            Entry<String, Object> entry = it.next();
+            System.out.println(entry.getKey() + ": " + wizard.getProperty(entry.getKey()));
+        }
+    }
+
+    public void uninitialize(WizardDescriptor wizard) {
+        panels = null;
+    }
+
+    public WizardDescriptor.Panel current() {
+        return getPanels()[index];
+    }
+
+    public String name() {
+        return index + 1 + ". from " + getPanels().length;
+    }
+
+    public boolean hasNext() {
+        return index < getPanels().length - 1;
+    }
+
+    public boolean hasPrevious() {
+        return index > 0;
+    }
+
+    public void nextPanel() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+        index++;
+    }
+
+    public void previousPanel() {
+        if (!hasPrevious()) {
+            throw new NoSuchElementException();
+        }
+        index--;
+    }
+
+    // If nothing unusual changes in the middle of the wizard, simply:
+    public void addChangeListener(ChangeListener l) {
+    }
+
+    public void removeChangeListener(ChangeListener l) {
+    }
+
+    // If something changes dynamically (besides moving between panels), e.g.
+    // the number of panels changes in response to user input, then uncomment
+    // the following and call when needed: fireChangeEvent();
+    /*
+    private Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+    public final void addChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.add(l);
+    }
+    }
+    public final void removeChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.remove(l);
+    }
+    }
+    protected final void fireChangeEvent() {
+    Iterator<ChangeListener> it;
+    synchronized (listeners) {
+    it = new HashSet<ChangeListener>(listeners).iterator();
+    }
+    ChangeEvent ev = new ChangeEvent(this);
+    while (it.hasNext()) {
+    it.next().stateChanged(ev);
+    }
+    }
+     */
+    // You could safely ignore this method. Is is here to keep steps which were
+    // there before this wizard was instantiated. It should be better handled
+    // by NetBeans Wizard API itself rather than needed to be implemented by a
+    // client code.
+    private String[] createSteps() {
+        String[] beforeSteps = null;
+        Object prop = wizard.getProperty("WizardPanel_contentData");
+        if (prop != null && prop instanceof String[]) {
+            beforeSteps = (String[]) prop;
+        }
+
+        if (beforeSteps == null) {
+            beforeSteps = new String[0];
+        }
+
+        String[] res = new String[(beforeSteps.length - 1) + panels.length];
+        for (int i = 0; i < res.length; i++) {
+            if (i < (beforeSteps.length - 1)) {
+                res[i] = beforeSteps[i];
+            } else {
+                res[i] = panels[i - beforeSteps.length + 1].getComponent().getName();
+            }
+        }
+        return res;
+    }
+}

+ 87 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontWizardPanel1.java

@@ -0,0 +1,87 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import java.awt.Component;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+public class AngelFontWizardPanel1 implements WizardDescriptor.Panel {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private AngelFontVisualPanel1 component;
+
+    // Get the visual component for the panel. In this template, the component
+    // is kept separate. This can be more efficient: if the wizard is created
+    // but never displayed, or not all panels are displayed, it is better to
+    // create only those which really need to be visible.
+    public Component getComponent() {
+        if (component == null) {
+            component = new AngelFontVisualPanel1();
+        }
+        return component;
+    }
+
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx(SampleWizardPanel1.class);
+    }
+
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return true;
+        // If it depends on some condition (form filled out...), then:
+        // return someCondition();
+        // and when this condition changes (last form field filled in...) then:
+        // fireChangeEvent();
+        // and uncomment the complicated stuff below.
+    }
+
+    public final void addChangeListener(ChangeListener l) {
+    }
+
+    public final void removeChangeListener(ChangeListener l) {
+    }
+    /*
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+    public final void addChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.add(l);
+    }
+    }
+    public final void removeChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.remove(l);
+    }
+    }
+    protected final void fireChangeEvent() {
+    Iterator<ChangeListener> it;
+    synchronized (listeners) {
+    it = new HashSet<ChangeListener>(listeners).iterator();
+    }
+    ChangeEvent ev = new ChangeEvent(this);
+    while (it.hasNext()) {
+    it.next().stateChanged(ev);
+    }
+    }
+     */
+
+    // You can use a settings object to keep track of state. Normally the
+    // settings object will be the WizardDescriptor, so you can use
+    // WizardDescriptor.getProperty & putProperty to store information entered
+    // by the user.
+    public void readSettings(Object settings) {
+        ((WizardDescriptor)settings).putProperty("font_name", component.getSelectedFont());
+    }
+
+    public void storeSettings(Object settings) {
+    }
+}

+ 86 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontWizardPanel2.java

@@ -0,0 +1,86 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import java.awt.Component;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+public class AngelFontWizardPanel2 implements WizardDescriptor.Panel {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private Component component;
+
+    // Get the visual component for the panel. In this template, the component
+    // is kept separate. This can be more efficient: if the wizard is created
+    // but never displayed, or not all panels are displayed, it is better to
+    // create only those which really need to be visible.
+    public Component getComponent() {
+        if (component == null) {
+            component = new AngelFontVisualPanel2();
+        }
+        return component;
+    }
+
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx(SampleWizardPanel1.class);
+    }
+
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return true;
+        // If it depends on some condition (form filled out...), then:
+        // return someCondition();
+        // and when this condition changes (last form field filled in...) then:
+        // fireChangeEvent();
+        // and uncomment the complicated stuff below.
+    }
+
+    public final void addChangeListener(ChangeListener l) {
+    }
+
+    public final void removeChangeListener(ChangeListener l) {
+    }
+    /*
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+    public final void addChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.add(l);
+    }
+    }
+    public final void removeChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.remove(l);
+    }
+    }
+    protected final void fireChangeEvent() {
+    Iterator<ChangeListener> it;
+    synchronized (listeners) {
+    it = new HashSet<ChangeListener>(listeners).iterator();
+    }
+    ChangeEvent ev = new ChangeEvent(this);
+    while (it.hasNext()) {
+    it.next().stateChanged(ev);
+    }
+    }
+     */
+
+    // You can use a settings object to keep track of state. Normally the
+    // settings object will be the WizardDescriptor, so you can use
+    // WizardDescriptor.getProperty & putProperty to store information entered
+    // by the user.
+    public void readSettings(Object settings) {
+    }
+
+    public void storeSettings(Object settings) {
+    }
+}

+ 7 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/Bundle.properties

@@ -0,0 +1,7 @@
+OpenIDE-Module-Display-Category=jMonkeyPlatform
+OpenIDE-Module-Long-Description=\
+    Font Support for jMonkeyPlatform, create AngelFont files from system fonts
+OpenIDE-Module-Name=jME3 Font Creator
+OpenIDE-Module-Short-Description=Create AngelFont files from system fonts
+Templates/GUI/angelFont=Font
+AngelFontVisualPanel1.jLabel1.text=

+ 138 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/FontCreator.java

@@ -0,0 +1,138 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.angelfont;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+
+/**
+ *
+ * @author normenhansen
+ */
+public abstract class FontCreator {
+
+    private static final Color OPAQUE_WHITE = new Color(0xFFFFFFFF, true);
+    private static final Color TRANSPARENT_BLACK = new Color(0x00000000, true);
+
+    public FontCreator() {
+    }
+
+    public static BufferedImage buildFont(String fontName) {
+        return buildFont(fontName, 63);
+    }
+
+    public static BufferedImage buildFont(String fontName, int offset) {
+        BufferedImage fontImage;
+        Font font;
+
+        int bitmapSize = 512; // set the size for the bitmap texture
+        boolean sizeFound = false;
+        boolean directionSet = false;
+        int delta = 0;
+        int fontSize = 24;
+
+        String charLocs = "";
+
+        /*
+         * To find out how much space a Font takes, you need to use a the
+         * FontMetrics class. To get the FontMetrics, you need to get it from a
+         * Graphics context. A Graphics context is only available from a
+         * displayable surface, ie any class that subclasses Component or any
+         * Image. First the font is set on a Graphics object. Then get the
+         * FontMetrics and find out the width and height of the widest character
+         * (W). Then take the largest of the 2 values and find the maximum size
+         * font that will fit in the size allocated.
+         */
+        while (!sizeFound) {
+            font = new Font(fontName, Font.PLAIN, fontSize); // Font Name
+            // use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
+            fontImage = new BufferedImage(bitmapSize, bitmapSize,
+                    BufferedImage.TYPE_4BYTE_ABGR);
+            Graphics2D g = (Graphics2D) fontImage.getGraphics();
+            g.setFont(font);
+            FontMetrics fm = g.getFontMetrics();
+            int width = fm.stringWidth("W");
+            int height = fm.getHeight();
+            int lineWidth = (width > height) ? width * 16 : height * 16;
+            if (!directionSet) {
+                if (lineWidth > bitmapSize) {
+                    delta = -2;
+                } else {
+                    delta = 2;
+                }
+                directionSet = true;
+            }
+            if (delta > 0) {
+                if (lineWidth < bitmapSize) {
+                    fontSize += delta;
+                } else {
+                    sizeFound = true;
+                    fontSize -= delta;
+                }
+            } else if (delta < 0) {
+                if (lineWidth > bitmapSize) {
+                    fontSize += delta;
+                } else {
+                    sizeFound = true;
+                    fontSize -= delta;
+                }
+            }
+        }
+
+        /*
+         * Now that a font size has been determined, create the final image, set
+         * the font and draw the standard/extended ASCII character set for that
+         * font.
+         */
+        font = new Font(fontName, Font.BOLD, fontSize); // Font Name
+        // use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
+        fontImage = new BufferedImage(bitmapSize, bitmapSize,
+                BufferedImage.TYPE_4BYTE_ABGR);
+        Graphics2D g = (Graphics2D) fontImage.getGraphics();
+        g.setFont(font);
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setColor(OPAQUE_WHITE);
+        g.setBackground(TRANSPARENT_BLACK);
+
+        FontMetrics fm = g.getFontMetrics();
+
+        for (int i = 0; i < 256; i++) {
+            int x = i % 16;
+            int y = i / 16;
+            char ch[] = {(char) i};
+            String temp = new String(ch);
+            Rectangle2D bounds = fm.getStringBounds(temp, g);
+
+            int xPos = (int) ((x * 32) + (16 - (bounds.getWidth() / 2)));
+            int yPos = (y * 32) + fm.getAscent() - offset;
+            g.drawString(temp, xPos, yPos);
+            //TODO: AngelFont support!
+//            g.setColor(Color.BLUE);
+//            g.drawRect(xPos, yPos-(int)bounds.getHeight(), (int)bounds.getWidth(), (int)bounds.getHeight()+fm.getDescent());
+//            g.setColor(Color.WHITE);
+//
+//            charLocs=charLocs+
+//                    "char id="+i+
+//                    "    x="+xPos +
+//                    "    y="+(yPos-(int)bounds.getHeight()-fm.getAscent())+
+//                    "    width="+(int)bounds.getWidth()+
+//                    "    height="+(int)bounds.getHeight()+
+//                    "    xoffset=0" +
+//                    "    yoffset=0" +
+//                    "    xadvance=0" +
+//                    "    page=0" +
+//                    "    chnl=15\n";
+        }
+//        System.out.println(charLocs);
+        return fontImage;
+    }
+
+}

+ 13 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/angelFont.html

@@ -0,0 +1,13 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        Lets you select a font from your computer and convert it to a jME3 compatible
+        font file.
+    </body>
+</html>

二進制
jme3-angelfont/src/com/jme3/gde/angelfont/font.gif


+ 15 - 0
jme3-angelfont/src/com/jme3/gde/angelfont/layer.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Templates">
+        <folder name="GUI">
+            <file name="angelFont">
+                <attr name="SystemFileSystem.icon" urlvalue="nbresloc:/com/jme3/gde/angelfont/font.gif"/>
+                <attr name="displayName" bundlevalue="com.jme3.gde.angelfont.Bundle#Templates/GUI/angelFont"/>
+                <attr name="instantiatingIterator" newvalue="com.jme3.gde.angelfont.AngelFontWizardIterator"/>
+                <attr name="template" boolvalue="true"/>
+                <attr name="templateWizardURL" urlvalue="nbresloc:/com/jme3/gde/angelfont/angelFont.html"/>
+            </file>
+        </folder>
+    </folder>
+</filesystem>