Saturday Aug 30, 2014

Lazybones Meets NetBeans (Part 1)

One of the things I learned about at JCrete is Lazybones, which is a command-line tool, similar to what Grails, Gradle, and Play provide, for bootstrapping new projects.

In particular, Andres Almiray (@aalmiray) is interested in seeing a NetBeans plugin for Lazybones. The starting point for creating such a plugin is to install Lazybones and run it from the command-line, to make sure everything is set up correctly. Once you've done that, the next step is to call the Lazybones command from within NetBeans IDE, i.e., using NetBeans APIs to do so.

Here's how.

import java.io.File;
import org.netbeans.api.extexecution.ExecutionDescriptor;
import org.netbeans.api.extexecution.ExecutionService;
import org.netbeans.api.extexecution.ExternalProcessBuilder;

public class LNBUtils {

    public static void command(String name) {
        ExecutionDescriptor executionDescriptor = new ExecutionDescriptor().
                frontWindow(true).
                controllable(true).
                showProgress(true);
        File userdir = new File(System.getProperty("netbeans.user"));
        ExternalProcessBuilder externalProcessBuilder = new ExternalProcessBuilder("lazybones").
                workingDirectory(userdir).
                addArgument("create").
                addArgument("ratpack-lite").
                addArgument(name);
        ExecutionService service = ExecutionService.newService(
                externalProcessBuilder,
                executionDescriptor,
                "lazybones create ratpack-lite" + name
        );
        service.run();
    }

}

The above has all the commands hard coded. That's a starting point. Later we'll create a wizard so the user can fill in the values and start the process of creating the selected template.

For starters, here's an ActionListener, registered to appear in the File menu, for invoking the above code:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;

@ActionID(
        category = "File",
        id = "org.netbeans.lnb.RunLazybones"
)
@ActionRegistration(
        asynchronous = true,
        displayName = "#CTL_RunLazybones"
)
@ActionReference(path = "Menu/File", position = 0)
@Messages("CTL_RunLazybones=Run Lazybones")
public final class RunLazybones implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        String name = "my-rat-app-1";
        LNBUtils.command(name);
    }

}

The result is shown in the Output window:


In the next blog entry in this series, we'll hook the above code into a wizard so the user can fill in the values and start the process of creating new Lazybones projects from a more complex GUI than the menu item defined above.

Want to contribute or follow the project as it develops? Go here:

https://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/LazyNetBeansBones

Friday Aug 29, 2014

JCrete 2014

When you go to any kind of conference, specifically a software programming conference, even more specifically a Java conference, you hold certain truths to be self-evident. For example, there'll be a program, there'll be organizers, there'll be rooms, there'll be chairs. There'll be a ceiling.

Well, no such thing, necessarily, at JCrete, an invitation-only annual conference, held for the 4th time, during this week, that strives to invite around 70 people in total. (Nice and small and intimate, and if it were any larger, the process described in the next paragraphs wouldn't work.) It's the best conference I have attended in, like, well, ever. On the day the conference starts, everyone gets a stack of empty yellow post-its and a pen. Then everyone thinks about two or three topics they'd like to hear or talk about and they all write those topics on their post-its, e.g., "Talking about lambdas: patterns and anti-patterns" or "Docker, Vagrant, Packer" or "What's your documentation process like?" or "Which tools do you use?" or "Programming is hard". And then everyone gets up one by one and introduces their topics to the group, enabling everyone to quickly jot down the name of topics that sound interesting, and then sticks the post-its on the "launch pad", i.e., a big piece of paper on the wall.

After everyone has introduced their topics, the process of moving the post-its into a schedule starts. First, some clusters are created, e.g., some topics are similar to other topics. The organizers, i.e., the 'disorganizers', lead this process of clustering and arranging topics in a schedule, though everyone is in full control over where in the schedule their topics will be convened.

The schedule consists of three sessions per day, in the morning, in four different tracks. (Each track is more like a slot, since sessions within a track don't necessarily have anything to do with each other, i.e., there's no Java EE track, instead, there's simply track 1, 2, 3, and 4.) That way, everyone can spend the afternoon at the beach, which is a big plus of Crete. Each session is convened by whoever submitted the post-it bearing the topic. But the convener sits in the session just like any other attendee. For example, just because you submitted "Docker, Vagrant, Packer" doesn't mean that you know anything about those technologies. It just means you might have some half-formed ideas about what they are and how they relate. The main thing is that you're interested in finding out about them and would like others to share their bits of knowledge with you and the rest. The blind leading the blind? Maybe. But remember that JCrete is invitation-only, meaning that many of the attendees have been invited precisely because they're experts in areas that are likely to be interesting, plus that in any of the sessions you'll find that when you combine everyone's half-sightedness you end up with more insight than you would have gained by sitting in a traditional session, no matter how good that traditional session is. Of all the sessions, even the most awesome ones, I've ever attended at other conferences, there's nothing (as in Really, Not One Thing) I remember at this stage, though I'm sure I'll remember the key points attained as a group within the JCrete sessions because I didn't sit passively in any of them. I was engaged and involved and any knowledge acquired wasn't handed to me but was built up throughout the session from the collective knowledge of whoever the people were that were in the session with me. The best sessions turn out to be those where the group is small (while in traditional sessions low attendance means you or your topic must suck somehow, OK sure it's a niche topic and you're really special and it's for smart people and everyone is at the Scala session and so on, and from the very beginning of your talk a grim sense of gloom and dejection hangs over you and everyone else who made the mistake to attend, scattered in odd clumps of one here, another there, and someone else way off in the back edging his way out, and it is more or less impossible to leave because then the speaker, with frail timid voice echoing in large sparsely populated room, might well start crying, hey I'm not mocking anyone, I've been that guy), so everyone gets to talk and the most knowledgeable attendees don't dominate things.

You know how the best part of any conference is the time you spend in the conference corridors, bumping into new and old friends? And how the worst part is when you're sitting in a session, realizing that for any number of different reasons you'd rather be in the corridor? Well, imagine you're in the corridor from start to end and you'll understand how cool JCrete is. Forget about being disappointed about the speaker's (lack of) knowledge or (in)ability to express their thoughts, and then being stuck with them for an excruciating hour, since in JCrete sessions everyone is the speaker, everyone participates, everyone simply chats and no one feels intimidated or stupid. Any question can be stated in as half-baked a form as you like, and is taken seriously by everyone and then mulled over, since questions arise naturally throughout the session no one needs to ask at the end whether there are any questions, nor look awkward when clearly no one cares enough to engage, while every moment is as valuable as you the attendee/speaker enables it to be. 

All separation and division falls away, including the day/night separation, as you find yourself hacking with random people late at night, while others discuss stuff in spontaneous groups, everyone with drinks and very informal. 

But the best sessions of all are the ones in the car on the way to the beach (some beaches are an hour away, so you're in a car with 4 others, and so you're chatting for an hour, i.e., hey that's another session), the ones spent in the sea, and the ones that take place at the dinner table over wine and raki. (For regular traditional conference attendees, consider the thought that every dinner is 'speakers dinner', i.e., no exclusion and no separation between speakers/attendees because everyone is there to speak and everyone is there to attend.) And that is exactly why there are only three sessions (in 4 tracks, i.e., each session you make a choice out of 4 different topics) per day, mostly before lunch, except when an excursion is so interesting it trumps the sessions. The rest of the day springs forth from car-based, sea-based, and dinner-based sessions. These sessions arise spontaneously, such as about the qualities and purpose of olive oil, the main export product of Crete, which, though such topics might have nothing to do with programming, initially, always somehow end up being about programming by the end of it, yes, certainly aided by wine and raki. 


And you know the feeling you have at the end of traditional sessions, when you walk out of a room full of people who must have the same interest as you, otherwise why would they be at the same session as you, but none of whom you had the opportunity to actually talk with? That empty feeling of "wow, a room full of people who are also interested in Java performance, some of them must be experts, all of them must have experiences to share, yet I've spent the past hour listening to one selfinflated illinformed slidebased dude drone on and on about very basic stuff that surely most attendees must have known already when they walked into the room an hour ago"? Or how about that feeling of "wow, within 5 minutes the dude went from uselessly simplistic 'hello world' to massively complex rocket science and I have no idea whatsoever how he did that and I've lost the plot completely within 10 minutes, I must really be a complete idiot because everyone else around me appears to be following along fine with their eyes wide open but that could be because they're proactive and surreptitiously taped up their eyelids which I'd do too if I'd brought tape, which makes me even more of an idiot for not thinking to bring tape". No chance of that when you're at JCrete! 

One of the dozens of takeaways I am left with at the end of JCrete is that next year's NetBeans Day should definitely be an unconference too. (And maybe JUGs could experiment with this format too? And maybe large conferences could attempt this format per topic, e.g., an unconference on IoT within a larger conference that deals with other things too?) Now need to figure out how to relocate NetBeans Day and JavaOne as a whole to Crete for the weather, great food, warm sea, friendly people, and everything else that defines Crete. Yes, the olive oil, for example.

Note: All images shown above were grabbed from Twitter, after doing a search on #jcrete. If you want a long list of enthusiasm about programming in general, that's the hash tag to keep track of.

Friday Aug 22, 2014

Over 300 "NetBeans Platform for Beginners" Sold

I've noticed that the authors of "NetBeans Platform for Beginners" have started exposing the number of sales they have achieved. Below, notice the '304' (which will probably change quite quickly) at the lower left end of this screenshot:

That's pretty good since the book has only existed for a few months and developers tend to share books they buy in PDF format. That probably means there are 300 teams of software developers around the world who are using the book, which is pretty awesome. (Though it would help the authors significantly, I'm sure, if individual developers on teams would buy the book, rather than sharing one between them. Come on, let's support these great authors so that they'll write more books like this.)

Also note that there is a set of reviewer comments on the page above:

Plus, the book is updated at the end of each month, so it continues to grow and improve from month to month, for free for everyone who has bought it.

If you've read the book and want to contribute a review like the above, contact walternyland @ yahoo dot com.

Great work, guys!

For anyone out there who hasn't got it yet: https://leanpub.com/nbp4beginners

Thursday Aug 21, 2014

RequireJS: JavaScript for the Enterprise

I made a small introduction to RequireJS via some of the many cool new RequireJS features in NetBeans IDE. I believe RequireJS, and the modularity and encapsulation and loading solutions that it brings, provides the tools needed for creating large JavaScript applications, i.e., enterprise JavaScript applications.

(Sorry for the wobbly sound in the above.)

An interesting comment by my colleague John Brock on the above:

One other advantage that RequireJS brings, is called lazy loading of resources. In your first example, everyone one of those .js files is loaded when the first file is loaded in the browser. By using the require() call in your modules, your application will only load the javascript modules when they are actually needed. It makes for faster startup in large applications. You could show this by showing the libraries that are loaded in the Network Monitor window.

So I did as suggested:

Click the screenshot to enlarge it and notice how the Network Monitor is helpful in the context of RequireJS troubleshooting.

Wednesday Aug 20, 2014

Asciidoctor / NetBeans

With Jason Lee's NetBake plugin (https://bitbucket.org/jdlee/netbake), when you've installed JRuby and then the Asciidoctor gem, you're good to go to use Asciidoctor with NetBeans IDE.

New Asciidoc files can be created, which have a Source view...

...and a Visual view. The current content of the text editor is parsed by the Asciidoctor gem and the resulting HTML is displayed in a JEditorPane:

Awestruct support is also part of the NetBake plugin, with a new project type and other related features. An Options window is included for configuring the plugin:

I've been in touch with Jason and we're discussing separating the Asciidoctor parts from the Awestruct parts and then putting them seperately as plugins on the NetBeans Plugin Portal.

Tuesday Aug 19, 2014

Gesture Based NetBeans Tip Infrastructure

All/most/many gestures you make in NetBeans IDE are recorded in an XML file in your user directory, "var/log/uigestures", which is what makes the Key Promoter I outlined yesterday possible. The idea behind it is for analysis to be made possible, when you periodically pass the gestures data back to the NetBeans team. See http://statistics.netbeans.org for details.

Since the gestures in the 'uigestures' file are identifiable by distinct loggers and other parameters, there's no end to the interesting things that one is able to do with it. While the NetBeans team can see which gestures are done most frequently, e.g., which kinds of projects are created most often, thus helping in prioritizing new features and bugs, etc, you as the user can, depending on who and how the initiative is taken, directly benefit from your collected data, too.

Tim Boudreau, in a recent article, mentioned the usefulness of hippie completion. So, imagine that whenever you use code completion, a tip were to appear reminding you about hippie completion. And then you'd be able to choose whether you'd like to see the tip again or not, etc, i.e., customize the frequency of tips and the types of tips you'd like to be shown.

And then, it could be taken a step further. The tip plugin could be set up in such a way that anyone would be able to register new tips per gesture. For example, maybe you have something very interesting to share about code completion in NetBeans. So, you'd create your own plugin in which there'd be an HTML file containing the text you'd like to have displayed whenever you (or your team members, or your students, maybe?) use code completion. Then you'd register that HTML file in plugin's layer file, in a subfolder dedicated to the specific gesture that you're interested in commenting on.

The same is true, not just for NetBeans IDE, but for anyone creating their applications on top of the NetBeans Platform, of course.

Monday Aug 18, 2014

Key Promoter for NetBeans

Whenever a menu item or toolbar button is clicked, it would be handy if NetBeans were to tell you 'hey, did you know, you can actually do this via the following keyboard shortcut', if a keyboard shortcut exists for the invoked action.

After all, ultimately, a lot of developers would like to do everything with the keyboard and a key promoter feature of this kind is a helpful tool in learning the keyboard shortcuts related to the menu items and toolbar buttons you're clicking with your mouse.

Above, you see the balloon message that appears for each menu item and toolbar button that you click and, below, you can see a list of all the actions that have been logged in the Notifications window. That happens automatically when an action is invoked (assuming the plugin described in this blog entry is installed), showing the display name of the action, together with the keyboard shortcut, which is presented as a hyperlink which, when clicked, re-invokes the action (which might not always be relevant, especially for context-sensitive actions, though for others it is quite useful, e.g., reopen the New Project wizard).


And here's all the code. Notice that I'm hooking into the 'uigestures' functionality, which was suggested by Tim Boudreau, and I have added my own handler, which was suggested by Jaroslav Tulach, which gets a specific parameter from each new log entry handled by the 'org.netbeans.ui.actions' logger, makes sure that the parameter actually is an action, and then gets the relevant info from the action, if the relevant info exists:

@OnShowing
public class Startable implements Runnable {
    @Override
    public void run() {
        Logger logger = Logger.getLogger("org.netbeans.ui.actions");
        logger.addHandler(new StreamHandler() {
            @Override
            public void publish(LogRecord record) {
                Object[] parameters = record.getParameters();
                if (parameters[2] instanceof Action) {
                    Action a = (Action) parameters[2];
                    JMenuItem menu = new JMenuItem();
                    Mnemonics.setLocalizedText(
                            menu,
                            a.getValue(Action.NAME).toString());
                    String name = menu.getText();
                    if (a.getValue(Action.ACCELERATOR_KEY) != null) {
                        String accelerator = a.getValue(Action.ACCELERATOR_KEY).toString();
                        NotificationDisplayer.getDefault().notify(
                                name,
                                new ImageIcon("/org/nb/kp/car.png"),
                                accelerator,
                                new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                a.actionPerformed(e);
                            }
                        });
                    }
                }
            }
        });
    }
}

Indeed, inspired by the Key Promoter in IntelliJ IDEA.

Interested in trying it out? If there's interest in it, I'll put it in the NetBeans Plugin Portal.

Update 08/19/14: OK, here it is -- http://plugins.netbeans.org/plugin/55751

Sunday Aug 17, 2014

Removing Menu Items from Window Tabs

So you're working on your NetBeans Platform application and you notice that when you right-click on tabs in the predefined windows, e.g., the Projects window, you see a long list of popup menus.

For whatever the reason is, you decide you don't want those popup menus. You right-click the application and go to the Branding dialog. There you uncheck the checkboxes that are unchecked below:

As you can see above, you've removed three features, all of them related to closing the windows in your application. Therefore, "Close" and "Close Group" are now gone from the list of popup menus:

But that's not enough. You also don't want the popup menus that relate to maximizing and minimizing the predefined windows, so you uncheck those checkboxes that relate to that:


And, hey, now they're gone too:


Next, you decide to remove the feature for floating, i.e., undocking the windows from the main window:

And now they're gone too:

However, even when you uncheck all the remaining checkboxes, as shown here...

You're still left with those last few pesky popup menu items that just will not go away no matter what you do:

The reason for the above? Those actions are hardcoded into the action list, which is a bug. Until it is fixed, here's a handy workaround:

  1. Set an implementation dependency on "Core - Windows" (core.window). That is, set a dependency and then specify that it is an implementation dependency, i.e., that you'll be using an internal class, not one of the official APIs.

  2. In one of your existing modules, or in a new one, make sure you have (in addition to the above) a dependency on Lookup API and Window System API.

  3. And then, add the class below to the module:
    import javax.swing.Action;
    import org.netbeans.core.windows.actions.ActionsFactory;
    import org.openide.util.lookup.ServiceProvider;
    import org.openide.windows.Mode;
    import org.openide.windows.TopComponent;
    
    @ServiceProvider(service = ActionsFactory.class)
    public class EmptyActionsFactory extends ActionsFactory {
    
        @Override
        public Action[] createPopupActions(TopComponent tc, Action[] actions) {
            return new Action[]{};
        }
    
        @Override
        public Action[] createPopupActions(Mode mode, Action[] actions) {
            return new Action[]{};
        }
        
    }

Hurray. Farewell to superfluous popup menu items on your window tabs. In the screenshot below, the tab of the Projects window is being right-clicked and no popup menu items are shown, which is true for all the other windows, those that are predefined as well as those that you add afterwards:


Thursday Aug 14, 2014

Sin IDE: Best Of All Worlds

Sin IDE is... a super slick and snappy mashup of Sublime Text + IntelliJ IDEA + NetBeans IDE.

Click to get a fuller picture:

Featuring a firy brew of free and out of the box tools for seamless work with Git, Mercurial, Subversion, Maven, Gradle, Java, JUnit, TestNG, FindBugs, Java EE, JavaFX, Java Profiler, Tomcat, TomEE, GlassFish, WildFly, WebLogic, MySQL, Oracle DB, Java Derby, embedded JavaFX WebKit browser, AngularJS, KnockoutJS, RequireJS, NodeJS, Bower, Karma, Grunt, HTML5, CSS3, JavaScript, Chrome Developer Tools, PhoneGap/Cordova, IoT, Oracle Cloud, Raspberry Pi, PHP, C/C++ and much much more, the top ten of which are here.

Promo material consists of a t-shirt featuring a laughing demon on the front and the logo "So good, it's sinful" on the back in flames...

About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« August 2014 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
15
16
23
24
25
26
27
28
31
      
Today