Česky   |  Deutsch   |  English   |  Español   |  Français   |  Indonesia   |  日本語   |  한글   |  Polski   |  Português (BR)   |  Türkçe   |  中文   |  正體中文   |  Your Language  
PlanetNetbeans
Planet NetBeans is an aggregation of NetBeans related musings from all over the Blogosphere.
Feeds
[RSS 1.0 Feed] [RSS 2.0 Feed]
[FOAF Subscriptions] [OPML Subscriptions]
Do you blog about NetBeans ? Add your blog to PlanetNetBeans.
Feed Subscriptions
pandaconstantin's blog (feed)
APIDesign - Blogs (feed)
ludo's blog (feed)
hansmuller's blog (feed)
pkeegan's blog (feed)
richunger's blog (feed)
tball's blog (feed)
timboudreau's blog (feed)
David R. Heffelfinger (feed)
NetBeans Zone - The social network for developers (feed)
Carsten Zerbst's Weblog (feed)
Winston Prakash's Weblog (feed)
Michael's blog » NetBeans (feed)
DukeScript (feed)
ProNetBeans (feed)
Tim Boudreau (feed)
Paulo Canedo » NetBeans English (feed)
Anchialas' Java Blog (feed)
markiewb's blog (feed)
Need to find a title (feed)
Category: NetBeans | Software and Science (feed)
Roger Searjeant's blog (feed)
Inspiration and Expression » Netbeans (feed)
John O'Conner » NetBeans (feed)
Adam Bien (feed)
Ignacio Sánchez Ginés » NetBeans (feed)
Bernhard's Weblog (feed)
Michel Graciano's Weblog (feed)
Ramon.Ramos (feed)
Ozone and Programming » netbeans (feed)
NetBeans Ruminations » NetBeans (feed)
Tiplite » netbeans (feed)
Arun Gupta, Miles to go ... (feed)
Geertjan's Blog (feed)
.JARa's Bilingual Weblog (feed)
JavaFX Composer (feed)
The Java Jungle (feed)
Jesse Glick (feed)
Martin Grebac (feed)
The NetBeans Community Podcast (feed)
NetBeans Profiler (feed)
NetBeans for PHP (feed)
NetBeans Web Client (feed)
Rechtacek's (feed)
Virtual Steve (feed)
My First Blog - Satyajit Tripathi (feed)
The Aquarium (feed)
Tinuola Awopetu (feed)
Insert Witty Irony Here (feed)
Gualtiero Testa » Netbeans (feed)
James Selvakumar's Blog » netbeans (feed)
nB gUru » NetBeans (feed)
Newsintegrator Blog » netbeans (feed)
Praxis LIVE » NetBeans (feed)
TechAshram » NetBeans (feed)
There's no place like 127.0.0.1 » Netbeans (feed)
Anuradha (feed)
Netbeans6/6.5 my best practices (feed)
Java Evangelist John Yeary (feed)
Neil's Dev Stuff (feed)
Computer says null; (feed)
NetBeans Adventures, Java and more (feed)
Bistro! 2.0 (feed)
NetBeans Community Docs Blog (feed)
The Netbeans Experience (feed)
NbPython/ jpydbg / pymvs (feed)
Shanbag's Blog (ರಜತ ಲೋಕ) (feed)
Wade Chandler's Programming Blog (feed)
Devlin's Lab (feed)
Big Al's Blog (feed)
Code Snakes (feed)
In perfect (spherical) shape (feed)
Van Couvering Is Not a Verb (feed)
Diego Torres Milano's blog (feed)
Vroom Framework (feed)
Messages from mrhaki (feed)
Jeff's Blog (feed)
Manikantan's Netbeans (feed)
Oliver Wahlen's Blog (feed)
Shuttle between Galaxies (feed)
Welcome to my live... (feed)
Netbeans IDE Blog by Tushar Joshi, Nagpur (feed)
Devel Blog (feed)
diamond-powder (feed)
Antonio's blog (feed)
Where's my Blog?!

Powered by:    Planet

Last updated:
September 02, 2015 10:05 PM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
DukeScript - September 02, 2015 11:53 AM
New HTML4J API Version 1.2

NetBeans 8.1 will ship with a new version of the HTML4J APIs we use in DukeScript.

This brings us a couple of new features:

HTTP request headers

The ability to set HTTP request headers when using the OnReceive annotation. The Twitter Demo has been updated to reflect these latest changes in the APIs. Authentication is getting so much simpler through this:

@OnReceive(url = "{root}/tweets.json?{query}", headers = {
        "Authorization: Bearer {bearertoken}"
    })
    static void queryTweets(TwitterModel page, TwitterQuery q) {
         //...
    }

   // used like this:
   model.queryTweets("https://api.twitter.com/1.1/search", sb.toString(), BEARER_TOKEN);

Writable ComputedProperties

It is now possible to have writable computed properties. ComputedProperties depend on other Properties of the model. Until now they were read only. With version 1.2 we can now also write. This allows you to bind an input field to a ComputedProperty and react on changes:

From the API Doc:

@ComputedProperty(write="setPowerValue")
 static int powerValue(int value) {
   return value * value;
 }
 static void setPowerValue(DataModel m, int value) {
   m.setValue((int)Math.sqrt(value));
 }

Firebug support

There is now an easy way to enable Firebug in the General Client for visually debugging the app. Just run with -Dfirebug.lite=true as this video demonstrates.

This way you can enable visual debugging when developing with Eclipse or IDEA. You’ll see a blog post here on how to use this in more detail soon.

In addition to that there were Bugfixes for issues 250503 and 252987.

The new version (1.2) of the APIs is already on Maven Central, so you can start using it right now.

APIDesign - Blogs - September 02, 2015 06:16 AM
HTML/Java version 1.2 has been Released!

Cross platform UI library called HTML/Java API (which is developed by the NetBeans project) is proud to announce that version 1.2 has just been released on Maven central. See javadoc to find out what is new in this version!

The project is also glad that binaries of the new HTML/Java version 1.2 are now included in forthcoming NetBeans 8.1 release making it easy to develop wizards as well as components and dialogs in a cross-platform manner (e.g. able to run in NetBeans platform applications, IDE, Eclipse RCP, plugin-less browser and thanks to adoption by DukeScript project also on iOS and Android).

HTML/Java API is the heart of Java that is written once, and displayed everywhere!

--JaroslavTulach - HTML/Java inventor 06:16, 2 September 2015 (UTC)

markiewb's blog - September 01, 2015 10:05 PM
NB: How to create a context sensitive action within a submenu

Today somebody asked “how create a context sensitive action with a submenu in the project-view?” in the NetBeans mailing list. So I figured it out and I like to document it using this post.

First here is the action for the submenu. The action is registered to the project context menu. It uses the Presenter.Popup interface to register itself as a submenu. In the getPopupPresenter() method the submenu is assembled via Utilities.actionsForPath.

@ActionID(
        category = "MyActions",
        id = "de.markiewb.netbeans.sample.PopupAction"
)
@ActionRegistration(
        displayName = "#CTL_PopupAction", lazy = false
)
@ActionReferences({
    @ActionReference(path = "Projects/Actions")
})
@Messages("CTL_PopupAction=I am a submenu")
public final class PopupAction extends AbstractAction implements ActionListener, Presenter.Popup {

    @Override
    public void actionPerformed(ActionEvent e) {
        //NOP
    }

    @Override
    public JMenuItem getPopupPresenter() {
        JMenu main = new JMenu(Bundle.CTL_PopupAction());
        List<? extends Action> actionsForPath = Utilities.actionsForPath("Actions/MyActions/SubActions");
        for (Action action : actionsForPath) {
            main.add(action);
        }
        return main;
    }
}

In the previous code snippet Utilities.actionsForPath has been used to resolve action(s) at Actions/MyActions/SubActions. Here is a context sensitive action, which is registered at this location.

@ActionID(
        category = "MyActions/SubActions",
        id = "de.markiewb.netbeans.sample.HelloProjectsAction"
)
@ActionRegistration(
        displayName = "#CTL_HelloProjectsAction"
)
@Messages("CTL_HelloProjectsAction=HelloProjects...")
public final class HelloProjectsAction implements ActionListener {

    private final List context;

    public HelloProjectsAction(List context) {
        this.context = context;
    }

    @Override
    public void actionPerformed(ActionEvent ev) {
        JOptionPane.showMessageDialog(null, context.size() + " projects selected: " + context);
    }
}

The result:
SubmenuWithContextSenstiveAction

The complete sample code can be found at https://github.com/markiewb/nb-api-samples/tree/master/SubmenuWithContextSensitiveAction. I will also add this documentation to the offical developer FAQ at http://wiki.netbeans.org/DevFaqActionNodePopupSubmenu

Happy coding!


Geertjan's Blog - September 01, 2015 07:00 AM
"Hack" Font in NetBeans IDE is Great!

A flurry of Tweets a day or so ago re Hack and NetBeans IDE:

John Sirach, from the PiDome project (which won a Duke's Choice Award last year), who started the flurry above and has now introduced the Hack font to the NetBeans community (thanks for that John!), likes this font because it makes code look good even when the font size is small. Here's a screenshot he sent me, with the font size set to 10px:

Here's how it looks for me, I'm using it fulltime now, with font size 18px (nice for teaching and so on), and "Dark Metal" from the "Dark Look and Feel Themes" plugin:

The above is a screenshot that is included in The Complete Guide to Tuning the Appearance of NetBeans.

Get the "Hack" font here: http://sourcefoundry.org/hack/

Adam Bien - September 01, 2015 01:17 AM
NetBeans, SVN, E155021, Problem and Resolution

The error message "E155021: Unsupported working copy format" indicates a version mismatch between the working copy and the svn client version. A repository checked-out with one client might be inaccessible to another SVN client tool.

NetBeans uses SVNKit as the default choice. However, the underlying SVN client in NetBeans can be configured in the Preferences / Options Dialog. E.g. if NetBeans complains, but the command line SVN client works, switch to CLI.

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 31, 2015 12:29 PM
Available: Official PDF of "Beginning NetBeans IDE for Java Developers"

Today I went to the Apress site for the new NetBeans book "Beginning NetBeans IDE for Java Developers". I used PayPal to pay for the PDF, since the hardcopy isn't available yet. I'm really looking forward to holding the hardcopy in my hands, the PDF is definitely secondary to me, though having it available is nice too! When I ordered it today, I assumed that I'd get sent some old version of the PDF of the book, together with the message: "Soon you will receive the final PDF of the book, for the moment here's a recent draft."

However, that was not the case at all! The final PDF of the book is available, right now. That's really great. Features that the final PDF of the book has, which early drafts did not have, and which the hardcopy book obviously will not have, either:

  • Bookmarks, as shown in the screenshot below.
  • Hyperlinks in the table of contents to the referenced pages.
  • Internal links, e.g., when the text says "as shown in Figure 3-2", there's a link on "3-2", which can be clicked, and then you're jumped to the related image.
  • Color in the screenshots, i.e., unlike the hardcopy book, the screenshots are not black/white, except for the awesome portraits of famous NetBeans users by Martien Bos

Here's an image of the book, showing Adam Bien's preface, as well as the bookmarks along the left side of the PDF reader:

And here's the start of the chapter on testing and code coverage, notice the hyperlinks mentioned above.

Get the book here: http://www.apress.com/beginning-netbeans-ide

Adam Bien - August 31, 2015 01:30 AM
A Note On Java EE Testing--Codepot.pl Conference Session Is Available

codepot.pl conference session about pragmatic Java EE testing in continuous coding style.

Also check out the Effective Java EE 7 Workshop (Streaming / Download edition). I used System and Unit Tests throughout the course to increase the pace. Who cares about code coverage? :-)


Real World Java EE Workshops [Airport Munich]>

Adam Bien - August 30, 2015 10:24 AM
My JavaOne 2015 Session Schedule

Conference: JavaOne
Session Type: User Group Forum Session
Session ID: UGF10284
Session Title: Building Nanoservices with Java EE and Java 8
Venue / Room: Moscone South—307
Date and Time: 10/25/15, 18:30 - 19:15

Conference: JavaOne
Session Type: User Group Forum Session
Session ID: UGF10300
Session Title: Being Productive with Maven, Java EE, and the Cloud
Venue / Room: Moscone South—310
Date and Time: 10/25/15, 11:00 - 11:45

Conference: JavaOne
Session Type: BOF (Birds-of-a-Feather) Session
Session ID: BOF1849
Session Title: Most Popular Java (EE) Q&A: Airhacks.tv Live
Venue / Room: Parc 55—Cyril Magnin II/III
Date and Time: 10/26/15, 19:00 - 19:45

Conference: JavaOne
Session Type: Conference Session
Session ID: CON1851
Session Title: From Macro to Micro(Services) and Back: Onstage Hacking with Java EE 7
Venue / Room: Parc 55—Cyril Magnin II/III
Date and Time: 10/26/15, 17:30 - 18:30

Conference: JavaOne
Session Type: Conference Session
Session ID: CON6699
Session Title: What's the Best IDE for Java EE?
Venue / Room: Hilton—Imperial Ballroom A
Date and Time: 10/27/15, 12:30 - 13:30

Conference: JavaOne
Session Type: Conference Session
Session ID: CON1850
Session Title: Nashorn: The “42” for Startups and Enterprises
Venue / Room: Hilton—Continental Ballroom 5
Date and Time: 10/28/15, 10:00 - 11:00

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 30, 2015 07:19 AM
NetBeans in Cancer Research in Pakistan

My background is not in IT, but in law—I grew up in South Africa and did my law degree there, focusing on subjects such as international law, labor law, and human rights law. I would certainly have become one of those typical human rights lawyers who inspired me to do a law degree in the first place—one of those lawyers from 90% of court room drama movies—pleading the innocence of an unjustly accused innocentshaking a self righteous finger at the heavens against the injustice of it allor standing on the ramparts of some eventually to be vindicated—after many years of hardship and struggle"lost cause".

It is with that kind of background that I am always so very pleased when the aspects of NetBeans that have always appealed to me most—free, open source, solid, stable, simple to get started, helpful community—are combined with the kind of vertical segment of software development that is closest to the kinds of concerns I had before being sidetracked into software—in this case, the software being developed at Shaukat Khanum Memorial Cancer Hospital in Pakistan:

The above is a laboratory automation integration solution being created at the aforementioned hospital in Pakistan on top of the NetBeans Platform and with NetBeans IDE. It integrates 63 pathology lab machines and analyzers into one coherent application, supporting a range of protocols. The system bi-directionally communicates with true random access analyzers, such as General Chemistry (e.g., Hitachi P-800, COBAS 6000) and Special Chemistry (e.g., Advia, Immulute), where analyzers read the tube barcodes and inquire the system for the test orders and receives them, analyzes samples, and reports back the results to the system. Other features include user/roles/rights management, integrated simulation for quick testing and debugging, and an easily accessible user interface for maintaining the analyzers and other machines, together with their support documents and manuals.

Many—even most—of my software colleagues will look at the above screenshot and say: "Oh my god! Why is that not a web app!" or "Wow—that needs to be converted to JavaFX, doesn't it?" And those software colleagues would be completely missing the point. Not going to explain this in detail again, have done that so many times already, but the web is simply not applicable to all imaginable business scenarios, while Java Swing is certainly a lot more stable with a lot more experienced developers available than JavaFX, and the usefulness that JavaFX would add to this particular application is so small that the significant investment that would be required would not be worth it.

When I read about the above software and write e-mails with the related software developers working in that hospital, to advise them on solutions they're working on for their software, yes, at that moment there's a very small and humble part of me that resonates with an earlier part of me, a younger part, sitting in a law lecture or, even, quite recently, listening to former head of the South African Constitutional Court, Albie Sachs, talk about his background and the motivations for the ways in which he has spent his life.

Geertjan's Blog - August 28, 2015 01:18 PM
YouTube: Overview of Newly Designed NetBeans Profiler

The redesign of the NetBeans Profiler is one of the big enhancements of the NetBeans IDE 8.1. In the release notes, you'll see a whole section dedicated to this:

  • Redesigned user interface
  • New features:
    • Live forward and reverse call trees in CPU results
    • Live allocation trees in Memory results
    • Monitoring CPU utilization
    • Thread dumps from profiled application
  • Engine improvements:
    • Faster connection to profiled application
    • Limited outgoing calls from profiled methods
    • Memory profiling for selected classes
  • Simplified profiler setup
  • Improved integration into the IDE

And, great newstoday, Josh Juneau, a NetBeans Dream Team member, has made available an excellent screencast on YouTube showing how friendly and usable the newly designed NetBeans Profiler is:

Thanks, Josh!

DukeScript - August 28, 2015 11:53 AM
New NetBeans Plugin 1.5

We’re happy to announce a new version of the NetBeans Plugin for developing DukeScript. The new Version (1.5) utilized new features of NetBeans 8.1 to allow on-device debugging of Android apps.

It also provides more intelligent code completion for knockout. Inside the data-bind attribute of an element code completion now offers you functions and Properties of your model:

To install the plugin go to Tools -> Plugins and select “DukeScript Project Wizard” in the list of available plugins. NetBeans will guide you through the installation.

DukeScript - August 28, 2015 09:54 AM
Links of the week

This week was quite a busy one:

  • NetBeans 8.1-beta was released. We’ve been eagerly waiting for this to publish our new NetBeans Plugin.

  • We published a new tutorial on how to deploy the CRUD-demo to Wildfly.

  • There’s a new comprehensive article on DukeScript at JavaCodeGeeks.

  • DukeScript also made it on the title of JavaSpektrum (a german magazine). You can get the PDF here.

  • Toni has started working on a first book about DukeScript.

  • He also made a short demo video of the upcoming integration of firebug-lite for users of Eclipse and IDEA

  • The Twitter Demo has been updated to reflect the latest changes in the APIs. Authentication is getting so much simpler.

  • Geertjan Wielenga has written an article comparing DukeScript and Vaadin.

Have a nice weekend and stay tuned for next weeks exiting updates :-)!

Adam Bien - August 28, 2015 09:36 AM
Rulz For EntityManager v0.0.2 and Rulz For JAX-RS Released v0.0.3

New releases of Rulz EntityManager and Rulz JAX-RS are available in maven central.

JAX-RS provider comes with three custom matchers (successful(), noContent() and created()):


import static com.airhacks.rulz.jaxrsclient.HttpMatchers.successful;

public class JAXRSClientProviderTest {

    @Rule
    public JAXRSClientProvider provider = JAXRSClientProvider.buildWithURI("http://www.java.com");

    @Test
    public void pingJavaAndVerifyWithMatcher() {

        Response response = (...)
        assertThat(response, is(successful()));
    }


Now the whole library comprises 2 classes...

The Rulz For EntityManager comes with no additional features -- just a superfluous persistence.xml was removed from the project.

See Rulz in episode 5 in the online version of the Effective Java EE 7 workshop.


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 27, 2015 07:00 AM
New: Complete Guide to Tuning the Appearance of NetBeans

The full article is here and will be added to and updated over time and should be considered the most complete and authoritative document on the topic of tuning the appearance of NetBeans:

https://jaxenter.com/netbeans/the-complete-guide-to-tuning-the-appearance-of-netbeans

DukeScript - August 26, 2015 09:53 AM
CRUD Example with Wildfly

This blog post is an answer to a question recently asked in the DukeScript Forum. The question is about our CRUD archetype, which contains a very simple Jersey based REST Server: “How do you suggest I deploy my web application to the Wildfly Application server?” Since this is not the first time I’ve been asked this question, I thought it’s worth a little tutorial.

I’m using NetBeans 8.0.2 with the latest version of the DukeScript Plugin and WildFly 8.2.0 for this. I’m assuming you have already created a project using the CRUD Archetype.

The purpose of our Jersey sample is to show how you can interact with a server via JSON messages. So the only purpose of the server module is to answer the requests from the client. For a more traditional setup you can simply create a more traditional web project, e.g. using the Maven Web Application project template.

In the Parent Project, right-click “Modules” and select “Create New Module” from the Context Menu. In the wizard that pops up choose “Maven -> Web Application”. In the second step you can select a server. Choose Wildfly here. If it’s not in the drop down list, click add and point it to the Wildfly dir. Then confirm the settings and finish the Wizard.

Now use “New -> Web Services -> Restful WebService from pattern” and create a Singleton Web Service. This is only needed to configure the project for Web Services. You can delete the class you just created after that. Now add the following class to your project:

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    /**
     * Do not modify addRestResourceClasses() method.
     * It is automatically populated with
     * all resources defined in the project.
     * If required, comment out calling this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(fully.qualified.path.to.ContactsResource.class);
    }
    
}

Now copy the ContactsResource to the new project and delete the old server project. Make sure to add the project with „Shared Client Server Data Structures“ as a dependency, so you can again reuse the data model. If you’re using NetBeans you’ll now see the ContactsResource in the IDE under the „Restful Web Services Node“. That’s it, you can now start the server and point the client to this more traditional Web Application.

Geertjan's Blog - August 26, 2015 07:54 AM
New from Apress: "Beginning NetBeans IDE for Java Developers"

Well, yesterday I heard the good news—the new Apress book "Beginning NetBeans IDE for Java Developers" has gone to the printer! This ends a cycle that started some months ago, with many in the NetBeans community being involved. Several people from the NetBeans Dream Team, as well as teachers using NetBeans around the world, and some of the subscribers on the NetBeans mailing list.

Here's where the book can be purchased: http://www.apress.com/beginning-netbeans-ide?gtmf=s

Some sneak previews are in order! Here's what the cover looks like:

Here's the more readable version of the small squiggly text you see on the back of the book above:

Of course, the book is focused on NetBeans IDE 8.1, e.g., the newly designed NetBeans Profiler is used in the chapter on Profiling. What does the table of contents look like? Here it is:

It's a reasonably thorough introduction to NetBeans IDE, though there's certainly room for another book on NetBeans IDE to be entitled "The Definitive Guide to NetBeans IDE", as well as another book in the "Beginning" series, e.g., "Beginning NetBeans IDE for JavaScript Developers".

The foreword is by Jaroslav Tulach and the preface is by Adam Bien. Each chapter begins with a relevant quote from a famous NetBeans user, and a portrait of that user by the brilliant professional illustrator Martien Bos, e.g., the chapter on Profiling begins with a portrait of Kirk Pepperdine, with a quote from Kirk about how awesome the NetBeans Profiler is. Similarly, Arun Gupta is featured in the chapter where you develop a Java EE application, while others included include James Gosling, Toni Epple, Zoran Sevarac, Sean Phillips, Sven Reimers, and Ken Fogel.

The book is aimed at students at universities and technical colleges, etc, (in fact, it would be great if it would become something of a standard text at educational institutions) as well as developers in the enterprise. In the book, Maven and, to some extent as well, Java EE, are a bit dominant, though if you're using something different, you'll gain a lot from the book too. Initially an Ant-based "Hello World" application is created, later a more complex Java EE application with Maven, though each chapter stands on its own. By the end, you have a basic overview of the key features of NetBeans IDE.

More info about this book will be revealed over the coming weeks/months, including interviews with some of the many people involved in the book, and, of course, it will play a big role in a variety of activities around NetBeans as soon as it is released!

DukeScript - August 25, 2015 09:53 AM
CRUD Example with Wildfly

This blog post is an answer to a question recently asked in the DukeScript Forum. The question is about our CRUD archetype, which contains a very simple Jersey based REST Server: “How do you suggest I deploy my web application to the Wildfly Application server?” Since this is not the first time I’ve been asked this question, I thought it’s worth a little tutorial.

I’m using NetBeans 8.0.2 with the latest version of the DukeScript Plugin and WildFly 8.2.0 for this. I’m assuming you have already created a project using the CRUD Archetype.

The purpose of our Jersey sample is to show how you can interact with a server via JSON messages. So the only purpose of the server module is to answer the requests from the client. For a more traditional setup you can simply create a more traditional web project, e.g. using the Maven Web Application project template.

In the Parent Project, right-click “Modules” and select “Create New Module” from the Context Menu. In the wizard that pops up choose “Maven -> Web Application”. In the second step you can select a server. Choose Wildfly here. If it’s not in the drop down list, click add and point it to the Wildfly dir. Then confirm the settings and finish the Wizard.

Now use “New -> Web Services -> Restful WebService from pattern” and create a Singleton Web Service. This is only needed to configure the project for Web Services. You can delete the class you just created after that. Now add the following class to your project:

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    /**
     * Do not modify addRestResourceClasses() method.
     * It is automatically populated with
     * all resources defined in the project.
     * If required, comment out calling this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(fully.qualified.path.to.ContactsResource.class);
    }
    
}

Now copy the ContactsResource to the new project and delete the old server project. Make sure to add the project with „Shared Client Server Data Structures“ as a dependency, so you can again reuse the data model. If you’re using NetBeans you’ll now see the ContactsResource in the IDE under the „Restful Web Services Node“. That’s it, you can now start the server and point the client to this more traditional Web Application.

Geertjan's Blog - August 25, 2015 08:31 AM
Kendo UI Core in NetBeans IDE 8.1

Good news for users of Kendo UI Core, everywhere. Problems in the initial release of the Kendo UI Core plugin have been fixed and, if you're using NetBeans IDE 8.1 Beta (or later), you'll have code completion for Kendo UI Core components, together with documentation, once the plugin is installed:

But... there's more! In code completion, in the place where you'd expect it, you also get code completion for the attributes of the currently used Kendo UI Core component, together with related documentation:

When you're using Visual Studio, you'll miss the above feature, i.e., context-sensitive code completion of attributes of Kendo UI Core components, since it's simply not supported fully or completely or correctly there:

Go here to get the plugin:

http://plugins.netbeans.org/plugin/60071/kendo-ui-core-editor

Many thanks to a variety of people involved in working on and supporting the Kendo UI Core Editor plugin for NetBeans IDE. In the first place, Johan Borchers for suggesting this feature for NetBeans IDE and also for trying it out multiple times, until we fixed the issues we initially had and now it works for him too in NetBeans IDE 8.1. Giorgio Del Cielo, thanks to you too, for trying out the plugin and reporting that it now works for you. Also, very many thanks to the Brazil team who worked on the documentation parsing of the Kendo UI Core Editor plugin during JavaOne Latin America, consisting of Mauricio Leal, Leonardo Zanivan, and All Pereira.

Many thanks to everyone. And there's still quite some work to be done, especially in the performance and caching of parsing results, i.e., these aspects are not optimal yet. Anyone wanting to get involved, there's a GitHub repo that contains all the code:

https://github.com/GeertjanWielenga/KendoNetBeans

Anyone using the plugin, please help by providing any kind of feedback, either here or on the plugin's page in the Plugin Portal.

Adam Bien - August 25, 2015 04:29 AM
Java EE 7: Sending JSON Objects Over WebSockets

Java EE 7 and particularly JSR 356: Java API for WebSockets supports Encoders to serialize any custom object into WebSocket stream. With JSR 353: Java API for JSON Processing the conversion between JsonObject instances and streams is straightforward:


import java.io.IOException;
import java.io.Writer;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonWriter;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;

public class JsonEncoder implements Encoder.TextStream<JsonObject> {

    @Override
    public void init(EndpointConfig config) {}

    @Override
    public void encode(JsonObject payload, Writer writer) throws EncodeException, IOException {
        try (JsonWriter jsonWriter = Json.createWriter(writer)) {
            jsonWriter.writeObject(payload);
        }
    }

    @Override
    public void destroy() {}
}


The Encoder instance needs to be registered with the @ServerEndpoint annotation:


[...]
@ServerEndpoint(value = "/changes", encoders = {JsonEncoder.class})
public class ToDoChangeTracker {

    private Session session;

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
    }

    @OnClose
    public void onClose() {
        this.session = null;
    }

    public void onToDoChange([...]) throws EncodeException {
        if (this.session != null && this.session.isOpen()) {
            try {

                JsonObject event = Json.createObjectBuilder().
                        add("name",[...]).
                        build();
                this.session.getBasicRemote().sendObject(event);

            } catch (IOException ex) {
                //we ignore this
            }
        }
    }

}

This example was taken from the 38th episode of the Effective Java EE Online Workshop. Sources are available from github.com/AdamBien/doit


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 24, 2015 09:36 AM
YouTube: Chrome Connector Plugin in NetBeans IDE 8.1

One of the best features for JavaScript development in NetBeans IDE is the Chrome Connector plugin, which connects the browser to NetBeans IDE and enables the Chrome browser—whether on the desktop or on a mobile deviceto integrate fully into the development cycle.

NetBeans IDE 8.1, which is currently in Beta, has some awesome enhancements for working with the Chrome browser via the Chrome Connector plugin. In particular, Polymer is supported for the first time via live Shadow DOM visualization and Knockout.js is even further integrated into the development cycle via a new window that shows live Knockout bindings of the currently selected item in the Chrome browser.

Find out all about the new features, plus a few additional handy tips and tricks, in a brand new YouTube screencast, here:

Watch more NetBeans videos here: https://www.youtube.com/user/NetBeansVideos

Adam Bien - August 23, 2015 04:08 PM
From #2 To #1: Java Stronger In The Lead

Java gained 4.29% on popularity in one year and now Java is leading again the Tiobe programming language index. Seems like Java is not only hot on github... Also an interesting observation:

"[...]Surprisingly or may be not, Java is consuming a large part of the market share that Objective-C is losing, while Objective-C's successor Swift was supposed to do this [...]"
From: [Tiobe Index for August 2015]

Big thanks to Samuel Santos @samaxes for the hint.


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 21, 2015 08:31 AM
Hello Perforce in NetBeans IDE

Figured out how to add the Perforce item below:

How to do it:

https://github.com/GeertjanWielenga/perforce

Below is the starting point, in the layer.xml, included in the Git repo above:

<folder name="VersioningOptionsDialog">
    <file name="Perforce.instance">
        <attr name="instanceClass" stringvalue="org.netbeans.perforce.PerforceAdvancedOption"/>
    </file>
</folder>

The rest follows from there, see the Git repo above that contains the entry point for configuring Perforce in NetBeans IDE.

Related info:

Adam Bien - August 21, 2015 04:52 AM
JUGs, Conferences and (Streaming) Events

  1. August, 28th, 12:45 pm, Free Live Streaming: "A Note On Java EE Testing" for codepot.pl conference.
  2. September, 3rd, Zurich, Workshop: "Genug ASCII-User Interfaces mit Java EE 7"
  3. September, 14th, 6 pm (CET) Airhacks Live Questions and Answers streaming show. Ask questions now. Also see: archives
  4. September, 16th, evening: free Session: "Java EE 7 — Simply The Best". Stay tuned
  5. September, 17th, evening. Fee JUG Streaming session for JUG Gothenborg. Stay tuned.
  6. October, 6th, 9am, Hannover, Java Forum Nord, Conference Keynote
  7. October 25–29, 2015, San Francisco, JavaOne Conference. Sessions: From Macro to Micro(Services) and Back: Onstage Hacking with Java EE 7 [CON1851], Most Popular Java (EE) Q&A: Airhacks.tv Live [BOF1849], Nashorn: The “42” for Startups and Enterprises [CON1850], Being Productive with Maven, Java EE, and the Cloud [UGF10300], Building Nanoservices with Java EE and Java 8 [UGF10284], What's the Best IDE for Java EE? [CON6699]
  8. November, 3rd, Munich, w-jax conference. Sessions: "Enterprise Scripting mit Nashorn: Tipps & Tricks live on Stage" and "Transactions? ACID, XA, BASE or what?"
  9. December 7th-11th. Airhacks Java EE Workshops at MUC Airport. If Munich is too far, try the streaming or download version: Effective Java EE

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 21, 2015 12:15 AM
Overriding Default Context-Sensitive Action Enablement

By default, when you create an Action that is context sensitive, via the New Action wizard, the NetBeans Platform looks out for the types that are of interest to you and, when they're in the Lookup, enables your Action. In the case below, when multiple Parts are in the Lookup, i.e., typically, multiple PartNodes are selected and their underlying Part objects are published, the Action will automatically be enabled:

@ActionID(
        category = "Parts",
        id = "org.car.viewer.PartComparatorAction"
)
@ActionRegistration(
        displayName = "#CTL_PartComparatorAction"
)
@ActionReference(
        path = "Menu/File", 
        position = 1200)
@Messages("CTL_PartComparatorAction=Compare Parts")
public final class PartComparatorAction implements ActionListener {
    private final List<Part> context;
    public PartComparatorAction(List<Part> context) {
        this.context = context;
    }
    @Override
    public void actionPerformed(ActionEvent ev) {
        StringBuilder sb = new StringBuilder();
        for (Part part : context) {
            sb.append(part.getName()).append(" ");
        }
        StatusDisplayer.getDefault().setStatusText(sb.toString());
    }
}

However, the default behavior is such that even when only one Part object is exposed to the Lookup, the Action is enabled, as shown below:

The above doesn't really make sense because you need more than one of something to make it worthwhile to compare. To override this default behavior, you can abandon the default underlying class and implement your own enablement strategy.

Begin by including "lazy = false", shown in bold below, which will generate layer.xml entries that, instead of delegating to the internal NetBeans Platform code for handling enablement, lets you provide that enablement yourself, as shown here:

@ActionID(
        category = "Parts",
        id = "org.car.viewer.PartComparatorAction"
)
@ActionRegistration(
        lazy = false,
        displayName = "NOTUSED"
)
@ActionReference(
        path = "Menu/File",
        position = 1200)
@Messages("CTL_PartComparatorAction=Compare Parts")
public final class PartComparatorAction extends AbstractAction {
    Lookup context;
    public PartComparatorAction() {
        context = Utilities.actionsGlobalContext();
        putValue(NAME, Bundle.CTL_PartComparatorAction());
    }
    @Override
    public boolean isEnabled() {
        return context.lookupAll(Part.class).size() > 1;
    }
    @Override
    public void actionPerformed(ActionEvent ev) {
        StringBuilder sb = new StringBuilder();
        for (Part part : context.lookupAll(Part.class)) {
            sb.append(part.getName()).append(" ");
        }
        StatusDisplayer.getDefault().setStatusText(sb.toString());
    }
}

Now, as is implied by the isEnabled method above, only when more than one object of interest is in the Lookup, will the Action be enabled. Below you can see that, in contrast to the earlier screenshot, the Action is disabled here because of the code above, which overrides the default behavior:

Note that in the second code scenario, you get hold of the Lookup yourself, you check whether the correct objects are available in the Lookup and then enable/disable as appropriate, and you also iterate through the objects in the Lookup to process them when the Action is invoked. In the default scenario, all this is done for you automatically, with the downside that even when only one object is available the Action will be enabled.

Also see:

Adam Bien - August 20, 2015 07:27 AM
Cool Kids Are Using Java

Java started slow, but is gaining momentum:

Java trend on github

From: Language Trends on GitHub, big thanks to @Stkoelle for the hint!
Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 19, 2015 03:09 AM
Complex Properties Windows on the NetBeans Platform (Part 2)

In part 1, you ended up removing the UI components from the custom Properties window whenever the Lookup changes. That's kind of messy and here's an alternative approach, where you repopulate the custom Properties window instead of recreating its UI components.

public class PlanetPropertiesTopComponent extends TopComponent
        implements LookupListener {

    private Lookup.Result<PlanetNode> planetNodeResult;
    private final JPanel mainPanel;
    private boolean isInitialized = false;

    public PlanetPropertiesTopComponent() {
        setName(Bundle.CTL_PlanetPropertiesTopComponent());
        setLayout(new BorderLayout());
        mainPanel = new JPanel(new MigLayout());
        JLabel title = new JLabel();
        add(title, BorderLayout.NORTH);
        add(mainPanel, BorderLayout.CENTER);
    }

    @Override
    public void resultChanged(LookupEvent le) {
        if (!planetNodeResult.allInstances().isEmpty()) {
            PlanetNode planetNode
                    = planetNodeResult.allInstances().iterator().next();
            if (!isInitialized) {
                initializeContent(planetNode);
            } else {
                repopulateContent(planetNode);
            }
        }
    }

    private void initializeContent(PlanetNode planetNode) {
        writeTabDisplayName(planetNode);
        List<Property> booleanProperties = new ArrayList<Property>();
        PropertySet ps = planetNode.getPropertySets()[0];
        Property<?>[] props = ps.getProperties();
        for (Node.Property property : props) {
            SinglePropertyJPanel ppJPanel
                    = new SinglePropertyJPanel(property);
            if (property.getValueType().equals(boolean.class)) {
                booleanProperties.add(property);
            } else {
                mainPanel.add(
                        ppJPanel,
                        "dock north, wrap, growx, pushx");
            }
        }
        mainPanel.add(
                new MultiPropertyJPanel(booleanProperties),
                "wrap, growx, pushx");
        revalidate();
        isInitialized = true;
    }

    private void repopulateContent(PlanetNode planetNode) {
        writeTabDisplayName(planetNode);
        PropertySet ps = planetNode.getPropertySets()[0];
        Property<?>[] props = ps.getProperties();
        for (Node.Property property : props) {
            Component[] components = mainPanel.getComponents();
            for (Component component : components) {
                if (component instanceof SinglePropertyJPanel) {
                    SinglePropertyJPanel spjp = (SinglePropertyJPanel) component;
                    PropertyPanel pp = spjp.getPropertyPanel().get(0);
                    String ppDisplayName = pp.getProperty().getDisplayName();
                    if (ppDisplayName.equals(property.getDisplayName())) {
                        pp.setProperty(property);
                    }
                } else
                if (component instanceof MultiPropertyJPanel) {
                    MultiPropertyJPanel mpjp = (MultiPropertyJPanel) component;
                    List<PropertyPanel> ppList = mpjp.getPropertyPanel();
                    for (PropertyPanel pp : ppList) {
                        String ppDisplayName = pp.getProperty().getDisplayName();
                        if (ppDisplayName.equals(property.getDisplayName())) {
                            pp.setProperty(property);
                        }
                    }
                }
            }
        }
    }

    private void writeTabDisplayName(PlanetNode planetNode) {
        String displayName = planetNode.getDisplayName();
        setDisplayName(displayName + " - Properties");
    }

    @Override
    public void componentOpened() {
        planetNodeResult
                = Utilities.actionsGlobalContext().lookupResult(PlanetNode.class);
        planetNodeResult.addLookupListener(
                this);
    }

    @Override
    public void componentClosed() {
        planetNodeResult.removeLookupListener(this);
    }

}

Adam Bien - August 18, 2015 01:43 PM
Running JavaFX On Mobile Devices With Gluon And Afterburner

Johan, could you please briefly introduce yourself? Why do you like JavaFX?

I am a Java developer, working with Java since it was released. From day 1, I was interested in running Java on small devices. When Enterprise Java started to become popular, my interest moved into combining the world of the small devices with the world of the large back-end systems. Today, that translates into combining JavaFX on embedded, mobile and desktop with Java EE and Cloud systems.

I think JavaFX is important to many Java Enterprise developers. At this moment, many Java Enterprise developers are using a framework to create web pages, based on the business functionality they have to provide. However, there is a clear evolution towards mobile. People and also companies are today rather using mobile devices (phones and tablets) instead of desktops and laptops to do their job.
On mobile, native apps are much more valued than sites that are viewed via a web browser. Hence, most of the business transactions in the future will start from native mobile applications.
Good enough, JavaFX is a perfect platform for writing native mobile applications. And that is great news for all those Java Enterprise developers! They can use their favorite Java language, and still address the future (mobile) needs of their customers. Moreover, thanks to the cross-platform functionality of JavaFX, their client application works on all mobile devices. There is no need to write different versions of the business logic, but there is also no need to write different versions of the user interface. It is really easy to create and to maintain a JavaFX client application that is truly and completely cross-platform.

You ported afteburner.fx to mobile. Was it hard?

No, that was easy. Afterburner.fx is well-structured and uses a few classes only. Also, JavaFX 8 on mobile supports almost the entire JavaFX 8 API. Since JavaFX applications currently run on top of Dalvik, though, we can not use the Stream API's and I had to replace those Java 8 API's with Java 7 API's.

How did you find afterburner? Why do you decided to use it?

There are a number of ideas on how to use enterprise functionality in JavaFX and it is not easy to find the perfect balance between known and trusted enterprise patterns on one side, and client restrictions on the other side. In general, I think developers have to realize that even though client CPU's might be very performant, there are still huge differences between server environments (in a cloud or dedicated datacenter) and client systems.
Afterburner provides an excellent mix, as it allows for Injection to be used, without the need of a complex framework. It is probably the simplest yet functional MVP framework for JavaFX. For server-side projects, I'm always very cautious to not include external dependencies that are not really needed. On the client, I'm even more careful about this.
The Afterburner framework is very small, but it can easily be extended for specific needs. This is important on clients in general, and mobile clients in particular.

What is gluonhq.com? How afterburner is related to gluonhq.com?

I earlier said that JavaFX provides an excellent platform for Java developers to create Java clients applications that work on all kinds of client, and that provide the business functionality that in the past would exclusively be offered via a web interface. While JavaFX is really great, there are a number of issues Java Enterprise developers will probably encounter. With Gluon, we are trying to fill this gap.
Gluon provides products and services for Java Client development. Our tools extend the JavaFX functionality, and bring it to the world of mobile clients as well. JavaFX, which essentially is the standard Java Component for Java on the Client, provides a great set of API's for creating and managing user interfaces. The Gluon products extend this functionality in two directions:

  • With Charm, our client library, it becomes easy to create compelling user interfaces that look excellent on mobile devices, as Charm provides a Material Design look and feel. Also, Charm provides the client API to synchronize data across clients, and to store data remotely in a JavaFX friendly way (by leveraging concepts as Observable, and taking into account the Threading issues that might occur in a JavaFX application)
  • With Gluon Cloud, we manage the data that needs to be stored or synchronized. Gluon Cloud connects client devices with each other, with its persistent storage, or with customer-specific enterprise systems or cloud providers.

What was your coolest Java EE project?

That is a very difficult question, as Enterprise Java changed considerable over the past years. Today, Java EE development is much smoother and easy than it used to be. I do remember we did a large scale voting application in 2010, with thousands of concurrent users. This was our first large-scale deployment of GlassFish on Amazon EC2 infrastructure. It was really exciting to watch Google Analytics Real-Time and see how the number of concurrent users went up while the 2 GlassFish instances were holding fine.

What was your coolest Java FX project?

We have a number of really cool customer projects that I am not allowed to discuss, unfortunately. Apart from the Gluon products we are developing, we have this nice kiosk application we created for CultuurNet Vlaanderen. We run a JavaFX application on an embedded device with an NFC reader, and when people swipe their card, we send this to a back-end. The monitoring of these devices is also done by a JavaFX application we created.
We have a number of similar, form-based applications that we are working on for customers that want to use mobile devices for their employees.
Another cool project we are currently working on, is based on OpenMapFX. For a customer, we provide location-based functionality on top of the geo-maps that are rendered by OpenMapFX.

Any resources, links, ideas you can share with us?

I really recommend Java Enterprise developers to create a simple mobile JavaFX Application, and connect that to their backend system. Gluon currently provides plugins for NetBeans and IntelliJ to make this JavaFX development really easy -- see http://docs.gluonhq.com/charm/latest/#_ide_plugins for more information.
Developers that are interested in creating JavaFX Applications on mobile should have a look at javafxports.org.
People can find everything on Gluon on our website gluonhq.com. Keep an eye on our news section, as we are constantly announcing new stuff.

Johan, thank you for the interview!


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 17, 2015 08:42 AM
Java Everywhere: Write Once Run Anywhere with DukeScript

For quite some time already, Java has been failing on its “write once, run anywhere” promise. DukeScript (DukeScript.com) would like to change that by enabling a clean separation of view and logic in cross-platform applications. In this article, a simple scenario is used to introduce the basics of DukeScript.

For many years, Java Swing enabled developers to write applications that could run on any operating system. That all came to an end with the arrival of smart phones, tablets, and embedded computers. In the enterprise, the desktop dominated for many years. In the meantime, however, every IT project includes plans for a future where the application will need to be ported to mobile platforms. Building native applications for all platforms requires special skills and is expensive in terms of both maintenance and development. What is to be done?

DukeScript gives you a Java-based solution again that enables cross-platform applications to be developed. DukeScript provides a clean separation of view and logic enabling UI designers to focus on UI design and coders to focus on writing well-tested application code. 

Read all about it here, which is where the paragraphs above come from: http://www.javacodegeeks.com/2015/08/java-everywhere-write-once-run-anywhere-with-dukescript.html and learn how to create a cross-platform To Do List application:

Adam Bien - August 17, 2015 04:30 AM
Effective Java EE Workshop Available For Streaming And Drm-Free Download

4 hours of Effective Java EE Workshop "On Demand" or 42+ videos are available for streaming and drm-free download.

During the workshop I'm building a "ToDo / Reminders" app with focus on productivity, design and pragmatism covering: Maven, BCE structure, testing (unit, integration and system-tests), JAX-RS, Bean Validation, JSF, JPA, WebSockets, exception handling, monitoring, CDI and EJB.

Any questions left? Then see you at each first Monday of the month at 6 P.M. live.

Also see you in person at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting


Real World Java EE Workshops [Airport Munich]>

DukeScript - August 16, 2015 09:53 AM
Simple Routing with DukeScript

If you’re using DukeScript for Web based applications, you might be interested in allowing users to use bookmarks and history to navigate your app. Here’s a very minimal example showing how to add that to an application.

First I created a new application named “routing” using the DukeScript wizard. I selected “Run in a Browser” as the target platform and the “Knockout 4 Java Maven Archetype” (without sample code).

This creates three Maven projects. We’ll first have a look at the “routing JavaScript Libraries”. In order to use knockout for the routing, we need to create a custom binding. This will allow us later to track the current active subpage in our viewmodel. First I deleted Dialog.java and it’s unit Test, because we won’t need that. Next I created a JavaScript file (‘com/dukescript/demo/routing/js/registerRouter.js’) in the resources directory:

window['ko']['bindingHandlers']['route'] = {
    'init': function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var callback = valueAccessor();
        window['onhashchange'] = function () {
            var url = location.hash.slice(2);
            callback(url);
        };
    }
};

This registers a new binding called “route”. We’ll use that in our html-page. In order to execute the JavaScript at the correct time I’ll also create a Java class (com/dukescript/demo/routing/js/Router.java):

@JavaScriptResource(value = "registerRouter.js")
public final class Router {

    private Router() {
    }

    @JavaScriptBody(
            args = {}, body
            = ""
    )
    public static native String registerBinding();
}

The JS-File will be loaded when I first call a method on this class. That’s it for the Custom Binding, lets forget about our short encounter with JavaScript and wash our hands in pure Java!

In the “routing General Client Code” I added a Property to the DataModel to track the route:

@Model(className = "Data", targetId="", properties = {
    @Property (name = "page", type = String.class)
})
final class DataModel {
    private static Data ui;
    //....
}

Also in the onPageLoad method I registered our new binding:

@Model(className = "Data", targetId="", properties = {
    @Property (name = "page", type = String.class)
})
final class DataModel {
    private static Data ui;
    /**
     * Called when the page is ready.
     */
    static void onPageLoad() throws Exception {
        ui = new Data("page1");
        Models.toRaw(ui);
        Router.registerBinding();
        ui.applyBindings();
    }
}

The call Models.toRaw(ui) initializes knockout, we need to do that before registering the binding. The View Model is ready. Now we can code the view (index.html):

<!DOCTYPE html>
<html>
    <head>
        <title>Routing Demo</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body data-bind="route: page">
        <ul>
            <li><a href="#/home">Home</a></li>
            <li><a href="#/page1">Page 1</a></li>
            <li><a href="#/page2">Page 2</a></li>

        </ul>

        <div data-bind="template: { name: page }"></div>

        <script type="text/html" id="home">
            <h3 >Home</h3>
            
        </script>
        <script type="text/html" id="page1">
            <h3 >Page 1</h3>
            
        </script>
        <script type="text/html" id="page2">
            <h3 >Page 2</h3>
            
        </script>
        
       
        <!-- ${browser.bootstrap} -->

    </body>
</html>

In the “body”-Element I bind the page property of DataModel with the route binding. This is how the changes of the location hash are synchronized with our model. Now we can use that property to control what page is displayed. That’s a nice usecase for knockout templates. We can model each page as a separate template and reference them via their id.

A “div”-Element will display a template depending on the page-Property. The knockout directive for this is ‘data-bind=”template: { name: page }”’.

The last step is to define the templates. Our custom binding removes the leading “#/” from the location hash, so we can use a simple string as the id or name of the template. I have defined 3 templates. Each of them displays a different heading.

That’s it. You can now navigate the page via the bookmarkable links on top of the page.

If you want to play with this, as always the demo project is available on github.

Have fun with DukeScript!