Sunday December 31, 2006
My Top 5 Discoveries on YouTube
I only discovered YouTube about 6 months ago, but in that time I've browsed through quite a lot of it. The best part is discovering completely new things relating to areas you already find interesting. So, anyway, here's my top 5 discoveries on YouTube over the last 6 months:
- Signed version of "Torn". This is the best thing on YouTube. A supposedly "signed" version of Torn by Natalie Imbruglia. Click here to check it out.
- Russell Peters. I like stand up comedy and had never heard of Russell Peters. Somehow I stumbled across him on YouTube. He's fantastic, hilarious, wise, clever, empathetic. Here's a list of results if you search for Russell Peters on YouTube. Honorable mention: Brian Regan. Really funny guy. Also discovered accidentally by me on YouTube.
- Greg Ferguson. Actually, Jon Stewart, who I had never seen until someone sent me a link from YouTube, was my ultimate presenter-hero for quite a while. But... he's becoming a bit too much, sometimes. His comments are always very sharp and right on the ball, I think. (But I'm more of a Conan guy, I guess.) However, I had never heard of Greg Ferguson. Here's a link to stuff with Greg Ferguson.
- Bloopers. If you search for "Seinfeld bloopers" and "Friends bloopers" on YouTube, you'll have a guaranteed gold mine of hilarious clips.
- We like the moon. Okay, so it's not on YouTube. But it is online and hilarious and fantastic. Click here.
Dec 31 2006, 12:43:44 AM PST Permalink
Dec 27 2006, 05:03:20 AM PST Permalink
Optimizing the Module Manager
Aaaargh! Someone tells you: "Install this module and all your problems will be solved." So you install the module. Later you want to uninstall it for some reason. So you go to the Module Manager and find... that you can't find the module. Why? Because it's in some category and you don't know which category:
However, did you know that you can right-click inside the Module Manager? Do that and choose Sort By Name:
And then... there are no categories. Only modules. And they're sorted alphabetically:
Helpful sometimes. (I blogged about this right-click menu some time ago, but didn't realize the true power of the Sort By Name item, until this morning when a colleague couldn't find a module and I remembered that I'd blogged about this.)
Dec 19 2006, 03:29:29 AM PST Permalink
Corporate Blogging and the Technical Writer
"Though it may be a small percentage of all blogging, corporate blogging is rapidly gaining popularity as a way for companies to connect with their customers and increase internal communication."
So begins a feature article entitled "Corporate Blogging and the Technical Writer" in the September/October 2006 issue of Intercom, the magazine of the Society for Technical Communication. Tom Johnson, the author of the article (who I met through this blog), interviewed me as part of his research and quotes me in one or two places, such as this one: "By blogging about the questions you have and the confusion coming out of the material you’re working on, you’ll find many people with similar issues, and some who have answers, thus enhancing your work without doing very much yourself. Anyone can stumble across what you’re blogging about and provide information that provides that little chunk of light needed to continue with your writing."
To me, that's one of the greatest uses of corporate blogging for the technical writer. The whole article is really good, I think (aside from the wisdom of deciding to include me, of course), covering the whole area of blogging for writers, the pros and cons, the concerns one might have, and the benefits. The whole article, permission obtained from the author, is available here in PDF format:
Corporate Blogging and the Technical Writer
Dec 18 2006, 11:44:33 PM PST Permalink
Programmatically Putting TopComponents in Modes
First a picture:
The list of menu items above appears when the TopComponent's tab is right-clicked. When a menu item is selected, the TopComponent moves to the selected mode.
Next, the two things you need to know to implement this:
- How to specify the mode. For each menu item, create a Java class implementing AbstractAction. In the actionPerformed method, send the name of the mode (e.g., "properties" or "editor") as a string to the TopComponent. In the TopComponent, define the open() method like this:
public void open() { Mode mode = WindowManager.getDefault().findMode(selectedMode); if (mode != null) mode.dockInto(this); super.open(); }Above, selectedMode is a string, received from the actionPerformed method in the AbstractAction implementation.
- How to put the actions in the TopComponent's tab. Override the TopComponent's getActions method. Like this:
public Action[] getActions() { return new Action[]{ new OpenExplorerWindowAction(), new OpenEditorWindowAction(), new OpenPropertiesWindowAction(), new OpenOutputWindowAction(), new OpenNavigatorWindowAction() }; }
And that's all you need to know to let the user move a TopComponent via a menu item. Of course, they could also just drag and drop the TopComponent via its tab, but by providing the menu items in the tab, the functionality is less hidden. You could also use the code above in a different way, maybe you want the TopComponent to move to a different mode, depending on something done by the user in the application.
Dec 17 2006, 10:54:20 AM PST Permalink
Playing with Persistence Across Sessions
There's an interesting bunch of code that you get when you use the "Window Component wizard", code that I had never understood before. When you use the wizard, you get a subclass of the TopComponent class, including a lot of code, which are stubs for your own implementations of the TopComponent abstract methods. One of these methods is writeReplace(), which instantiates a new serializable class called ResolvableHelper. This is exactly what this part of the generated code looks like by default:
public int getPersistenceType() {
return TopComponent.PERSISTENCE_ALWAYS;
}
public Object writeReplace() {
return new ResolvableHelper();
}
final static class ResolvableHelper implements Serializable {
private static final long serialVersionUID = 1L;
public Object readResolve() {
return DemoTopComponent.getDefault();
}
}
Let's say you have two JTextFields in your TopComponent. You would then modify the generated writeReplace() method as follows:
public Object writeReplace() {
return new ResolvableHelper(
jTextField1.getText(),
jTextField2.getText()
);
}
So, now you're passing the value of your two text fields to the ResolvableHelper, which means you need to create a constructor so that this class can receive the two strings. All the changes to the code are highlighted:
final static class ResolvableHelper implements Serializable {
private static final long serialVersionUID = 1L;
private final String text1;
private final String text2;
ResolvableHelper(String text1, String text2) {
this.text1 = text1;
this.text2 = text2;
}
public Object readResolve() {
return DemoTopComponent.getDefault();
}
}
So, now that we have our strings in the ResolvableHelper class, let's use the Serializable's readResolve() method:
public Object readResolve() {
DemoTopComponent result = DemoTopComponent.getDefault();
result.jTextField1.setText(text1);
result.jTextField2.setText(text2);
return result;
}
Now install the module, type some text in both text fields and notice that, when you restart the IDE, the text that you typed has been preserved. The key to the whole story is this: Because of TopComponent.PERSISTENCE_ALWAYS in the getPersistenceType() method, you are indicating that the TopComponent should be saved when the IDE (or your own application on the NetBeans Platform!) shuts down. If you don't define a writeReplace() method, nothing will be preserved when the application starts again. However, when you define the writeReplace() method, you can create a serializable class that will store your data across restarts.
I think this is a pretty powerful mechanism, especially since it is so easy to use (once you know how to use it). By the way, this is one of the cool things I'm learning while reviewing one of the chapters in the upcoming NetBeans Platform book. Yes, this is the level of detail that this book covers. No lofty theoretical treatise, but a practical handbook for every day use. Hurray.
Dec 16 2006, 01:29:06 PM PST Permalink
Lifting the Veil: How the NetBeans Platform Book is Being Written
The upcoming NetBeans Platform book, entitled "Rich Client Programming" (subtitled "Plugging into the NetBeans Platform") is being written in...
...NetBeans itself. We're using a DocBook module (made by Jesse and Tim, as far as I'm aware) that recognizes a DocBook folder structure as a project, so that a folder of DocBook files can be treated like files in any other project. So, this is what the book looks like, and this is the view I have on it while writing:
And, each individual chapter (or the book as a whole) can be turned into an HTML file via a menu item, as shown above. And then you're one click away from a PDF document:
So, we're writing the book in the same way as NetBeans encourages people to program... in a modular way. Various individual people are responsible for individual chapters, they write them, commit them to CVS, and eventually the whole book will be assembled from these separate pieces.
We're by no means at the end yet, but our deadline is coming up very soon, (and then the proof reading cycle begins) so we're definitely very far along already. I'm really looking forward to seeing it in print!
Dec 14 2006, 08:46:20 AM PST Permalink
10 Questions about the new NetBeans Lexer API
I am learning about the new NetBeans Lexer API and asked Mila Metelka, the main engineer responsible for this API, a few questions about it. Below are summaries of his responses, together with some of my own research.
- What is a "lexer"? A lexer "lexes" (also known as "parsing" or "tokenizing") textual input and turns it into tokens. The textual input currently supported by the new Lexer API can come from java.lang.CharSequence and java.io.Reader. javax.swing.text.Document is also supported by wrapping it by means of a CharSequence. Character sequences having a textual content that can be modified (such as the Swing Document) may benefit from the main feature of the new Lexer API, which is incremental updates of the token list based on modifications made in the textual input.
In the context of the NetBeans Platform, the Lexer API is useful for lexing text in an editor so that groups of related characters can be recognized as 'tokens', which can then be bound to a color. For example, for the syntax highlighting (also known as "syntax coloring") to work in the screenshot below, the document had to be lexed so that everything before the colon is recognized as one token, everything after the colon (up to the linebreak) is recognized as another token, and the colon itself is recognized as a token too. Then colors are bound to the tokens, with this result:
Without NetBeans APIs that provide lexing support, the NetBeans editors would need to have an implementation of a DrawLayer (or a HighlightLayer, in terms of the new Highlighting SPI) that would perform the syntax coloring in their own manner. In 6.0, with a back port to 5.5, the NetBeans APIs provide a new and improved approach to lexing. Basically, the new Lexer API makes it easy to provide incremental lexing, which is otherwise a lot of work.
- Where does the new Lexer API come from? The algorithm that updates the token list incrementally is based on "General Incremental Lexical Analysis", a PhD thesis written by Tim A. Wagner and Susan L. Graham, from the University of California, Berkeley. It is available online here: twagner-lexing.pdf.
The Lexer API does not expose the algorithm in any way, because the TokenListUpdater is hidden in the implementation (here). Although the lexer module has existed since 05/2002, its API was rewritten completely for NetBeans 6.0, with additional support for language embedding.
- What's the crux of the thesis in relation to the NetBeans Platform? Well, this paragraph in the thesis sums it up: "In some situations, such as in a software development environment (SDE), a series of character streams are repeatedly analyzed with few differences (relative to the total number of tokens in the program) from one application of lexical analysis to the next. Since tokens typically have very limited contextual dependencies, the resulting differences in the token stream are typically limited to the area immediately surrounding modification sites. In this setting it makes sense to retain the token stream as a persistent data structure and use it to decrease the time required for subsequent analyses. We will refer to this as incremental lexing and the tool that performs it as an incremental lexer. Our approach exploits existing technology for generating batch lexers by using the output of these tools produce in conjunction with an incremental run-time system."
- Is the Lexer API implemented exactly as outlined in the thesis? No. The NetBeans Lexer API is a simplification of the algorithm proposed by the thesis. The thesis proposes a very generic approach. In NetBeans only those parts that are relevant are implemented. For example, something called "lookbacks" (discussed in section 3.6) are calculated on the fly and are not stored. A lookback is the number of tokens to look back from the current token, to work out the boundaries of subsequent tokens. However, a disadvantage of this is that it gives you an extra value to maintain and store, while typical languages do not need to store a lookback. Furthermore, the thesis argues that the algorithm should not be able to restart at the beginning of certain tokens, while the NetBeans Lexer API assumes each token is restartable. For further details, read the extensive comments at the start of the source of org.netbeans.lib.lexer.inc.TokenListUpdater.java.
- What's so much better about this new API? Before NetBeans used the Lexer API, a different approach was used, via the NetBeans API Syntax class. Using the Lexer API, the improvements are as follows:
- Permanent token instances. The original support was designed in early times, where NetBeans engineers didn't want to create permanent token instances, because in JDK 1.1 object creation was expensive. So there were no permanent, long lived tokens. If you wanted to iterate back into the tokens, no backward scanning was possible, the infrastructure needed to create batches of tokens, and then go backward. So, backward iteration was very awkward. In contrast, the new Lexer API has a permanent token list, so you can iterate forward and backward.
- Smaller token updates. With the new Lexer API, updates after document modifications are typically very small. The old support updated at least the whole line, which is not a problem in regular typing, but when you reformat a bunch of code, or the whole source, because of the reformatting to save bookmarks, other annotations, and positions, it became problematic. Now, the reformatting does incremental changes to the whole document, because if there are a lot of incremental changes, the amount of update information becomes important. The Lexer API is based on the technology that was mentioned in Tim Wagner's dissertation, which includes proof that this algorithm relexes only a minimal necessary number of tokens.
- Triggering. The old lexing support was triggered after each request. Each request that needed tokens, such as painting and brace matching, triggered lexing. In contrast, the new Lexer API is only triggered once, after modification, to fix the token list. This also helps debugging of your Lexer implementation—originally, if you put any debugging code into your syntax code, the debugger got triggered many many times and you didn't know what was going on. There was a lot of debugging info, because there were many requests for lexical scanning. Right now, there is only one invocation of the Lexer API for each modification, which helps you to find problems more easily.
- Testing. There's now much better support for testing of lexical correctness. There are several ways of testing.
- TokenDumpTest. In this test, batch lexing is done. You have some text input that you can run the Lexer API on and check whether the created tokens match your expectations.
- ManifestLexerRandomTest. In this test, you specify the characters (or strings) with a certain probability of insertion. Then the test builds the global list of probabilities and randomly inserts/removes the data in a Swing text document. This will trigger the Lexer API to fix the token list after modification and this fixed token list will be compared with another token list, created by taking the string text of the whole document after the modification and scanning it by batch scanning (from the beginning until the end). These two token lists are compared and must match, otherwise the test fails.
So, you can reuse the testing infrastructure that is provided by the Lexer API, for your own lexer implementation.
- Embedded languages. The old support was very awkward in relation to language embedding. It was necessary for token IDs to have ordinals, and it was necessary to shift the ordinals of the embedded languages. The old support was only able to see the source as a flat list of tokens. Switching between the syntaxes, and other complexity of the embedding, was the responsibility of the implementer of the solution. There was a very infamous NetBeans class called JSPMultiSyntax. It was very large and it was very easy to make some error that was very hard to find. So, language embedding was very difficult.
Now, the lexers can be reused for embedded languages. You just specify the top level language, you specify in which tokens there can be potential embedding, which you can either specify directly in your language hierarchy class (method called "embedding") or declaratively in the XML Layer. You only specify the MIME type or the language, and the infrastructure will do the rest, will create the physical tokens and update them. It should be easy, especially compared to how it was before.
- Simplification of hand coded lexers. No editorkit class is needed, because you reuse the LexerEditorKit, registered declaratively in the XML Layer. No settings initializer is used, because default font colors are made available declaratively through the XML Layer. As a side effect of removing the editorkit, no Options window extension is needed either. (However, the effect of this is that the Manifest Editor will not be listed in the Advanced section of the Options window. But the colorings will be configurable in the main part of the Options window, so that should be sufficient.) And because you're not using a settings initializer, you don't need to call it from the module installer either. So, unless you need a module installer for other reasons, you don't need it here. (Not having a module installer is a good thing, because even though they're necessary in various cases, they slow down the start up process.) For details on the changes to make, see the Lexer Migration Guide.
Clearly, a lot less classes, a lot more done declaratively, a lot more is reused from the API itself without requiring you to implement anything. As evidence, in the screenshots below, the first shows the files needed for the old way of providing syntax highlighting for manifest files, while the second shows the fact that far less is needed for the new Lexer API:
- What are the steps for creating an implementation of the Lexer API? It depends on whether you want to use a Lexer Generator or if you want to hand code the implementation. For simple lexers, you may want to hand code the implementation yourself. You need to implement org.netbeans.api.lexer.TokenId, using Enums to define the token IDs. Next, you need to provide a lexical scanner, implemented by Lexer<T extends TokenId>, among other API classes, which together take the input, turn it into tokens, and bind them to colors. The colors come from an XML file, registered in the XML layer for the applicable MIME type. The XML file contains the default colors, mapped to the names of the token IDs. (The user can modify the default colors, using the Options window to do so.)
- Will the new Lexer API, once stabilized, be compatible with the old support for syntax highlighting in NetBeans? No. The old support will be deprecated. By the time 6.0 comes out, all NetBeans sources will be rewritten to use the new Lexer API.
- Can I migrate my existing hand coded syntax highlighting implementation to create a hand coded implementation of the Lexer API instead? Yes! The Lexer Migration Guide provides a quick journey through the NetBeans Manifest File Syntax Highlighting Module Tutorial, telling you what to change where and, in some cases, why. If the migration guide proves useful, it will be expanded to include more detailed descriptive explanations.
- Where can I find out more about this API? The current homepage for this API is http://lexer.netbeans.org/, though it will probably move to the NetBeans Wiki soon. On the homepage, you'll find tips, a FAQ, source description, lexer generated tools, and a variety of use cases. Everything you need to know about the new Lexer API should be available from there. In addition, make sure to read Lexer API Javadoc.
- What do I need to get started? The modules that provide the Lexer support will be included out of the box in 6.0. For 5.5, you will (soon) be able to get the modules from the update center. The modules are as follows:
- Lexer module. The module that provides the infrastructure that contains the APIs and implementation.
- Lexer/editorbridge. The module that provides for the binding of the Lexer module to NetBeans editors and provides syntax highlighting.
- Lexer/nbbridge. The module that provides for finding and instantiating the languages registered declaratively in the XML layer.
The Lexer support is already available in trunk builds, although work continues to be done to improve it further. (See Mila's list of issues here, which includes Lexer-related issues.) However, everything currently works as described in the migration document listed above.
Thanks to Mila Metelka and Tor Norbye (who blogs about his Ruby Lexer, based on the new NetBeans Lexer API, here) for feedback on this blog entry. Any errors or misinterpretations are purely my own fault.
Dec 13 2006, 03:51:28 AM PST Permalink
The "Browseable" Attribute in the Error Annotation DTD
Today I learned something new about the error annotation DTD. If you define an annotation with the browseable annotation set to true (as shown below, in the highlighted line), then (and only then) the Jump to Next Error Action Module will work for your annotation.
<!DOCTYPE type PUBLIC
"-//NetBeans//DTD annotation type 1.1//EN"
"http://www.netbeans.org/dtds/annotation-type-1_1.dtd">
<type name="org-netbeans-modules-manifesterrorannotation"
description_key="LAB_Error"
localizing_bundle="org.netbeans.modules.manifesterrorannotation.Bundle"
visible="true"
glyph="nbresloc:/org/netbeans/modules/java/resources/error-glyph.gif"
waveunderline="#ff0000"
type="line"
browseable="true"
severity="warning"
actions="some-action"
/>
What the module does is, it lets you jump (or, "browse") from annotation to annotation (and then back to the first one), using the Alt-Shift-N keybinding. That's possible by default for bookmarks, although not with that keybinding. Using the Alt-Shift-N keybinding, you will be able to browse to all annotations that have browseable set to true.
Dec 12 2006, 08:21:46 AM PST Permalink
Common Palette API + MultiView Windows API
I wanted to try to combine the Common Palette API with the MultiView Windows API, just to see if I could do it. So, I started with the sample that you get at the end of the NetBeans Component Palette Module Tutorial, by turning the editor into the source view of a multiview editor. Once that was working, I created a TopComponent, implementing MultiViewElement, and then created a MultiViewDescription for the TopComponent, and added that MultiViewDescription implementation to the array of MultiViewDescriptions in the CloneableEditorSupport implementation. Then, as usual, associated the palette with the TopComponent's constructor. It was just an experiment, so I added the same palette to both views, even though it doesn't actually work for the visual view (because I haven't implemented a drop target in the TopComponent and because the palette items are for a text based editor, not for a visual component).
The result of all of this is that I now have a palette in my source view, as shown here:
But I also have a palette in my visual view, as shown here:
Mohamed and co's Plethora open source project provides something similar.
Dec 11 2006, 10:07:15 AM PST Permalink
The "Action" Attribute in the Error Annotation DTD
I discovered something interesting today. I was trying to work out what the "actions" attribute is for in the error annotations DTD (click here to see it). I found out that there are at least two cases in the NetBeans sources where the "actions" attribute is used. In BreakPoint.xml, BreakpointActions is defined as the value of the "actions" attribute, while in parser_annotation_err_fixable.xml one finds hints-fixable defined there.
I've experimented with the attribute and discovered that, after defining a value for that attribute, you need to register it in the Layer XML file's AnnotationTypes section. So, I defined the value of the "actions" attribute as "some-action" and then registered it in the Layer XML file like this:
<folder name="Editors">
<folder name="AnnotationTypes">
<folder name="some-action">
<file name="org-netbeans-modules-mymodule-SomeAction.instance"/>
</folder>
</folder>
</folder>
And then... in the left sidebar, you have a new menu item, defined by the action registered in the XML Layer (the name "Manifest is Broken", comes from the Bundle.properties file, which is also defined in the error annotations XML file):
This is also how the Bookmark menu items end up in the left sidebar's menu. In the definition of the Bookmark.xml error annotation XML file, BookmarkActions is defined as the value of the "actions" attribute". Then, in the Layer XML file, you find the following registration:
<folder name="AnnotationTypes">
<file name="bookmark.xml" url="bookmark.xml"/>
<folder name="BookmarkActions">
<file name="bookmark-toggle.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/bookmark-toggle.instance"/>
</file>
<file name="bookmark-next.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/bookmark-next.instance"/>
</file>
<file name="bookmark-previous.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/bookmark-previous.instance"/>
</file>
</folder>
</folder>
Pretty cool. This is a very obscure corner of development on the NetBeans Platform, but handy to know about nonetheless...
Dec 10 2006, 01:41:18 PM PST Permalink
World's First Computer: More Valuable Than Mona Lisa?
Somewhere between 100BC and 150BC, possibly by the Greek astronomer Hipparchos, who at that time lived on the island of Rhodes, an astronomical instrument was invented, turning out to be a complex computer for calculating the relative positions of the sun, the moon and the planets. I visited it this morning, in the National Archaeological Museum of Athens. This, thanks to this week's article (which also describes it in some detail) in the Athens News, is what a main part of its remains looks like:
"It does raise the question of what else were they making at the time. In terms of historic and scarcity value, I have to regard this mechanism as being more valuable than the Mona Lisa," Professor Mike Edmunds of Cardiff University, who is a leading member of the research team that identified the mechanism's use, said.
What is interesting, though, is that visually the Antikythera Mechanism (named after the island near which it was found) is just about the ugliest thing in the entire museum, filled as it is with a vast array of statues, busts, vases, and intricate sculptures and paintings from all over Greece, stretching back many centuries. Maybe in terms of what it tells us, and because it is a lot more unique than the thousands of amphoras displayed all over the museum, it is more valuable than the Mona Lisa. But I know I spent a lot more time admiring the youth from Antikythera than this pretty twisted piece of bronze and wood from the same island, which you would walk right past if you weren't intentionally looking for it... so I guess it is the apples and pears comparison once again. (And, at the same time, when I visited the Louvre, I would probably have walked right past the Mona Lisa as well, if it hadn't been for the crowd clustered around it, reconfirming that my sense of beauty does not coincide with the value of the object I admire, whether financial or utilitarian, which is a good thing, possibly.)
Read more about the Antikythera Mechanism in this Athens News article: Greek astronomy ahead of its time.
Dec 09 2006, 02:51:25 AM PST Permalink
Eclipse and NetBeans: A Tale of Two Rich Client Platforms
I've been talking off and on with Kai Toedter from Siemens about proposing a technical session for JavaOne on the differences and similarities between the NetBeans Platform and Eclipse RCP. We're now at the point where we're formulating a proposal (since we only have until the 15th to do so). This is what our plans are so far (although we may change things here and there before the 15th):
Title:
Eclipse and NetBeans: A Tale of Two Rich Client Platforms
Abstract:
Currently rich desktop clients are becoming very popular again. The NetBeans Platform and the Eclipse Rich Client Platform (RCP) both offer a rich framework on which developers can build very advanced desktop applications without reinventing the wheel. These platforms offer standard functionality out of the box, such as a windowing system, update functionality, a help system, and branding concepts. They also both offer a module based runtime system.
However, what are their differences and how do they stack up against each other? On the surface, one of the fundamental distinctions is the choice of UI toolkit. Eclipse RCP uses SWT, while NetBeans Platform uses Swing. What are the consequences of choosing these distinct toolkits? And, what support do the corresponding IDEs give, such as their approaches to development cycles and ease of development?
In this presentation we will use a demo application built on both platforms to illustrate the ways in which each platform implements the same features and to compare the different approaches.
Presentation Summary:
- Introduction and architecture overview of both platforms
- Fundamental concepts
- Swing and NetBeans Core UI <-> SWT, JFace and Generic Workbench
- NetBeans Module System <-> Eclipse OSGi based Platform Runtime
- NetBeans System Filesystem and XML Layers <-> Eclipse Extension Point Mechanism
- Introduction of the demo application "MP3 Manager" on both platforms
- NetBeans Suite and Modules <-> Eclipse Features and Plug-ins
- NetBeans Window System, TopComponents, & Editors <-> Eclipse Perspectives, Views, & Editors
- NetBeans Node system <-> Eclipse resource and workspace concept
- Integrating update functionality
- Other ancillary topics, such as product branding and help system integration
How does the above proposal sound? If you were at JavaOne, would you be interested in this technical session?
Dec 07 2006, 09:21:40 AM PST Permalink
Convert your TopComponent to a MultiViewElement
A brief overview of how to convert a TopComponent to a visual page in a multiview editor. First we recognize a new file type, then we change the Open menu item to open a TopComponent instead of a data editor, and then we change the TopComponent to a multi view element.
- Use File Type wizard to let IDE recognize your new file type.
- Use Window Component wizard to create new TopComponent implementation.
- Create an OpenSupport class, extending OpenSupport and implementing OpenCookie and CloseCookie. Content of methods:
public MyOpenSupport(MyDataObject.Entry entry) { super(entry); } protected CloneableTopComponent createCloneableTopComponent() { MyDataObject dobj = (MyDataObject)entry.getDataObject(); MyTopComponent tc = new MyTopComponent(dobj); tc.setDisplayName(dobj.getName()); return tc; }In the data object, replace the DataEditorSupport's addition to the CookieSet by adding the OpenSupport class to the CookieSet:
cookies.add((Node.Cookie) new MyOpenSupport(getPrimaryEntry()));
- Change the TopComponent's extension class to CloneableTopComponent and receive the data object in the constructor (not doing anything with it here, but useful later). Return null in the getDefault() method.
- Install the module and when you double-click (or choose Open from the menu) on the file type, your TopComponent will open.
Now we'll convert the TopComponent to an element in a multiview editor.
- Add dependency on "Core - MultiView Windows".
- For each page in the multiview editor, create classes that implement MultiViewDescription and Serializable. The method createElement() returns a MultiViewElement. What you want to return here is your TopComponent, which means you must modify the TopComponent to extend JPanel and implement MultiViewElement.
- Repeat the last step for each page in the multiview editor.
- Change the createCloneableTopComponent method in the OpenSupport class to open your multiview elements (here we have two):
protected CloneableTopComponent createCloneableTopComponent() { // Create an array of multiview descriptors: MyPanelMultiViewDescriptor main1 = new MyPanelMultiViewDescriptor(); MyPanelMultiViewDescriptor2 main2 = new MyPanelMultiViewDescriptor2(); MultiViewDescription[] descArry = { main1, main2 }; // Create the multiview: CloneableTopComponent tc = MultiViewFactory.createCloneableMultiView(descArry, main1, null); return tc; } - Install and open the file again. Now you have a multiview editor (without a source view, currently). The second argument in MultiViewFactory.createCloneableMultiView determines which of the pages is open by default. Here it is "main1", the page defined by MyPanelMultiViewDescriptor1:
A lot more needs to be done (for example, with the above instructions you won't even be able to close the multiview editor), but the above is a start. Thanks Rich, as you can see I'm learning a lot from reviewing your document.
Dec 06 2006, 01:04:58 AM PST Permalink
Creating Error Annotations in NetBeans IDE (Part 4)
I'm visiting Andreas and we've been working on adding error annotations to the Tapestry Support Module for NetBeans. Here's the result so far, a prototype for an annotation on the object attribute in Tapestry inject elements:
I provided the annotation, its registration in the XML layer, the DataEditorSupport implementation, and its addition to the DataObject's Lookup. All this is very standard code, nothing special at all. The contribution by Andreas was more complex—parsing the XML document to the point where the error occurs. Here, a dummy value is filled in. Eventually all the allowed values will be compared against whatever is typed in as the object attribute's value. The method returns the offset of the value that is wrong, as well as the length of the value:
public int[] findError(Document doc) {
int[] errors = null;
BaseDocument bdoc = (BaseDocument) doc;
ExtSyntaxSupport sup = (ExtSyntaxSupport)bdoc.getSyntaxSupport();
boolean prev = false;
try {
TokenItem token = sup.getTokenChain(0, 1);
while (token!=null) {
if ("attribute".equals(token.getTokenID().getName())) {
String attr = token.getImage();
if ("object".equals(attr)) {
TokenItem next = token.getNext().getNext();
if (next!=null && "value".equals(next.getTokenID().getName())) {
String val = next.getImage();
if (val.startsWith("\"service:tapestry.")) {
errors = new int[2];
errors[0] = next.getOffset() + 1;
errors[1] = next.getNext().getOffset() - next.getOffset();
}
}
}
}
token = token.getNext();
}
} catch (BadLocationException ex) {
ex.printStackTrace();
}
return errors;
}
However, note that here BaseDocument.getSyntaxSupport() is used to get the tokens. There's no other way to do this, as far as I'm aware, although using this approach is not ideal since the Lexer module provides a different way of working with tokens. So, this will have to be rewritten once the Lexer module becomes the official way of working with tokens.
Dec 05 2006, 03:49:14 AM PST Permalink



