blob: b434660bdc70bbdddee46c139119fbe7a93ab747 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head></head><script charset="utf-8" id="injection_graph_func" src="nbm_interview_toni-1_bestanden/injection_graph_func.js"></script><link href="nbm_interview_toni-1_bestanden/injection_graph.css" type="text/css" rel="stylesheet" charset="utf-8" id="injection_graph_css"><body>
<h1>Meet a NetBeans Module Writer: Tonny Kohar</h1>
<table class="ltblue" align="right" border="1" cellpadding="5" cellspacing="0" width="190">
<tbody>
<tr>
<td align="center"><img src="nbm_interviews/tonny/tonny.png" alt="Tonny's picture" align="middle">
<br><b>Tonny Kohar</b></td>
</tr>
</tbody>
</table>
<p>Some weeks ago, the NetBeans team became aware of a cool new application
called "Sketsa SVG Graphics Editor". It appeared to have been made in Indonesia,
by a team of developers who used the NetBeans Platform as their framework. Here
is an interview with the lead developer, Tonny Kohar.
<h3>Hi Tonny. Please tell us a bit about who you are and where you're from.</h3>
<p>I am Indonesian and currently I live in Surabaya, Indonesia. Before this, I
lived in Perth, West Australia, for 4 years, and before that in Singapore for a year.
<p>Currently I work at <a href="http://www.kiyut.com">Kiyut</a> as the project leader
for Sketsa SVG Graphics Editor.
<h3>What does "Sketsa" mean?</h3>
<p>Sketsa is an Indonesian word for "sketch". Here are a few screenshots
to give you an idea of what we're talking about. This first screenshot,
the largest, shows the Sketsa Main Window. In fact, all the windows, tabs,
panels, and dockings that you see... are provided by the NetBeans Platform:
<p><img src="nbm_interviews/tonny/sketsa.png" alt="Sketsa picture" align="middle">
<p>These are two close-ups, the first is our "toolbox", inherited from the
<tt>TopComponent</tt> class:
<p><img src="nbm_interviews/tonny/toolbox.png" alt="Toolbox picture" align="middle">
<p>Next, you can see the SVG Gradient Dialog Editor:
<p><img src="nbm_interviews/tonny/linear_gradient.png" alt="Linear gradient picture" align="middle">
<h3>Wow cool. So, tell us something about that editor. What's the background here?</h3>
<p>The background is the <a href="http://www.w3.org/Graphics/SVG/About.html">SVG Spec 1.0</a>!
It provides for a lot of XML, because that's what SVG uses, but there is no
application that allows the designer to build SVG content or art work
visually, using a drag-and-drop approach similar to a drawing application.
<h3>Who is the target audience for this application?</h3>
<p>The target audience for Sketsa are designers or web developers
looking for an easy-to-use cross-platform SVG Graphics Editor. We're trying
to provide solutions to graphics designers so they can create SVG content without
requiring any technical SVG or XML knowledge. We also support the advanced user with
an integrated DOM Editor and SVG source editor.
<h3>On which operating systems does the application run?</h3>
<p>Sketsa runs on any platform that support Java 1.5 / 5.0
(<a href="http://www.java.com/getjava">http://www.java.com/getjava</a>) or higher.
For example, Microsoft Windows, Unix/Linux, etc.
"Java" means write once and run anywhere. This technology
developed by Sun includes byte code and a virtual machine that allow truly
cross-platform applications. "Write once, run anywhere" is a genuine reality.
<h3>When was the product officially released?</h3>
<p>Sketsa 4.0 was the first product release that built on top of the NetBeans
Platform. It was released back in 31 January 2007. Now, we are at Sketsa
4.1.0, which was released 7 February 2007.
<h3>It is a commercial product?</h3>
<p>Yes, it is a commercial product. However, you can download a trial version, so people can try
before buying. The trial is full-featured, no function is disabled, and there is no time limit
on the evaluation version. However, it clearly displays the
text "For Evaluation Use Only".
You can download it <a href="http://www.kiyut.com/products/download.html">here</a>.
<h3>Does your editor have any competitors? Are there other SVG editors
out there and how is yours different?</h3>
<p>In the commercial sector, there is <a href="http://www.adobe.com">Adobe Illustrator</a>
and <a href="http://www.corel.com">Corel Draw</a>, which
allow import and export of SVG Content. In the open source area, there is
<a href="http://www.inkscape.org">Inkscape</a>. There are also other XML text editor
applications and other drawing applications that allow export to SVG.
<p>All of the abovementioned products are well known, feature-packed,
powerful, and very respectable products. But we differ with them in the
ways that we handle SVG content. Currently, Sketsa is the only SVG Graphics
Editor out there which produces clean SVG code. In other words, it does not embed
any proprietary SVG XML tags. In addition, our decision to use Java shows
that Sketsa is one of the best cross-platform SVG Graphics Editors.
<p>Besides that, our decision to build on top of the NetBeans Platform provides the
opportunity for third parties, either commercial or open source, to very easily extend the editor
with new functionality and features.
<h3>Tell us about the SVG Editor API that you've created, can we use it and where can we get it?
And where is the Javadoc?</h3>
<p>We created an SVG Editor API. For the SVG API itself, there is
already excellent <a href="http://xmlgraphics.apache.org/batik/">Apache Batik SVG API</a>,
which we used in Sketsa. Our SVG
Editor API mainly contains our canvas, together with various tools to interact with
the canvas.
<p>The SVG Editor API is released with Sketsa, which is available at
<a href="http://kiyut.com/products/sketsa/index.html">http://kiyut.com/products/sketsa/index.html</a>
under the download section.
The downloaded Sketsa application contains the Editor API ready
for use. It contains the following, based on the NetBeans Platform that comes with NetBeans IDE 5.5:
<ul>
<li>Harness
<li>Platform Cluster
<li>IDE Cluster
<br>* Options Dialog and SPI
<br>* Form Layout Integration
<li>Sketsa SVG Graphics Editor Cluster
</ul>
<p>To use it, simply open NetBeans IDE and use the NetBeans Platform Manager
to specify that download as your platform, and then follow the wizard. Then you
can start to utilize the Sketsa SVG Editor API.
<p>The Javadoc is available at
<a href="http://kiyut.com/products/sketsa/developer/index.html">http://kiyut.com/products/sketsa/developer/index.html</a>.
<h3>How long have you been working on this? On your own or in a team?</h3>
<p>We've been working on this for 4 years, in a team of developers.
Our development team consists of 3 people. My task was to make sure
the project runs smoothly and I am also the integrator. I took the SVG
Editor API and integrated that API into Sketsa as an application, using
the NetBeans Platform. The other developers created the SVG Editor API,
which I integrated into Sketsa.
<p>For this reason, NetBeans IDE is our favorite Java editor;
in fact, all our developers use NetBeans IDE, because of the NetBeans IDE
free-form Ant project type. Three different people
with different characteristics... we needed to ensure that the IDE we used
supported us in this kind of heterogeneous environment. That's what the
free-form Ant project does for us.
<h3>And why did you choose to develop this on the NetBeans Platform?</h3>
<p>Initially, Sketsa was developed using an in-house framework and a third party
library for the plugin framework. However, at some point we realized that we were
spending more time on developing the framework than adding features to our
application. We had become distracted from our main focus,
which should have been our SVG Graphics
Editor application. Our other focus should have been
our SVG Editor API, intended for use by other
developers. This in-house framework took a lot of resources to create and
maintain and ultimately it would only be able to benefit us&#8212;it
was unusable outside the project, because it had
far too many hardcoded assumptions specific to our own application.
<p>When the buzzword "RCP" come out one or two years ago, we started evaluating the
available RCPs. At that time, we didn't know that
the NetBeans Platform was available, because to us there was only NetBeans IDE,
so naturally we looked at Eclipse RCP.
During the evaluation period, we found that Eclipse RCP was too tightly
integrated with SWT. In order to fully utilize or
derive benefits from Eclipse RCP, we would have had to use SWT to create
a Workspace manager, with menus and dialogs, preferences, options, etc. Although
we found that we could choose to not use SWT, we found that doing so meant losing
the benefits of RCP. It would only have left us with the OSGi modular framework, since the
rest of the RCP features, such as the integrated Workspace or Window manager, requires
the use of SWT.
<p>What we needed was the whole application framework, including menus,
preferences, workspace system, windows and dialogs system, etc, and it
had to be Swing because our application is Swing-based. Luckily, not long
after that, NetBeans folks started to publicize more heavily the
spinning of NetBeans Platform from the IDE.
<h3>What do you think about the NetBeans Platform?</h3>
<p>The NetBeans Platform is the best general purpose application framework out
there. The Lookup API concept is really amazing and an eye opener for us.
The NetBeans Platform introduces us to a simple, understandable approach
to architecting a module-based application. It allow for service (lookup)
discovery in plain and simple ways and made us rethink what we had been
doing before.
<p>In the sense that we were looking for an application framework that we could build
applications on top of, the Lookup API is the "best of breed". Right up
till today, it has never stopped amazing us what benefits derive from that Lookup API. It
always gives us new ideas on how to write better, even more modular and pluggable,
applications. Honestly, we never thought of the Lookup concept before; just
after beginning to use the NetBeans Platform did we begin realizing how powerful that API
is.
<h3>How long have you used the NetBeans Platform?</h3>
<p>We started using the NetBeans Platform from the second half of 2006. It has been a very
nice and pleasing experience to learn how to use the NetBeans Platform. We had
some difficulties, but the community at <a href="https://netbeans.org/projects/openide/lists/dev/archive">dev@openide.netbeans.org</a> and the
<a href="http://wiki.netbeans.org/wiki/view/NetBeansDeveloperFAQ">NetBeans Developer FAQ</a>
easily helped us overcome our problems.
<h3>Do you have any code snippets or tips and tricks to share with people who develop on the NetBeans Platform?</h3>
<p>For new developers or existing developers that utilize the NetBeans Platform,
I encourage you to learn the Lookup API/SPI. It will save a lot during
development and as an added bonus it will change the ways you develop
modular, service-oriented applications using provider discovery and consumption in a
nice, clean, and simple way.
<p>There is already an excellent set of information available regarding
Lookup API/SPI:
<ul>
<li><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">Lookup Library</a>: The solution to comunication between components.
<li><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/lookup-api.html">Lookup Library API</a>: For those interested in using Lookup.
<li><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/lookup-spi.html">Lookup Library SPI</a>: For those interested in providing Lookup.
<li>Lookup section in <a href="http://wiki.netbeans.org/wiki/view/NetBeansDeveloperFAQ">NetBeans Developer FAQ</a>.
</ul>
<p>Recently we discovered how to provide a dynamically created and
extensible <tt>JPopupMenu</tt> for a non-text editor or custom <tt>TopComponent</tt>, using
the Lookup API. It will be included in Sketsa, in the next release! :)
<p>To create it, in the <tt>layer.xml</tt> file, declare a menu structure
as folders, such as the following:
<pre class="examplecode">&lt;folder name="Sketsa"&gt;
&lt;folder name="Canvas"&gt;
&lt;folder name="Popup"&gt;
&lt;attr name="SystemFileSystem.localizingBundle" stringvalue="kiyut.sketsa.Bundle"/&gt;
&lt;file name="org-openide-actions-UndoAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-UndoAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="org-openide-actions-RedoAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-RedoAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="Separator1.instance"&gt;
&lt;attr name="instanceClass" stringvalue="javax.swing.JSeparator"/&gt;
&lt;/file&gt;
&lt;file name="org-openide-actions-CutAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-CutAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="org-openide-actions-CopyAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-CopyAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="org-openide-actions-PasteAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-PasteAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="org-openide-actions-DeleteAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-openide-actions-DeleteAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="Separator2.instance"&gt;
&lt;attr name="instanceClass" stringvalue="javax.swing.JSeparator"/&gt;
&lt;/file&gt;
&lt;file name="kiyut-sketsa-actions-CAGUnionAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Modify/kiyut-sketsa-actions-CAGUnionAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="kiyut-sketsa-actions-CAGSubtractAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Modify/kiyut-sketsa-actions-CAGSubtractAction.instance"/&gt;
&lt;/file&gt;
&lt;file name="kiyut-sketsa-actions-CAGIntersectAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Modify/kiyut-sketsa-actions-CAGIntersectAction.instance"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;</pre>
<p>Next, let's add a <tt>MouseListener</tt> to one of our
Swing components. In our case, we attach it to
the <tt>TopComponent</tt>, which is called <tt>canvas</tt>.
</p>
<pre class="examplecode">//Declare the JPopupMenu:
private JPopupMenu popupMenu;
//Define the constructor:
public CanvasTopComponent() {
//Create the JPopupMenu:
createPopupMenu();
//Attach the JPopupMenu in the mouse event's popup trigger:
canvas.addMouseListener(new MouseInputAdapter() {
public void mousePressed(MouseEvent evt) {
if (evt.isPopupTrigger()) {
showPopup(evt);
}
}
private void showPopup(MouseEvent evt) {
popupMenu.show(evt.getComponent(),evt.getX(),evt.getY());
}
});
}</pre>
<p>Next, put the following code in the <tt>TopComponent</tt>,
to create the <tt>JPopupMenu</tt> and build its content from folders in the <tt>layer.xml</tt> file:
<pre class="examplecode">protected void createPopupMenu() {
String folderName = "Sketsa/Canvas/Popup";
FileSystem fs = Repository.getDefault().getDefaultFileSystem();
FileObject fo = fs.getRoot().getFileObject(folderName);
if (fo == null) { return; }
popupMenu = new JPopupMenu();
buildPopup(fo,popupMenu);
}
/** Recursive Build JPopupMenu
*@param fo FileObject as the DataFolder
*@param comp Menu Container eg: JPopupMenu or JMenu
*/
private void buildPopup(FileObject fo, JComponent comp) {
DataFolder df = DataFolder.findFolder(fo);
DataObject[] childs = df.getChildren();
DataObject dob;
Object instanceObj;
for (int i = 0; i < childs.length; i++) {
dob = childs[i];
if (dob.getPrimaryFile().isFolder()) {
FileObject childFo = childs[i].getPrimaryFile();
JMenu menu = new JMenu();
Mnemonics.setLocalizedText(menu,dob.getNodeDelegate().getDisplayName());
comp.add(menu);
buildPopup(childFo,menu);
} else {
//Cookie or Lookup API discovery:
InstanceCookie ck = (InstanceCookie)dob.getCookie(InstanceCookie.class);
try {
instanceObj = ck.instanceCreate();
} catch (Exception ex) {
instanceObj = null;
ErrorManager.getDefault().notify(ErrorManager.EXCEPTION,ex);
}
if (instanceObj == null) {
continue;
}
if (instanceObj instanceof JSeparator) {
comp.add((JSeparator)instanceObj);
} else if (instanceObj instanceof BooleanStateAction) {
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem();
Actions.connect(menuItem,(BooleanStateAction)instanceObj,true);
} else if (instanceObj instanceof Action) {
JMenuItem menuItem = new JMenuItem();
Actions.connect(menuItem,(Action)instanceObj,true);
comp.add(menuItem);
}
}
}
}</pre>
<p>Apart from the fact that its content is loaded from the <tt>layer.xml</tt> file,
the <tt>JPopupMenu</tt> behaves the same way as any other standard <tt>JPopupMenu</tt>. Therefore, you could attach the <tt>JPopupMenu</tt>
to any Swing component, such as,
for example, a <tt>JList</tt>, as shown <a href="http://blogs.sun.com/geertjan/date/20070217">here</a>.
<p>And for a real dynamic <tt>JPopupMenu</tt>, you could extend the above snippets by
leveraging the NetBeans Platform's <tt>org.openide.awt.DynamicMenuContent</tt> and
listening for <tt>FileObject</tt> changes.
<h3>Cool. So, the code searches for menu items registered in a
folder in the <tt>layer.xml</tt> file. Why is this useful for you and
how/where do you plan to use it in your SVG editor?</h3>
<p>This is <i>very</i> useful for us and maybe other developers who build on top of
the NetBeans Platform. This <tt>layer.xml</tt> approach allows third-party developers, or
any other developers, to very easily
add their own <tt>JPopupMenu</tt> entries into a <tt>TopComponent</tt> in a modular way.
<p>Consider the following scenario. <i>Without</i> the <tt>layer.xml</tt> approach, if
a third-party module wants to add a menu item to the <tt>JPopupMenu</tt>:
<ul>
<li>A third-party module needs to listen for our <tt>TopComponent</tt>'s activated or created event.
<li>A third-party module needs to have deep dependencies on our modules.
<li>A third-party module needs to grab the <tt>JPopupMenu</tt> from our <tt>TopComponent</tt> and
do complicated ordering of menu entries, which become more complicated with
deep sub menu hierarchies.
<li>A third-party module needs to do the plumbing by itself.
<li>A change in our <tt>TopComponent.getPopupMenu()</tt> will be a disaster, because all
the modules will be stop working.</ul>
<p>On the other hand, using the <tt>layer.xml</tt> approach:
<ul>
<li>In terms of Java code, the third-party module only needs to provide its own actions.
<li>In terms of <tt>layer.xml</tt> entries, the third-party module only needs
to register their own actions. Ordering of menu entries is also
simple.
<li><i>We</i> handle the plumbing, using the Lookup discovery.
<li><i>We</i> build the <tt>JPopupMenu</tt> based on the <tt>layer.xml</tt> approach.
<li><i>We</i> handle anything else that needs to be handled.
</ul>
<p>And <i>voila</i>, everything will work together automatically.
<p>And, it is important to realize that
things increase in complexity when a module is installed or
uninstalled during runtime. Using the <tt>layer.xml</tt>, we only need to listen for
changes to the <tt>FileObject</tt> and then rebuild the <tt>JPopupMenu</tt>. The runtime module's
install or uninstall will then run as expected without additional complicated
code for the third party to implement.
<p>This is very similar to the NetBeans Platform's <tt>Node</tt> popup menu, however the NetBeans
Platform's <tt>Node</tt> popup menu is only applicable to a component derived
from the <tt>ExplorerManager</tt> and to components based on <tt>EditorKits</tt>,
such as text-based or source-oriented editor
components. For the custom <tt>TopComponent</tt>, which is a non-text editor component,
as well as projects without <tt>Nodes</tt> or <tt>DataNodes</tt>, this is a powerful approach that
one can take.
<p>By the way, if the NetBeans Platform could have the above snippets as
utility methods, that would be great. As a result, others would not need to always
create the functions <tt>createPopup()</tt> and <tt>buildPopup()</tt> by themselves. They'd
just call them from a NetBeans utilities class, which would do the parsing of the XML Layer
content similar to what my code does above.
<h3>Are there areas relating to the NetBeans Platform that could be improved?</h3>
<p>Well, specifically the following areas:
<p><b>The Documentation.</b>
<ul>
<li>Developers would be very grateful if there was more documentation on
how to use NetBeans Platform efficiently.
<li>Easy to find documentation. Currently it is very hard to find
documentation, the documentation is spread in many different locations, such
as, Wiki FAQs and Javadoc descriptions.
<li>Wiki FAQs needs more content.
</ul>
<p><b>The NetBeans Platform APIs.</b>
<ul>
<li>The base Platform cluster should cover a broader area. Many things in IDE
clusters could become part of the Platform cluster.
<li>Better Loader API. For example, ability to "Save As", currently none exists without a
workaround.
<li>Even better JNLP / Webstart support.
<li>Separate branding into modules that can be installed through the Update Center,
instead of branding being part of the start up, which prevents it
from being updateable using the Update Center.
<li>Deprecate Cookie and replace it with Lookup. Currently it is very
confusing, the situation with Cookie and Lookup. Lookup should be the focus of the
NetBeans Platform, and Cookie should be kept only for backward compability.
Currently, in NetBeans Platform 5.5, Cookies are still a central concept
of the platform, almost anything still requires Cookies to be used.
</ul>
<h3>And what do you think about NetBeans IDE?</h3>
<p>The NetBeans IDE is one of the best Java IDEs we have ever used, especially the
free-form Ant project type. It does not dictate how we should develop our
applications. Instead, it supports us, rather than forcing us to follow the IDE-way of
doing things. It lets us do things the way we like doing them. The free-form Ant project type is
the best project container we have ever seen.
<p>Some tips for other Java IDE users... firstly, you really need to try the free-form
Ant project type! You will not want to go back to your
previous IDE. NetBeans IDE has excellent support for developing Java
applications in the way <i>you</i> prefer doing it, so that
you are <i>not</i> forced to follow the IDE's
conventions.
<p>In NetBeans IDE, the free-form Ant project is our favorite feature, while
in the NetBeans Plaform, we like the Lookup API/SPI most of all.
<h3>What's the future of Sketsa SVG Graphics Editor?
What features will be in the next release?</h3>
<p>With more widespread use of SVG, both in the desktop and mobile areas,
there are increasingly more unexplored opportunities for SVG authoring tools such as ours.
<p>In the short term, we will keep updating Sketsa with features, bug fixes,
and more migrations of the existing in-house framework for the further utilization of the NetBeans
Platform. In the long term, we are looking forward to the SVG Spec 1.2 and JSR
226.
<h3>What will JSR 226 mean for your editor?</h3>
<p><a href="http://wiki.svg.org/index.php?title=JSR_226">JSR 226</a> is a combination of SVG Tiny and Java technology code. JSR 226
API opens the door to interesting applications that adapt to the varying
display sizes and resolutions of mobile devices. We are looking forward
to being able to produce JSR 226-compliant SVG code with Sketsa and to thinking about how we could
interact with Java SVG API as described in JSR 226.
<h3>Finally, do you have any useful links you want to share with us?</h3>
<p>I usually check the following links for updates relating to Java in
general:
<ul>
<p><li><a href="http://www.javalobby.org">http://www.javalobby.org</a>.
General news and updates regarding Java, with an active community.
<p><li><a href="http://www.javadesktop.org">http://www.javadesktop.org</a>.
This link also provides links to a lot of blogs from people inside Sun.
</ul>
<h3>Thanks for the interview Tonny, and please keep us updated about
developments relating to your cool SVG editor!</h3>
</p></body></html>