X

Geertjan's Blog

Recent Posts

Oracle JET

Oracle as an Agent of Social Change

Together with my colleague JB Brock I've spent the past week in South Africa. Last year, with Andrejus Baranovskis from Oracle partner Red Samurai Consulting, I did something similar—introducing Oracle's new modern vision on application development and user interface design to a range of Oracle partners and customers, including to Oracle staff in the the local Oracle offices, too.  A pic of a few of them is below, taken in Cape Town, Johannesburg, and Pretoria. Just like the last trip, we had 4 or 5 engagements per day, for a week, covering partner visits, workshops, and internal Oracle knowledge sharing sessions. We visited Oracle partners and customers involved in a variety of industries, including insurance, finance, education, and logistics. In each case, we introduced Oracle's application development vision, focusing on Oracle JET, Visual Builder Cloud Service, and Developer Cloud Service, while also referring to related PAAS technologies, such as Mobile Cloud Service, Java Cloud Service, and Application Container Cloud Service. What struck me more than anything is that, in South Africa, IT is seen as an agent of social change. For example, we spent time with Steltix and Project codeX, who have done great work raising the skills level of South African youth: Also, did you know that ten years ago, Nelson Mandela asked Oracle to build a school in one of Johannesburg’s poorest townships? Take a look here: Isn't that inspiring? Really amazing to be working in an organization that makes such an impact in South Africa.

Together with my colleague JB Brock I've spent the past week in South Africa. Last year, with Andrejus Baranovskis from Oracle partner Red Samurai Consulting, I did something similar—introducing...

My OpenWorld/JavaOne 2017 Session Schedule

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Times New Roman'; color: #333333; min-height: 18.0px} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Times New Roman'; color: #333333} span.s1 {font-kerning: none} In most cases, I'm speaking with one or more others in the below.   Sunday, 1 October   SUN4389: Oracle JavaScript Extension Toolkit: How and Why Organizations Use It Room: Marriott Marquis (Yerba Buena Level) - Salon 13 When: 15:45 - 16:30 Monday, 2 October   CON3935: Getting Started with Oracle JavaScript Extension Toolkit Room: Moscone West - Room 3001 When: 11:00 - 11:45   CON6063: Java Versus JavaScript for the Enterprise? Room: Moscone West - Room 2007 When: 12:15 - 13:00   14:00 Meeting   15:30: Code Online Interview about Open Source with Jim Grisanzio   16:00 - 18:00: Booth   18:00 JCP Party Tuesday, 3 October   HOL2103: Get Your Hands Dirty with Oracle JavaScript Extension Toolkit Room: Hilton San Francisco Union Square (Lobby Level) - Plaza Room B When: 10/03/17 — 09:45 - 10:45   CON6269: JavaScript Libraries: Which Ones for Your Project? Room: Moscone West - Room 2003 When: 10/03/17 — 13:15 - 14:00   16:30: DevLIVE Interview: Getting Started with Oracle JavaScript Extension Toolkit   19:00 - 21:00 Team Dinner Wednesday, 4 October   CON3643: RIA Technologies and Frameworks Panel Room: Moscone West - Room 2008 When: 10/04/17 — 10:45 - 11:30   Build Web, Mobile, & Desktop Apps Room: Moscone West - Room 2003 When: 10/04/17 — 11:45 - 12:30   12:15 - 14:30: Booth   CON5168: Java Desktop in the Wild for Science and Analysis Room: Moscone West - Room 2008 When: 10/04/17 —  14:45 - 15:30   CON5172: JavaScript: Does It Make Sense In Large Web and Mobile Apps? Room: Moscone West - Room 2012 When: 10/04/17 — 16:30 - 17:15   CON4102: Ground Systems for the NASA James Webb Space Telescope Using the Java Platform Room: Moscone West - Room 2008 When: 17:30 - 18:1

In most cases, I'm speaking with one or more others in the below.   Sunday, 1 October   SUN4389: Oracle JavaScript Extension Toolkit: How and Why Organizations Use ItRoom: Marriott Marquis (Yerba Buena...

Oracle JET

jquery-stockquotes and Oracle JET

Here's https://github.com/ajwhite/jquery-stockquotes integrated into an Oracle JET application: Steps: Somehow download https://github.com/ajwhite/jquery-stockquotes, e.g., via Bower. In "main.js" include a reference: 'jqueryui-stockquotes': 'libs/jquery-stockquotes/dist/jquery.stockquotes',  In your module, reference 'jqueryui-stockquotes' in your define block and in your "self.handleAttached" include the following:   $('.stock-quote').stockQuote(); In the view, include this:     <h2>Apple:  <span class="stock-quote" data-symbol="AAPL"></span></h2>     <h2>Bank of America:  <span class="stock-quote" data-symbol="BAC"></span></h2>     <h2>Facebook:  <span class="stock-quote" data-symbol="FB"></span></h2>     <h2>IBM:  <span class="stock-quote" data-symbol="IBM"></span></h2>     <h2>Microsoft:  <span class="stock-quote" data-symbol="MSFT"></span></h2>     <h2>Oracle:  <span class="stock-quote" data-symbol="ORCL"></span></h2>     <h2>SalesForce:  <span class="stock-quote" data-symbol="CRM"></span></h2>     <h2>Twitter:  <span class="stock-quote" data-symbol="TWTR"></span></h2> In the index page, reference the CSS: <link rel="stylesheet"   type="text/css"   href="js/libs/jquery-stockquotes/dist/jquery.stockquotes.css" /> And that's all!

Here's https://github.com/ajwhite/jquery-stockquotes integrated into an Oracle JET application: Steps: Somehow download https://github.com/ajwhite/jquery-stockquotes, e.g., via Bower. In "main.js"...

Beyond Mobile App vs. Mobile Browser

The continual discussion of whether to create a native/hybrid mobile app or to create an app accessed via the browser, has two recent alternatives. The starting point is to recognize that most people use about 5 apps on their mobile device and ignore the other 30 or so that are there by default. Most people have no clue about which apps are available and don't go searching for them randomly in an app store. Instead, they go to their browser on their mobile phone, access the page that interests them, e.g., the website of their newspaper of choice or hotel they'd like to book, and then use the browser to read the newspaper or book their hotel. In this reality, two new-ish approaches have arisen: Progessive Web Apps (PWA). In the scenario described above, once you're on the site of your newspaper or hotel, you're prompted to download an app that will reopen that browser page or start up a dedicated app, i.e., a native/hybrid app. For example, normally, you're not aware that your newspaper also has an app and hence you don't go to the app store to look for that app. Instead, you access the newspaper in the browser. If that browser-based newspaper is a PWA, it will let you download an app, yes, the app you didn't know the newspaper made available but which your being in the browser reading the newspaper provides an opportunity for the organization behind the newspaper to make available directly to you the app connected to the newspaper. Chatbots. In response to the same scenario described above, chatbots integrate with your existing apps, e.g., SnapChat, Facebook, WhatsApp, providing a purely conversational text-based communication mechanism for interacting around some topic, e.g., when you're in IKEA, you get a message via one or more of your existing apps to ask you what you're looking for and then the IKEA chatbot helps narrow down your aspirations and directs you to where you can fulfil them. A side effect is that there's no user interface at all, simply text, i.e., we're back on the command line in many ways, with chatbots. "Bots will start replacing mobile apps. No more looking for an app, downloading an app, updating an app, or managing an app." — Gartner, 2017 Interesting developments and, yes, neither are new, though both should always be included in any discussion on mobile app vs. browser app.

The continual discussion of whether to create a native/hybrid mobile app or to create an app accessed via the browser, has two recent alternatives. The starting point is to recognize that most...

NetBeans Day

Trip Report: NetBeans Day India 2017

NetBeans Day India was held today in Bangalore, hosted by BlueJeans. Not only did BlueJeans give us a location, but food and drinks as well, which was great! The program was announced here, with thanks to Vaibhav Choudhary, for organizing the event: https://www.meetup.com/BangaloreOpenJUG/events/238630862/ Attendance was good, the room was mostly full, which was especially great since it is a long weekend, with Monday being a public holiday. Sessions focused on Java as well as JavaScript, frontend and backend, all via NetBeans IDE. Below, you see Gaurav Gupta, from Payara, the developer behind the Jeddict project, a code generator for Java EE as well as Angular, which he presented with demos in NetBeans IDE. Other sessions included a focus on enterprise JavaScript, via Oracle JET, hybrid mobile development, and Node.js, presented by myself and my local colleagues Rohit Dhamija and Abhinav Shroff.  The move of NetBeans to Apache was a big theme of the event, with in my opinion this being the Tweet of the day, including a nice pic of Ivar Grimstad, from the JCP Executive Committee, who did a session on MVC 1.0 with NetBeans IDE: A definite highlight was the presence of Sharad Medhavi, Oracle Senior Director, seen next to me below, who announced that Oracle is actively building a team of Apache NetBeans developers at the local Oracle office. Two of those to join Sharad's local NetBeans team have already been hired, and were present too, Reema Taneja and Arunava Sinha. Looking forward to that team getting bigger, some of the attendees indicated an interest in this. Just think, Oracle will be paying developers fulltime to commit code to Apache NetBeans.  Another highlight was the presence of four NetBeans Dream Team members: Aatul Palandurkar, Tushar Joshi, Ivar Grimstad, and Gaurav Gupta, here eating lunch together below: It was a great event, many thanks to everybody involved, and hope it was enjoyable and informative for everyone who attended! 

NetBeans Day India was held today in Bangalore, hosted by BlueJeans. Not only did BlueJeans give us a location, but food and drinks as well, which was great! The program was announced here, with thanks...

NetBeans Day

Trip Report: NetBeans Day UK 2017

The 3rd NetBeans Day took place in London today! (Go here for the 2016 report and here for the 2015 report.) As before, NetBeans Day UK took place at the beautiful and historic Greenwich University. Many people were involved in making the event possible, such as Chris Walshaw, lecturer at Greenwich University, and Laura Muncey also from Greenwich University; Mark Stephens, Zain Arshad, and Georgia Ingham from IDR Solutions; Mike Croft and Andrew Pielage from Payara; Neil C. Smith from Praxis LIVE; and John Kostaras who came all the way from Belgium. Also present to do sessions and demos were Vladimir Voskresensky and Petr Kudryavtsev from Oracle Russia, as well as Chris Seaton from Oracle Labs. Paul Tinker from the local Oracle office was present as well, supporting the Oracle JET workshop. There was a lot of engagement and interaction between attendees, which was really cool. We focused a lot on providing informal opportunities, e.g., workshops and activities in the lunch area, for people to chat in an informal way. E.g., those without laptops in the workshops were quickly paired up with those with laptops, so that new connections were established while working with NetBeans IDE!  The day began with a warm welcome from Chris Walshaw and myself, followed by an overview of the history of NetBeans IDE and an update on the Apache NetBeans process. This was followed by Chris Seaton's intoduction to Graal/Truffle, i.e., the new fast polyglot JVM being developed by Oracle Labs. Mark and Zain then did a "NetBeans 101", with lots of tips and tricks, quite a few of which came back in discussions I had with people afterwards. All this was followed by lunch. We had put tables throughout the lunch area and various attendees demoed and hacked code with attendees. For example, we had briefly introduced their projects to the whole group, e.g., Vladimir introduced the C/C++/Java integration work done in Oracle Russia via Oracle Solaris Studio, which he discussed at one of the tables in the lunch room. Meanwhile, Neil C. Smith showed off PRAXIS Live at another table and discussed it with those interested in that topic, while eating lunch. I.e., the lunch room became a hacker garden, where whoever wanted to hear more about a topic brought their lunch and hung out and discussed with others on particular topics.  After which the group split into two tracks for workshops. Based on previous surveys, workshops were something missing from previous events, i.e., opportunities to learn new things and actually code and use them at the same time. We set up two workshops in parallel, the first on Java 9 and Jigsaw, while the other room had a Java EE microservices session with the Payara team. The Java 9 session, introduced by John Kostaras, was pretty interesting, i.e., seeing attendees playing with JShell and Jigsaw for the first time. After that followed a session on Oracle JET in parallel with a NetBeans IDE plugin development session. The choices were hard to make, i.e., quite a few would have wanted to attend all the workshops, though the day wasn't long enough for that! Many thanks to Paul Tinker for the excellent help during the Oracle JET session, his assistance made a big difference also because I had to rush off to the airport for the next conference. The day ended with a prize draw for books, including "Java EE 7 Recipes", kindly donated by its author Josh Juneau, and "Java EE 7 with NetBeans 8" kindly donated by David Heffelfinger, followed by the inevitable hangout at a local pub! All the resources used throughout the day are available here: https://github.com/NetBeansDay/042517-London

The 3rd NetBeans Day took place in London today! (Go here for the 2016 report and here for the 2015 report.) As before, NetBeans Day UK took place at the beautiful and historic Greenwich University. M...

NetBeans

Software Adoption Surveys: From Quantity To Quality!

In a democracy, everyone is equal. One person, one vote, and all votes are equal since all people are equal. Erroneously, that approach is applied to software adoption surveys too. Anyone at all can respond to a survey and can indicate that they use software product X, Y, or Z. However, what if I am a student paddling in the shallow waters of software development, with the likelihood that I'll abandon it before I graduate, while you are a senior Java architect creating mission critical software for NASA? Should my vote for product X, Y, or Z be equal to yours? Surely not? According to "Baeldung", NetBeans usage has MORE THAN DOUBLED between 2016 and 2017, from 5.9% to 12.4%: And look here! NetBeans IDE is 2nd, beating IntelliJ IDEA and Eclipse: And... wow... look at this one, NetBeans is 2nd, after Eclipse, leaving IntelliJ IDEA far away in the dust: Hurray, NetBeans is waaaaay more popular than X, Y, and Z!  Sorry, the above results are meaningless, just like the results by RedMonk and the results by RebelLabs. Yes, even though the above results favor NetBeans, the tool that I like and have been promoting, and will continue to promote, for many years, the above results are bullshit. When you look at the results of a software adoption survey, you have no idea at all whether the 70% using product A are creating financial software while the 2% using product B are brain surgeons or rocket scientists. And surely that makes a difference, i.e., knowing that information makes a difference in how you would evaluate software adoption surveys. Your software may be aimed at brain surgeons or rocket scientists and so the 70% doing financial software with a competing product are irrelevant to you. So, let's stop the meaninglessness of software adoption surveys. Let's instead turn things around and do surveys of projects instead of people.  One project, one vote—instead of one person one vote.  And there'd also need to be distinctions between types of projects. Plus, there'd need to be agreement on which specific projects to survey, with the same survey being done with exactly the same projects over a specific number of years, e.g., 5, to show trends. We'd get richly textured results like this: In the 1000 commercial projects surveyed over the past 5 years, 40% use Java-based product X, 30% use competing Java-based product Y, while the remainder don't use Java-based products at all. Over the past 3 years, adoption has shifted significantly amongst the 1000 commercial projects surveyed, from product B to product A in the financial sector, while in the logistics sector adoption has remained constant. Meanwhile, Java-based product Z has declined, though not significantly, and remains popular in large enterprises with over 500 fulltime software developers who combine product A with product B.   90% of the 700 financial projects that have been surveyed use product X, while 75% of the 500 scientific projects that have been surveyed use product X together with competing product Y because product Y provides benefit A in the context of process B which is important specifically to scientific projects because of reason C. In 20% of the organizations surveyed, strict rules are defined about software usage, while 70% leave it up to the developer, and 10% did not respond to this question.    In all of the 2500 organizations with over 100 fulltime developers surveyed, three competing open source products are used in one way or another. In the aerospace domain, which is 15% of the 2500 organizations surveyed, product A is slightly more popular than product B, while in the educational domain, which is 60% of the 2500 organizations surveyed, product B is clearly dominant, while product C is mainly popular amongst developers at startups, encompassing 20% of the organizations surveyed. Wouldn't these kinds of results be far more meaningful than the winner-take-all mentality of one (random) person, one vote—which is the current approach that software adoption surveys take? You'd be able to judge the relevance of the results based on your target audience. For example, you'd be able to say things like: "Well, since we don't care about startups, it doesn't matter that we're not popular there." Right now, we're unable to say these kinds of meaningful things because of the random 2000 people taking part in your survey, they could all be in the same country or working in a similar domain or a majority could be sympathetic to your organization, or came across your survey because they happened to be following you on Twitter, or all working on the same or similar projects.   Let's stop focusing on the very simplistic "how many people filled in my survey" (e.g, "Last year, 2250 Java developers decided to take the time to answer the questions, and so it's fantastic to see this year that number is almost double - we got 4439 answers.") and switch over to the much more complicated task of "how can I be sure I am getting quality data from my survey". E.g., if you were to ask me "do you use OpenOffice or Microsoft Word", I would probably say "OpenOffice" even though I am using both these products more or less equally (together with other small editors like Notepad and Sublime, but you'll never know that since you never asked about that), though you're not giving me the choice to say that, and my individual usage statistic is meaningless if everyone else answering your survey is just like me or working on the same project or I have persuaded my friends to fill in your meaningless survey or rocket scientists at NASA don't care enough or are behind a firewall and so aren't filling in your survey. To be honest, I am not hopeful, at all. I admit to being a bit cynical since I have the feeling that the most important reason for software surveys is not to gain meaningful insights, though I believe you completely when you claim good intentions and I applaud you for what I think you think you're honestly trying to do—instead, the reason why surveys exist is to promote the organization behind the survey as a neutral repository of truth and insight. And the glossier the brochures you print, the shinier the graphs that display your random data, the more suspicious I am that you're marketing your organization rather than gathering meaningful data.

In a democracy, everyone is equal. One person, one vote, and all votes are equal since all people are equal. Erroneously, that approach is applied to software adoption surveys too. Anyone at all can...

NetBeans

Running NetBeans IDE 9 Development Build on JDK 9 EA Build 162

For the adventurous, interesting times ahead since you're able to try out the NetBeans IDE 9 development build on top of JDK 9 EA, in my case, Build 162. When you configure that in your 'etc/netbeans.conf' file, the first thing you see on start up is this error, which appears to be related to the Darcula plugin that I'm using. Of course, since it's awesome despite this aspect for the moment, I'm using the Darcula plugin, which you can download and install from here, i.e., simply use the latest release of the plugin for 8.2, works fine in 9 development builds, except for this error. After seeing the above, simply click Cancel, and, so far, despite the above, things are pretty good! There are two big advantages to running the NetBeans IDE 9 Development Build on top of JDK 9. The first is that the fonts are automatically a lot better, at least, on Windows and, at the very least, on my system (click to enlarge the below, where you see NetBeans IDE 9 Development Build on JDK 9 on the left versus on JDK 8 Update 121 on the right): The second advantage is that you automatically have JShell integration (choose Tools | Open Java Platform Shell), as shown below. Excellent enhancement here is that, since the last time I used it, there's now a code fold for the text at the top of the JShell. Until further notice, this is the environment I'll be using. 

For the adventurous, interesting times ahead since you're able to try out the NetBeans IDE 9 development build on top of JDK 9 EA, in my case, Build 162. When you configure that in your...

NetBeans

Software at Delta Air Lines

A few days ago, not long after flying with Delta to Atlanta for DevNexus, and benefiting from a Delta upgrade and bathing in the luxury of Delta business class, I spent some time at Delta's Operational Control Center (OCC). I was able to do that thanks to Graeme Ingleby, a senior developer at Delta who has been exploring the benefits of the NetBeans Platform for quite some time and has attended JavaOne over the past years, including related events such as NetBeans Day and other NetBeans social events at JavaOne. Delta, of course, is one of the key international organizations based in Atlanta, as well as Coca Cola and CNN. The terrain of the OCC is large and diverse and includes a museum being built within a Delta plane, shown below: I was given an inspiring tour throughout the OCC, by Ben Shermer, General Manager, Flight Control. The OCC handles absolutely everything you can think of in relation to Delta operations. Everything, absolutely everything, in relation to aircraft, crew, and passengers is managed from the OCC, a very small part of which is shown below: For example, the OCC handles aircraft maintenance, hotel bookings for aircraft crew, emergencies such as death or illness of passengers on planes, boarding procedures, and more. Much more. Everything, in fact, all over the world, connected to anything to do with Delta is handled in the OCC in Atlanta.  Each computer in the OCC has a light on top of it which, when switched on, indicates that the operator is on the phone. I was told during the tour that the head of the OCC is happiest when all the lights are switched off and when all the operators have their feet up on their desks while reading their newspapers—since that means that there isn't an emergency of some kind being handled. For me, as a developer, the most interesting part of the day was seeing the application below:  What you see above is, yes, a Java Swing application. The dominant elements are a JTable and, along the bottom, some JFreeCharts. All the data of all planes, crews, and passengers are received and monitored in this application. Someone sick on a plane? Flight delays? Snow storms? Crew hotel bookings? Current percentage of boarded passengers? Everything is displayed in one of the columns of this highly customized JTable. The application above is named "Bridge Desktop". It is one of dozens of applications in use at the OCC. And that's precisely the problem of the OCC. The software across the OCC handles multiple different use cases and the applications have multiple different histories, coming from a variety of different organizations historically over time. Some duplicate the functionality of other software. Cut/paste and drag/drop between these applications is difficult to impossible, while multiple monitor support is an essential requirement, since as you can imagine, each operator is looking at about six different screens all at the same time. How to integrate these different applications is the big problem of Delta. Some of the applications are Java, some C/C++, some web-based, etc. Each has different requirements and demands. Bridge Desktop, for example, has as its central component a highly customized JTable, which has taken years to develop to the point where it is now, both in terms of content and functionality. For example, multi-select across rows in tables has been built in, with a rules engine underneath it all, and features for comparing disparate data sets. There's no point in moving this application to JavaFX, since that JTable would need to be rewritten and the benefit of JavaFX in this context is severely limited, especially when weighed against the cost of the rewrite. And a web-based solution would also not bring anything of benefit versus the cost of moving the application into the browser. One could imagine an interactive dashboard of some kind, to replace the JTable. In principle that sounds like a cool thing, while in reality that isn't a requirement for this piece of software. The operators using the JTable-based solution know how it works and understand it. The slick look and feel that a web-based dashboard would provide sounds completely valid in principle, as would purchasing an off-the-shelf solution sound like a logical thing to do. However, off-the-shelf solutions don't work in these highly customized contexts and, though attempts are always being made along those lines, they inevitably fail. Of course, there's continual pressure for a web-based solution, not from users or developers, but from managers. Not a new story at all, though interesting to see replicated again at Delta. After discussing all these kinds of interesting challenges, I was given a tour of the flight simulators, see below:  It was a brilliant time and I learned a lot and came out of it affirmed in several opinions I've had for many years. Of course, the NetBeans Platform is being evaluated as a mechanism for integrating the variety of software solutions throughout Delta. It's simply the right tool for the job in this context.  Thanks again Graeme Ingleby as well as Ben Shermer for the inspiring and enthusiastic tour around the OCC.

A few days ago, not long after flying with Delta to Atlanta for DevNexus, and benefiting from a Delta upgrade and bathing in the luxury of Delta business class, I spent some time at...

NetBeans

NetBeans and Apache (Part 2)

Since the various announcements about NetBeans transitioning to Apache, what's been going on and what's the current status? Before reading on, take a look at the following: James Gosling on NetBeans and Apache NetBeans and Apache (Part 1) NetBeans Apache Incubator Proposal Well, if you're asking "what's been going on?" it simply means you're not part of the discussion, which is a simple step-by-step process to be part of: https://cwiki.apache.org/confluence/display/NETBEANS/How+to+Participate After following the above, you'll be on the NetBeans Apache developer mailing list and be able to follow the process as it happens. Right now, weekly updates are provided on the process. In short, Oracle is going through the process of making sure that the NetBeans repositories that are targeted at being donated to Apache do not contain anything that should not be donated. For example, Oracle cannot donate files that are not Oracle's to donate. The repositories contain code going back 20 years, since NetBeans has existed since 1995/96, and are therefore full of potential accidental reusages of code that may or may not belong to Oracle, e.g., that could be forks of the JDK, for example. All files are being examined for such instances, including missing copyright notices, and similar potentially problematic areas. Which repositories are we talking about? How long will all this take? Scroll to the end of the page here for details: https://cwiki.apache.org/confluence/display/NETBEANS/Apache+Transition The aim is for NetBeans 9 to be released as a top level Apache project together with the release of JDK 9. Prior to that, i.e., in order to move out of the Apache Incubator, there needs to be at least one release of NetBeans done from within the Apache incubator, i.e., NetBeans IDE 8.2.1 or NetBeans IDE 8.3. So, those are tight deadlines we're aiming for, though all sides are clear about what we're targeting and focused on meeting those deadlines. Things are looking good and, speaking for myself, I'm happy that we're going through such a thorough process, since the end result will be clear and comprehensive to everyone involved. And, guess what, the Apache NetBeans community already has a new website in place, clearly a work in process though it's awesome we have it at this stage already, with thanks especially to Chris Lenz from Leipzig who is leading this project: netbeans.apache.org If you're out there and interested in joining in and keeping in touch with the process, go here to get started: https://cwiki.apache.org/confluence/display/NETBEANS/How+to+Participate

Since the various announcements about NetBeans transitioning to Apache, what's been going on and what's the current status? Before reading on, take a look at the following: James Gosling on NetBeans and...

NetBeans Day

Trip Report: NetBeans Day France 2017

The Laboratoire d'Informatique de Grenoble hosted NetBeans Day France yesterday. The event was sponsored by Davidson in Paris, who provided the great lunch! The program included the following topics: Reactive Systems with Eclipse Vert.x and Red Hat Open Shift (Clement Escoffier, Red Hat) Développement entreprise JavaScript avec Oracle JET (Geertjan Wielenga, Oracle) Jouer avec Spring Boot et Docker (Nebrass Lamouchi, Davidson SI) JBoss Forge, WildFly et Java EE (Emmanuel Hugonnet, Red Hat) The day began with a session about the NetBeans project, its history, unique features, and transition to Apache. Clement Escoffier demoed in a lot of detail Vert.x together with OpenShift and NetBeans IDE: That was followed by me talking about Oracle's new JavaScript toolkit, Oracle JET: I had to leave shortly after the above, though I heard Nebrass and Emmanuel did great sessions on Spring Boot and Docker (Nebrass) and JBoss Forge, WildFly, and Java EE (Emmanuel). Both Emmanuel and Nebrass are NetBeans Dream Team members, great to have worked with them to organize this event. And thanks again, Davidson in Paris, for sponsoring the lunch for this successful event. Possibly we could have two NetBeans events in France each year. One in Grenoble and the other in Paris! 

The Laboratoire d'Informatique de Grenoble hosted NetBeans Day France yesterday. The event was sponsored by Davidson in Paris, who provided the great lunch! The program included the following topics: Reac...

New Year: New Opportunities, New Rewards!

In Dutch they say, "Nieuwe kansen, nieuwe prijzen", at the start of the latest installment of a game show, lottery, etc. Well, each new year offers new opportunities, with new rewards, and here we are in 2017. I haven't blogged for a while, simply because I've been too busy to do so. Oracle JET is taking up all my time. I've traveled a lot over the past months and that will continue, the first half of the year is almost completely booked full already. At the same time, there's NetBeans IDE or, should I say, "Apache NetBeans (incubating)", which is moving along really well. By that I mean everything in every sense, in that context, from the Apache process, to its continued development by Oracle engineers focused on supporting Java 9, to my continual promotion of it via demonstrations of how to use Oracle JET, to all kinds of dependencies that multiple large organizations have both on NetBeans as a development tool, tooling platform, and application framework. Oracle JET I must confess I'm really excited about Oracle JET, for being an open source, free, and library-based JavaScript toolkit. And, no, I'm not excited about just about everything in the world (you could not, for example, get me to promote vacuum cleaners; then again, on the other hand, if it were to be a really effective vacuum cleaner that was simply awesome and somehow open source, ok, well, never mind, I'd promote your open source vacuum cleaner and probably even for free) or even everything that my employer wants me to be excited about, i.e., there are enough things my employer has suggested I promote that I feel really lukewarm about and that didn't excite me enough to spend time understanding and promoting, simply because of not completely connecting to my areas of interest, etc. That's also something that's underhighlighted about Oracle as a whole—it is simply such a massive ecosystem of products that once you're connected to a part of it, you really do have a lifetime's worth of interesting work ahead of you. Oracle provides a lot of opportunity for learning and meaningfulness in that sense. Java Desktop So. Where does that leave my erstwhile enthusiasm for the Java desktop? Now that I'm a fullblown JavaScript enthusiast, spreading the gospel of browser-oriented development, have I simply dumped my many years of advocacy of the Java desktop?No, not at all. What I have done over the years is very simple and easy to understand—I have advocated tools and technologies for industrial application development. As opposed to what? Well, as opposed to game development, for example, which I've always considered a bit, well, trivial. I've always found it most interesting to focus on development that means something real, that makes a difference, whatever those phrases mean, as opposed to those that simply seek to entertain or that do little more than help fill time, though I don't want to necessarily pass moral judgement here either, since a lot of really skilled and artistic work is done in those areas, of course, at the same time. In general, I definitely prefer the complexities of solving problems for applications targeted for the back office, or behind the firewall, or in secure areas, over those targeted at non-technical end users.What does that mean, concretely, in terms of what I find meaningful, i.e., industrial application development? I have, and continue to do so, promoted the open source tools and technologies that, in my humble opinion, make sense when you're creating large enterprise solutions. Are you creating large applications in the areas of finance, human resources, logistics, and the like? Well, then, moving your data to "the Cloud" and your user interface to the browser, whether on mobile or desktop, makes perfect sense. (And the Oracle Cloud is truly comprehensive and stable, with a large ecosystem of knowledgeable experts and enthusiastic partners to help you. I know this, since I have interacted with many of them directly and personally over the past months.) Are you, on the other hand, creating large applications in the areas of bioinformatics, aerospace, and defense, where you want to make maximum use of desktop resources and graphic visualization and you have a lot of in-house Java desktop experience while the volatility of the JavaScript ecosystem is a real blocker for migration to the browser? Well, great, in that case, the Java desktop is perfect and you clearly need a lot more than Java toolkits such as JavaFX or Java Swing—you also need an application framework, module system, windowing/docking framework, and so on. In fact, you need the NetBeans Platform. Wait, am I saying that there's a place for both JavaScript and Java, for both browser and desktop? Yes, of course there is—"the right tool for the right job" is simply the best approach to anything. Therefore, my argument is that you shouldn't be "religious" about your choices, of course... Tools ...except for your tools. :-) Ultimately, you need a comprehensive and stable development environment to create your applications, regardless of where they are to be deployed. The best thing to do is to use open source tools and technologies, uniquely provided by NetBeans IDE, which is in the process of becoming an Apache project, which means that you can participate in its development process and roadmap far more than any other development tool in the history of development tools. Hurray, 2017 is going to be great and is filled with opportunities that all make sense and all have a logical place in unlocking data and turning it into actionable information that makes a real difference in people's lives. 

In Dutch they say, "Nieuwe kansen, nieuwe prijzen", at the start of the latest installment of a game show, lottery, etc. Well, each new year offers new opportunities, with new rewards, and here we are...

Oracle JET

Custom Component for Zipping and Downloading Files

Here's a handy custom component (i.e., a CCA component) for zipping files and downloading them, in an Oracle JET application: <fileDownloadForm file="{{file}}" content1="{{htmlContent}}" content2="{{jsContent}}"></fileDownloadForm> I've created it as part of a project where we want to let developers design a CCA component and then download it as a ZIP file, so that it can be distributed to those who want to make use of the component. That's the reason you can see above that two files are assumed to be provided, with 'file' being the name of the file, used for both the view and the viewModel. In an application, the above component is rendered as follows: What happens when "demo" is changed to "sample" in the text field above and then the "Download" button is clicked? Well, when you do that, a download process begins and you'll have a ZIP file, with this content, yes!, a CCA component: So... what this blog entry is about is... how to create a CCA component for downloading CCA components...  The structure of the CCA component you'll create is as follows: Here's the JSON file, "fileDownloadForm.json": { "properties": { "file": { "description": "file name.", "type": "string" }, "content1": { "description": "html content.", "type": "string" }, "content2": { "description": "js content.", "type": "string" } }} Here's the view, in "fileDownloadForm.html": <div class="oj-panel"> <label>ZIP Name:</label> <input type="text" data-bind="ojComponent: { component: 'ojInputText', value: file}"/> <button class="oj-button-primary" style="float: right;" data-bind=" click: downloadFile, ojComponent: { component: 'ojButton', label: 'Download' }"> </button></div> Here's the business logic in the viewModel, "fileDownloadForm.js": define(['knockout', 'jszip', 'file-saver'], function (ko, JSZip) { function model(context) { var self = this; self.file = null; self.content1 = null; self.content2 = null; context.props.then(function (properties) { if (properties.file) { self.file = properties.file; } if (properties.content1) { self.content1 = properties.content1; } if (properties.content2) { self.content2 = properties.content2; } }); self.downloadFile = function (model, event) { if (event.type === 'click' || (event.type === 'keypress' && event.keyCode === 13)) { var zip = new JSZip(); zip.file(self.file+".html", self.content1); zip.file(self.file+".js", self.content2); zip.file("loader.js", "to be done"); zip.file("README.txt", "to be done"); zip.generateAsync({type: "blob"}) .then(function (content) { saveAs(content, self.file+".zip"); }); } }; } return model; }); The above assumes you've set up these two libraries in your application: https://github.com/eligrey/FileSaver.js http://stuk.github.io/jszip I.e., somehow, via Bower or otherwise, you've included them like this: In 'main.js', you should have these references in the 'paths' of 'requirejs.config': 'file-saver': 'libs/file-saver/FileSaver', 'jszip': 'libs/jszip/dist/jszip' And, to wrap things up, tying everything together, you have "loader.js": define(['ojs/ojcore', 'text!./fileDownloadForm.html', './fileDownloadForm', 'text!./fileDownloadForm.json', 'ojs/ojcomposite'], function(oj, view, viewModel, metadata) { oj.Composite.register('fileDownloadForm', { view: {inline: view}, viewModel: {inline: viewModel}, metadata: {inline: JSON.parse(metadata)} }); }); As a simple example of usage of the above, include the following in the "viewModel" of the handy custom component outlined at the start of this blog entry: self.file=ko.observable('demo');self.htmlContent=ko.observable('dummy html content');self.jsContent=ko.observable('dummy javascript content'); Now, whenever you include the handy custom component, anywhere in your application, the user can click "Download" and then they'll have a ZIP file downloaded with the specified content in the specified files.

Here's a handy custom component (i.e., a CCA component) for zipping files and downloading them, in an Oracle JET application: <fileDownloadForm file="{{file}}" content1="{{htmlContent}}" ...

Oracle JET

Page Flow, Enablement, and ojListView (Part 1)

Let's combine a couple of recent blog entries into a scenario. We'll combine Simple JSON and ojListView Sample with From ojNavigationList to ojButton and add some additional bits and pieces.  Start by setting up Simple JSON and ojListView Sample. Now, we have a new requirement—we need a "Next" button, i.e., for navigating to the next section of our single page application. However, that button should only be enabled if something is selected in the list. Some small tweaks are needed to achieve this. Take a look in particular at the bits in bold below, which are the only differences to Simple JSON and ojListView Sample: define(['text!../data/employees.json', 'ojs/ojcore', 'knockout', 'jquery', 'appController', 'ojs/ojlistview', 'ojs/ojarraytabledatasource'], function(file, oj, ko, $, app) { function DashboardViewModel() { var self = this; self.data = [];self.selectedItem = ko.observable(-1); var content = JSON.parse(file); var employees = content.employees; for (var i = 0; i < Object.keys(employees).length; i++) { var employee = employees[i]; self.data.push({ first: employee.firstName, last: employee.lastName }); }self.optionChangeListener = function (event, ui) { if (ui.option === 'currentItem' && ui.value !== null) { self.selectedItem(ui.value); } }; self.dataSource = new oj.ArrayTableDataSource ( self.data, {idAttribute: "first"} );self.next = function() { app.router.go('incidents'); }; } return new DashboardViewModel(); }); Here's the view, notice in particular the usage of the "disabled" property of the ojButton, while also noticing the "optionChange" property of the ojListView: <div class="oj-hybrid-padding"> <h2>Select Customer</<h2> <ul data-bind="ojComponent: { component: 'ojListView', data: dataSource,optionChange: optionChangeListener, item: {template: 'employee_template'}, rootAttributes: {style: 'width:20%;height:80%'}, selectionMode: 'single'}"> </ul> <script type="text/html" id="employee_template"> <li> <h3 data-bind="text: first"></h3> <span data-bind="text: last"></span> </li> </script> <button id= "nextButton" class="oj-button-primary" style="width: 5%" data-bind=" click: next, ojComponent: { component: 'ojButton', label: 'Next',disabled: selectedItem() == -1 }"> </button></div> Thanks to my colleague Max Froeschl for these insights.

Let's combine a couple of recent blog entries into a scenario. We'll combine Simple JSON and ojListView Sample with From ojNavigationList to ojButton and add some additional bits and pieces.  Start by...

Oracle JET

json2form Generator for Oracle JET applications

There's often a need to create standard forms for different purposes in an application, such as these, an incident entry form and a customer feedback form: Imagine if all that would be needed for creating the two forms above would be this in each view: <json2form json="{{jsonFile}}"/> For each view containing the above, the viewModel would load a file such as this for the form on the left above: [ { "key": "incidents_form", "title": "Incident Entry Form", "description": "Enter Incident Details", "message": "We want incidents fixed fast!", "properties": [ {"name": "Type", "options": ["Serious", "Minor"]}, {"name": "Description"}, {"name": "City"}, {"name": "State"}, {"name": "Country"} ] }] And this for the form on the right above: [ { "key": "customer_form", "title": "Customer Feedback Form", "description": "Enter Customer Feedback", "message": "We love our customers!", "properties": [ {"name": "Name"}, {"name": "Feedback"}, {"name": "Rating", "options": ["Excellent","Good","Bad"]} ] }] To achieve the above, we need to make use of the composite component architecture, described here: http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=composite&demo=basic I have blogged about a simple getting started scenario for composite components architecture here: https://blogs.oracle.com/geertjan/entry/minimal_oracle_jet_composite_component We also need to make use of the metadata-driven dynamic form functionality described here: http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=controlcombos&demo=formdynamic In this case, what we need is a structure like this: See yesterday's blog entry if you want your applications structured like the above. Here's the definition of loader.js: define([ 'ojs/ojcore', 'text!./view.html', './viewModel', 'text!./metadata.json', 'ojs/ojcomposite'], function (oj, view, viewModel, metadata) { oj.Composite.register('json2form', { view: {inline: view}, viewModel: {inline: viewModel}, metadata: {inline: JSON.parse(metadata)} }); }); Here's the definition of metadata.json: { "properties": { "json": { "type": "Array" } }} Here's the definition of viewModel.js: define(['ojs/ojcore', 'knockout', 'ojs/ojinputtext', 'ojs/ojradioset', 'ojs/ojbutton'],function (oj, ko) { function CompositeModel(context) { var self = this; context.props.then(function (props) { self._props = props; _initProperties(); }); function _initProperties() { self.descriptors = ko.computed(function () { var mapped = self._props.json.map( function (json) { var def = { title: json.title, description: json.description, message: json.message, properties: json.properties }; return def; } ); return mapped; }); } } return CompositeModel;}); Here's the definition of view.html: <div data-bind="foreach: descriptors" class="oj-panel-alt2 oj-margin oj-flex-item"> <div class="oj-flex-item oj-panel-alt2 oj-margin"> <h1 data-bind="text: title"></h1> <h3 data-bind="text: description"></h3> </div> <div class="oj-flex-item oj-panel-alt2 oj-margin"> <!-- ko foreach: $data.properties --> <div class="oj-flex-item oj-panel-alt oj-margin"> <label data-bind="text: $data.name"></label>: <!-- ko if: $data.options --> <!-- ko foreach: $data.options --> <div data-bind="ojComponent: { component: 'ojRadioset', value: $data}" > <span class="oj-choice-row"> <input type="radio" value="$data"> <label><span data-bind="text: $data"></span></label> </span> </div> <!-- /ko --> <!-- /ko --> <!-- ko ifnot: $data.options --> <input id="inputcontrol" data-bind="ojComponent: { component: 'ojInputText', rootAttributes: {style:'max-width:100em'}}"> <!-- /ko --> </div> <!-- /ko --> </div> <div class="oj-flex-item oj-panel-alt2 oj-margin"> <b data-bind="text: message"></b> </div></div><hr> And, finally, here's how the files are loaded and used in all the viewModels that need to make use of it: define(['text!./customers.json', 'ojs/ojcore', 'knockout', 'jquery', 'ojs/ojcomposite', 'app/jet-composites/json2form/loader'], function (file, oj, ko, $) { function CustomerViewModel() { var self = this; self.jsonFile= JSON.parse(file); } return new CustomerViewModel(); }); There is more to be done to complete this scenario because right now we're only rendering the forms and not processing the input. That will be the next step of this series. Right now, based on the above, you're able to transform a JSON file into a form, which is the first step in this scenario. Thanks to my colleague Max Starets for providing a similar scenario to this recently.

There's often a need to create standard forms for different purposes in an application, such as these, an incident entry form and a customer feedback form: Imagine if all that would be needed for...

NetBeans

Restructuring of Oracle JET Applications

During UKOUG 2016, this week, I learned a cool thing from my colleague Lyudmil Pelov—the response to the most frequently asked question from the Oracle JET sessions I have been doing around the world: "Isn't the 'js/views' and 'js/viewModels' structure a technical rather than a functional architecture? And wouldn't it be better to have both sides of an Oracle JET module in the same folder?" Well, take a look at this, the "navdrawer" template restructured based on functionality, e.g., in the "app/pages/dashboard" folder, both sides of the "dashboard" module are found, rather than the viewModel being in 'js/viewModels' and the view in 'js/views': If you prefer this structure over the default structure brought to you by the Oracle JET templates, take the following steps. I suggest you first get it working in the "navdrawer" template, before trying to apply this structure to your own application.  Set up the 'navbar' template, i.e., use the "Oracle JET QuickStart Basic" template in NetBeans IDE. Create a new folder named 'app', as shown in the structure above. Inside 'app', create a folder called 'pages', with a subfolder for each of the custom Oracle JET modules provided by the 'navbar' template, i.e., 'dashboard', 'incidents', 'customers', and 'about'. Move the 'dashboard.js' and 'dashboard.html' from 'js/viewModels' and 'js/views' into the 'app/dashboard' folder. Do the same for the other Oracle JET modules. Move the 'libs' folder into 'app' (and tweak '.bowerrc' and potentially other similar files, to download JavaScript libraries into the new location of 'libs'). In 'main.js', change all the paths to JavaScript libraries to reflect their new locations, i.e., they're no longer in 'libs'; they're in 'app/libs'. Move 'appController.js', 'main-release-paths.json', and 'main.js' into the 'app' folder. In 'index.html', correct the reference to 'main.js' to its new location in 'app' and do the same for 'require.js', which should now be in 'app/libs/require'. In the 'requirejs.config' section in 'main.js', change the 'baseUrl' to point to '.' instead of 'js'. In 'appController.js', change the router as follows and notice that you can also have a functional nested structure for your Oracle JET modules:function getPagePath(path) { return 'pages/' + path + '/' + path.substr(path.lastIndexOf('/') + 1);}self.router = oj.Router.rootInstance;self.router.configure({ 'dashboard': {value: getPagePath('dashboard'), label: 'Dashboard', isDefault: true}, 'incidents': {value: getPagePath('incidents'), label: 'Incidents'}, 'customers': {value: getPagePath('customers'), label: 'Customers'}, 'about': {value: getPagePath('about'), label: 'About'}}); In 'main.js', as the new first lines in the 'require' block, override the default locations of the viewModels and views, i.e., rather than the default 'js/viewModels' and 'js/views', you now want them to both be found within the 'app' folder (in the location specified by the router in the previous step):oj.ModuleBinding.defaults.modelPath = 'app/';oj.ModuleBinding.defaults.viewPath = 'text!app/'; At this point, you should be able to delete the 'js' folder, i.e., there should be nothing in it anymore. Run the application and everything should work exactly as before!

During UKOUG 2016, this week, I learned a cool thing from my colleague Lyudmil Pelov—the response to the most frequently asked question from the Oracle JET sessions I have been doing around the world:...

Oracle JET

Wireframing with Oracle JET

I learned a few interesting things from my colleague Sylvain Côme in London today. Sylvain is a very big enthusiast of Oracle JET and is introducing it in a variety of contexts. For wireframing, he uses Adobe XD. For the images in his wireframes, he has installed SVG Crowbar into his Chrome browser, which enables him to download SVG files of images in the Oracle JET Cookbook. He then imports those SVG files into his wireframe in Adobe XD, where he can even edit them, resulting in a wireframe with awesome Oracle JET visualizations, which will, once the wireframe is accepted, look identical to the final app since the SVG files are created directly from the image of the related Oracle JET component in the Oracle JET Cookbook. That's a lot of info to process all at once, so let's take it step by step. 1. Start up Chrome,  show the Chrome bookmarks bar (Ctrl + Shift + B), and then go here and follow the instructions:  http://nytimes.github.io/svg-crowbar. 2. Go to one of the cool data visualizations in the Oracle JET Cookbook, such as this one: http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=dataVisualizations&demo=polarWeatherPlot 3. Click "SVG Crowbar 2" in the bookmarks bar and you'll see (depending on how many SVG images are available), an icon for each SVG image. In this case, there's only one SVG image on the page, which makes it very simple and simply click the Download button: 4.  You now have an SVG image. Open Adobe XD, which is not supported yet on Windows, which is what I'm using, so let's use this instead, just to prove the point: http://editor.method.ac Click the link above and then go to File | Open SVG. Browse to the SVG you downloaded and open it into the above.  Now, as you can see above, depending on the SVG image you're using, you can edit all kinds of parts of it, and then integrate it into your wireframe. Of course, before downloading it, you can edit various parts directly in the browser within the Oracle JET recipe in the Oracle JET Cookbook too, i.e., tweak code, and then click Apply. It's pretty powerful, as you can see, that you can use the power of SVG via the Oracle JET Cookbook to create content for your wireframes, very easily indeed!

I learned a few interesting things from my colleague Sylvain Côme in London today. Sylvain is a very big enthusiast of Oracle JET and is introducing it in a variety of contexts. For wireframing, he...

Oracle JET

Integrating Styles into Oracle JET Applications

A lot of organizations have style guidelines for their browser apps. I.e., these style guidelines consist of colors, sizes, icons, etc, normally supported by CSS stylesheets. Wouldn't it be nice if there'd be a few customizable templates for quickly styling Oracle JET applications? Well, take a look here: http://www.oracle.com/webfolder/technetwork/jet/globalExamples-ThemeViewer.html Welcome to the Oracle JET Theme Builder. It's been around for a while, though a bit hidden on the Oracle JET Examples page. The Oracle JET Theme Builder is an Oracle JET application that lets you create themes (i.e., CSS stylesheets), based on a set of existing themes, for your Oracle JET applications. Click "Live Demo" and then click "Instructions" in the top right, which brings you here. Follow those steps and you'll literally have everything you need. Below I have summarized things a bit, though the Instructions speak for themselves. 1. Set Up. Download the ZIP file on the Instructions page, unzip it, and run the 4 Yeoman commands shown on the Instructions page on that folder: When you run "yo oraclejet:restore", both 'npm' and 'bower' will be run, to access all the required JavaScript libraries for any Oracle JET application.  When you run "yo oraclejet:add-sass" and you receive error messages about Python being needed, the simplest solution is to downgrade 'node' to v5.x, e.g., I have v5.9.1, i.e., when I was on v6x, I had all kinds of problems, e.g., needing Python and then something else, which I fixed by downgrading node. Doing this has not had adverse effects so far.  When you run "yo oraclejet:add-theme mytheme", you populate "src\themes\mytheme" with content. Make sure that the name you specify is literally "mytheme", i.e., do not change it to something different. "mytheme" is the fixed name of the custom theme you'll be creating. After you've created your theme, i.e., a set of CSS files, you can name them whatever you like. When you run "grunt serve --themes=all:all", the browser will show the Theme Builder running locally, which is what you want to have happen so that you can start building your themes. 2. Theming. At this point you should see this and now you can choose a combination of different buttons on the left to get to the theme that you want to base your own theme off of. Below, notice I am working on "web" and "mytheme": Now, look at the Palette in the left column, for example, notice the first color is "$interaction1Color". In "src/themes/mytheme/web", go to "_mytheme.web.settings.scss" and look for "$interaction1Color", which you'll see is listed as follows: // $interaction1Color: #0572ce !default; Change the above to the below: $interaction1Color: red !default; When you make the change above and save it, automatically the CSS will be generated, and the browser will refresh, showing you the change you've made: When the above works for you, get the style guide that you're wanting to integrate into your Oracle JET application. Take note of the color codes and other styles and continue tweaking the SCSS files, using the Theme Builder, as described above, to check the changes you're making.  3. Usage. At some point, you'll want to see how the CSS files you're generating look in your own Oracle JET application. Follow the earlier blog entry, The Mechanics of Theming Oracle JET Applications, for details on how to set up theming support within your Oracle JET application. Once you've set that up, copy the CSS files that have been generated in "themes/mytheme/web", in this case, into the relevant theme folder in your own application. Now, isn't this simply an awesome tool? Following the steps above, all the UI elements provided by Oracle JET can be restyled to match the style guidelines of your choice. Note that you do not have to use the "mytheme" theme as a starting point, there are other themes too, which might more closely resemble the end point you're trying to achieve. Pick the one that's closest to your intended theme and then start tweaking it as described in step 2 above. 

A lot of organizations have style guidelines for their browser apps. I.e., these style guidelines consist of colors, sizes, icons, etc, normally supported by CSS stylesheets. Wouldn't it be nice...

Oracle JET

From ojNavigationList to ojButton

The Oracle JET "navbar" template provides a navigation bar for switching between Oracle JET modules: Let's remove that navigation bar and replace it with buttons: By means of the above, you have more control over the navigation in your page, e.g., you can include validation rules, which will be handled in a future blog entry, etc. Plus, via this mechanism you have the basis of a wizard-like step-through sequence enabling the user to work through a number of different screens. To get the basics shown above, i.e., no navigation bar and buttons instead, do the following. 1. In "index.html", remove the DIV element that has its role set to "navigation". Now the navigation bar is gone. 2. In the view of all your Oracle JET modules, include your buttons, as follows: <button class="oj-button-primary" data-bind="click: next, ojComponent: { component: 'ojButton', label: 'Next' }"></button><button class="oj-button-primary" data-bind="click: prev, ojComponent: { component: 'ojButton', label: 'Prev' }"></button> 3. In the viewModel of all your Oracle JET modules, reference the "appController.js" and use the router to switch to the page applicable to a specific button, e.g., here you see the content of "dashboard.js": define(['ojs/ojcore', 'knockout', 'jquery', 'appController'], function(oj, ko, $, app) { function DashboardViewModel() { var self = this; self.next = function() { app.router.go('incidents'); }; self.prev = function() { app.router.go('about'); }; } return new DashboardViewModel(); }); That's it, you now have nicely styled (thanks to the Oracle JET CSS classes) buttons for navigating through your Oracle JET modules.

The Oracle JET "navbar" template provides a navigation bar for switching between Oracle JET modules: Let's remove that navigation bar and replace it with buttons: By means of the above, you have more...

Oracle JET

React.js and Oracle JET (Part 2)

Following on from part 1, the next step is to have support for React JSX in the context of our Oracle JET application. The RequireJS plugin below works perfectly in the context of Oracle JET applications, as outlined below: https://github.com/podio/requirejs-react-jsx To use the above in your Oracle JET applications: Include the above plugin in "bower.json": "requirejs-react-jsx": "1.0.2" Add the following to the bootstrap file (i.e., main.js) paths directive: 'babel': 'libs/requirejs-react-jsx/babel-5.8.34.min', 'jsx': 'libs/requirejs-react-jsx/jsx' Create a file named "app.jsx", e.g., in a folder named "components", with this content, i.e., this defines a simple React component in a JSX file: define(function (require) { var React = require('react'); var ReactDOM = require('react-dom'); function App() { this.HelloWorld = React.createClass({ render: function () { return ( <div> <h1>Hello, React!!!</h1> </div> ); } }); } App.prototype.init = function () { ReactDOM.render( <this.HelloWorld />, document.getElementById('root') ); }; return App;}); Now, let's use the above React component in one of our Oracle JET modules: define(['ojs/ojcore', 'knockout', 'jsx!components/app'], function (oj, ko, App) { function HomeViewModel() { var self = this; self.handleAttached = function (info) { var app = new App(); app.init(); }; } return new HomeViewModel(); }); Finally, let's render the view, i.e., this is the "home.html" for the above "home.js": <div id="root"></div> That's it, the first React component expressed in JSX in an Oracle JET application. Here's a variation whereby you use a property in your JSX component, where the value changes based on a timer: define(function (require) { var React = require('react'); var ReactDOM = require('react-dom'); var messages = ['Hello, World', 'Hello, Planet', 'Hello, Universe']; function App() { this.Greeting = React.createClass({ render: function () { return ( <p>{this.props.message}</p> ) } }); } App.prototype.init = function () { this.repeat(); }; App.prototype.repeat = function () { var ctx = this; var randomMessage = messages[Math.floor((Math.random() * 3))]; ReactDOM.render( <this.Greeting message={randomMessage}/>, document.getElementById('root') ); setTimeout(function(){ctx.repeat()}, 1000); }; return App; References:  https://www.sitepoint.com/getting-started-react-jsx/ http://stackoverflow.com/questions/3264739/image-change-every-30-seconds-loop

Following on from part 1, the next step is to have support for React JSX in the context of our Oracle JET application. The RequireJS plugin below works perfectly in the context of Oracle JET...

Top 5 Features of Oracle Application Container Cloud

I asked Shaun Smith, product manager of Oracle Application Container Cloud (ACC), what he considers its top 5 features to be. He responded with this list: Polyglot platform. Use the language of your choice. Today we have Java SE, Node.js, PHP, and will be adding support for Java EE WAR deployment, as well as Python and Ruby. We're open to supporting other languages if the demand is there. Open platform. Run anything. This is an ideal platform for running open source stacks and containers like Tomcat, Jetty, Express, etc. Elastic. Applications can be scaled in/out and up/down to meet demand. Auto-scaling is coming soon so that, based on metrics, scaling actions can be triggered. Integrated with Oracle Developer Cloud Service. Handy for end-to-end continuous integration, build, test, and deployment. Integrated with Oracle Public Cloud ecosystem. This combination is ideal for building cloud native (microservice style) applications that need messaging, storage, etc. Also, Java SE Advanced is included, i.e., you're able to interact with Flight Recorder under the Admin tab.  Once there, you'll see "Recordings".  The help text explains what you can do. The best strategy in production is to turn on Flight Recorder in "continuous" mode so that it is recording all the time, keeping a  user-specified amount of data/minutes of data. Then, in ACCS, one can trigger the dump of this data if any anomalous behavior is detected. From ACCS, you can download Flight Recorder data dumps and open in Mission Control on your desktop. Watch Shaun in action here, where he provides a really great overview of the key features of ACC:

I asked Shaun Smith, product manager of Oracle Application Container Cloud (ACC), what he considers its top 5 features to be. He responded with this list: Polyglot platform. Use the language of your...

NetBeans

Updates to Oracle JET MOOC

Before JavaOne/OpenWorld this year, we ran the first session of the Oracle JET MOOC (massive open on-line course). The aim was to prepare a large number of developers all at the same time about enterprise JavaScript in the context of Oracle JET, i.e., Oracle's free and open source JavaScript platform. The MOOC is on-line, self paced, three weeks, and focused on 10 YouTube clips per week for three weeks, with many homework tasks, quizzes, and a certificate of completion at the end. We ran the second session after JavaOne/OpenWorld and have started the third session today. In the process, thousands of developers have been introducing themselves to Oracle JET. Since the time when we put the MOOC together in August, quite a few changes have taken place and we've tried to update some of the parts of the MOOC as a result. If we were to be really thorough about it, we'd need to re-record absolutely every part, which is not really doable. So, here's an overview of all the changes and where parts of the MOOC are impacted. Oracle JET Releases. Oracle JET 2.1.0 and Oracle JET 2.2.0. When we put the MOOC together, Oracle JET was at version 2.0.2. In the meantime, both 2.1.0 and 2.2.0 have been released. Read about 2.1.0 here and about 2.2.0 here. To ensure that the latest version of Oracle JET is always downloaded via "bower.json", we've changed the hardcode "2.0.2" in the GitHub samples to "latest", which will mean that in some cases you'll see different libraries and different versions of libraries in the YouTube clips than you'll see in your own code when working with Oracle JET templates. Composite Component Architecture. The biggest impact of the above releases on the MOOC is the introduction of the Composite Component Architecture introduced in Oracle JET 2.1.0. Read about there here in the Oracle JET Cookbook. That topic was already mentioned in the MOOC, in Lesson 3, Part 1, where we look at integration with 3rd party components. However, the code sample for that part has been updated to include all the code samples from the Cookbook dealing with composite components. Go here to look at that code sample. Oracle JET Templates. A big impact on the MOOC is that the "Oracle JET QuickStart Basic" wizard in NetBeans IDE now uses the "navdrawer" template. Read about that here. Some parts of the MOOC have been updated so that, especially at the start of the MOOC, you're not confused about the difference in the code you'll see being generated when you work through the tasks and the code you'll see in the YouTube clips. In Lesson 1, part 1, 7, 8, and 9 have all been reworked a bit, so that you see "navdrawer" code in the YouTube clips, in most cases. However, the code on GitHub continues to use the earlier templates and so on, so that, if you want to have the old structure and so on, in case you want that for reference or to understand something you're seeing in the YouTube clips, just use the code in the GitHub repos. NetBeans IDE 8.2. NetBeans IDE itself has seen a new release since the initial release of the MOOC. In most of the MOOC, NetBeans IDE 8.1 is used, though in some of the updated parts, the latest release, which is NetBeans IDE 8.2 is used. The only difference is that in NetBeans IDE 8.2, you do NOT need to install the Oracle JET Support plugin, since that is now a standard part of NetBeans IDE. If you are using NetBeans IDE 8.2, do NOT go to the Plugin Manager and do NOT search for the Oracle JET Support plugin. Instead, simply use the "Oracle JET QuickStart Basic" template in "Samples | HTML5/JavaScript", which you will immediately find to be available. Hybrid Oracle JET Generator for NetBeans IDE. The generator in NetBeans IDE for hybrid mobile applications, which is used in Lesson 2, Part 10, has been rewritten. That part of the MOOC will be updated during this week. Read about the changed generator here. Samples on GitHub. There are several new and updated samples in the Oracle JET MOOC GitHub repository. For example, Part-001 now contains all the code shown in the related YouTube clip, Part-012 contains a lot more data visualization samples, including usage of ojThematicMap, Part-014 contains the complete MovieFactory sample, Part-021 contains all the composite components from the Oracle JET Cookbook, and Part-022 includes samples for integrating with the Application Container Cloud. Some other parts of the Oracle JET MOOC may be changed/updated during the coming weeks, though the above points are the main areas where the differences lie between the original MOOC as published in August and the current status of Oracle JET and the MOOC itself.

Before JavaOne/OpenWorld this year, we ran the first session of the Oracle JET MOOC (massive open on-line course). The aim was to prepare a large number of developers all at the same time...

Join NetBeans on Slack: https://netbeans.signup.team

One of the coolest recent developments in the NetBeans ecosystem is the establishment of the NetBeans Slack channel. We've only got this going over the past few weeks and there's a few hundred already registered and active. What's the big deal and what's so great about Slack? Well, to me, and to how I'm using it, is that I see it as a modernized version of IRC, with the benefit of direct and quick interaction, e.g., I was holding off on publishing the new release of the One Click Open Sesame plugin because I wasn't completely sure about what new features Chris and Benno had implemented and so I quickly wrote back and forth with Chris on Slack and very quickly had my questions cleared up, rather than e-mailing back and forth for a week or two before getting the story straight. So, want quick answers to your questions, want to resolve something without too much hassle? Join the NetBeans Slack channels and, of course, the more that join the more useful it will be since there'll be more knowledge going around. Go here to get started, i.e., simply enter your e-mail address and you're good to go: https://netbeans.signup.team/ And this is what the UI looks like, for me:  Nice and neat and efficient. Thanks Wade and Chris and others for working on this and making this already a big success with the potential for much more! 

One of the coolest recent developments in the NetBeans ecosystem is the establishment of the NetBeans Slack channel. We've only got this going over the past few weeks and there's a few hundred already...

No More Double-Clicking To Open Files In NetBeans!

Probably to most NetBeans users, the need to double-click a file to open it has become part of your DNA. However, consider the thought of not needing to double-click anymore. Simply select a file and it opens. That's what the "One Click Open Sesame" plugin aims to achieve for you: http://plugins.netbeans.org/plugin/53723/one-click-open-sesame The project was started some time ago here: https://github.com/GeertjanWielenga/OneClickOpenSesame Chris Lenz (@Chrizzly42) and Benno Markiewicz (@benM4) in Leipzig worked on it quite a bit over the past weeks and now usability has improved significantly: The opened file does not get the focus anymore. Instead, focus stays back in the view where the click came from (Projects window, Files window, or Favorites window). This gives you the benefit that you can navigate through your view with your arrow keys and the focus will not change to the file that opens. A fixed delay is added, of about 400ms, while in the next version the aim is to make it configurable, so that you can navigate through the view with your arrow keys and files don't open instantly and only after the specified delay. An open document is reused while navigating through the view. If you set the focus to an open document and go back to the view, a new document will be created. Awesome and I am using this constantly now. Well, since yesterday when I tried it out, and it's really nice. If you encounter any issues, go to the GitHub location above and report them! Many thanks to Benno and Chris!

Probably to most NetBeans users, the need to double-click a file to open it has become part of your DNA. However, consider the thought of not needing to double-click anymore. Simply select a file and...

Handy Tools for Working with CSS

Here's an overview of CSS tools in NetBeans that I've found to be quite useful. Below, in the first example, the value of "class" is set to "foo", which does not exist in any of the available CSS stylesheets. NetBeans offers to create the rule in a stylesheet of my choosing and to import that stylesheet into my HTML file: Below, the value of "id" is "foo", which doesn't exist in any of the stylesheets. NetBeans suggests to create it for you and import the related stylesheet: In this case, no stylesheets exist and NetBeans offers to create a new stylesheet in which it will write the currently undefined rule: Below, you can see I am using code completion and am shown all the available rules for the "class" attribute, from all the stylesheets, regardless of whether those stylesheets have been imported: In the scenario below, I hold down the Ctrl key and click on "foo", i.e., the value of "class", because I want to jump to the definition of "foo" in the stylesheet in which it is defined. However, NetBeans tells me that there are two different "foo" rules available. One of those is from a stylesheet that has been imported and the other is from an unrelated stylesheet, i.e., one that has not yet been imported: And here I have imported the previously unrelated stylesheet so that now NetBeans shows me both stylesheets where "foo" is defined and lets me choose which one should be opened. Pretty handy!Earlier articles on this theme:Editor Tools for CSS in NetBeans IDE (Part 1) Editor Tools for CSS in NetBeans IDE (Part 2)

Here's an overview of CSS tools in NetBeans that I've found to be quite useful. Below, in the first example, the value of "class" is set to "foo", which does not exist in any of the available CSS...

UI Component Extensions for ABCS (Part 4: Drop Dialogs)

The next feature to be added to your UI component extension is a Drop Dialog, i.e., when the citizen developer drags and drops your component, a small dialog will appear to fill in some of the values in the component to override the defaults the component gives you:To achieve the above, do the following. Create the View. In your 'templates' folder, add a new HTML file, with any name, such as "popup.html", with this content: <div> <label for="componentdropCustomizer-label">First Name</label> <input id="componentdropCustomizer-label" type="text" placeholder="Enter First Name" data-bind="ojComponent: { component: 'ojInputText', value: text1 }"> <label for="componentdropCustomizer-label">Last Name</label> <input id="componentdropCustomizer-label" type="text" placeholder="Enter Last Name" data-bind="ojComponent: { component: 'ojInputText', value: text2 }"></div><div> <button data-bind="ojComponent: { component: 'ojButton', label: 'Finish' }, click: finish"> </button> <button data-bind="ojComponent: { component: 'ojButton', label: 'Cancel' }, click: cancel"> </button></div> Add the Business Logic. All the business logic for this scenario is found in the 'Creator.js' file. Rewrite the 'define' block, to load the 'popup.html' file and provide the API you'll be needing: define([ 'com.greeting/js/Constants', 'components.dt/js/api/ComponentFactory', 'components.dt/js/spi/creators/CreatorType', 'components.dt/js/spi/creators/DropPopupController', 'text!com.greeting/templates/popup.html'], function(Constants, ComponentFactory, CreatorType, DropPopupController, popupMarkup) { Change the return value of "getType" to CreatorType.POPUP. Below 'createView', define 'getDropPopupController': ComponentCreator.prototype.getDropPopupController = function (view) { // right after the view is created, the infrastructure calls this method // to get an instance of DropPopupController, providing the html markup, // view model, and the callback implementation for the popup. var myPopupViewModel = this._createModel(); var customizer = new ComponentCreator.MyDropCustomizer(view, myPopupViewModel); // create an instance of DropPopupController with required popup model and markup. var controller = new DropPopupController(myPopupViewModel, popupMarkup, customizer); // attach a finish handler to your model and dismiss the popup // when the model says so using an API finish method. myPopupViewModel.finishHandler = function (result) { controller.finish(result); }; return controller;}; Below the above, you need all of this: ComponentCreator.prototype._createModel = function () { var model = { text1: ko.observable(), text2: ko.observable(), finishHandler: undefined, finish: function () { this.finishHandler(true); }, cancel: function () { this.finishHandler(false); } }; return model;};var MyDropCustomizer = function (view, model) { this._view = view; this._model = model;};MyDropCustomizer.prototype.opened = function () { // you can do something useful here};MyDropCustomizer.prototype.closed = function (accepted) { if (accepted) { // popup was accepted and closed, let's update view properties this._view.getProperties().setValue('text1', this._model.text1()); this._view.getProperties().setValue('text2', this._model.text2()); } // do not forget to return a promise resolving to the view instance return Promise.resolve(this._view);};ComponentCreator.MyDropCustomizer = MyDropCustomizer; And now, when you drag and drop, you should see a small dialog for filling in initial values.

The next feature to be added to your UI component extension is a Drop Dialog, i.e., when the citizen developer drags and drops your component, a small dialog will appear to fill in some of the...

UI Component Extensions for ABCS (Part 3: Property Inspectors)

The next step is to give your citizen developers a Property Inspector for the UI component extension you're creating for them. Let's go through the whole process from start to finish, imagining you've gone through the various dialogs in yesterday's blog entry and you now have a UI component extension generated for you from the "blackbox" template. We'll use the "Hello World" scenario from the Knockout site for this example.  Define the UI Component Extension. In 'blackbox.html', replace the content between the 'div' tags with the following: <p>First name: <input data-bind="value: firstName" /></p><p>Last name: <input data-bind="value: lastName" /></p><h2>Hello, <span data-bind="text: fullName"> </span>!</h2> In 'Initialiser.js', rewrite the 'ko.components.register' expression to the following and note that "text1" and "text2" do not exist yet, we'll create them in the next steps below: ko.components.register(Constants.COMPONENT_ID, { viewModel: function (params) { var self = this; self.firstName = ko.observable(params.text1); self.lastName = ko.observable(params.text2); self.fullName = ko.pureComputed(function () { return self.firstName() + " " + self.lastName(); }, this); }, template: template}); You now have your UI component extension and should be able to reload it into your Page Designer. From there, you can drag and drop it into the canvas. In the Property Inspector, on the right side of the Page Designer, notice the "Initial Value" field, which has its value set to "Hello World!" We're going to rewrite that to a "First Name" property, and connect it to the "First Name" field in the UI component extension, so that your citizen developer can set a default first name whenever they've dragged our UI component extension into the canvas. Reuse the Default PropertyThe template you used to create your extension includes a property that we can use as the basis of our own property, after which we can connect it to our component. To do this, we'll work down the list of files in the "js" folder, one by one and rewrite bits and pieces as needed: Constants.js. Change the name of PROPERTY_ID_TEXT to PROPERTY_ID_FIRST and its value to 'text1'. Change the name of DEFAULT_MESSAGE to DEFAULT_FIRST and its value to 'Planet'. Creator.js. In 'ComponentCreator.prototype.createView', change the property 'text' to 'text1' and DEFAULT_MESSAGE to DEFAULT_FIRST. (Tip: In Creator.js, change the "2" for "minWidth" to a different integer if you want the component, when it is dropped, to have a different width.) PropertyInspectorViewModel. In the function, rewrite 'text' everywhere to 'text1' and PROPERTY_ID_TEXT to PROPERTY_ID_FIRST. ViewGenerator.js. Change 'text' to 'text1'. Change all usages of 'message' to 'text1'. Next, we'll work in the "html" folder: blackboxPI.html. Rewrite 'Initial Value' to 'First Name', rewrite 'text' to 'text1'. blackboxWrapper.html. Change the two usages of 'message' to 'text1'. Use the Property InspectorOn the Extensions page, click "Reload Extensions", go back to the Page Designer, drag-and-drop your component into the canvas and then notice that you're able to fill in and change the default first name in the Property Inspector: Write a Property from ScratchNow that we've rewritten the default property and, essentially, refactored it for our purposes, let's write one ourselves. We'll write a "text2" property so that the Last Name will be customizable from the Property Inspector. Constants.js. Define PROPERTY_ID_LAST and its value to 'text2'. Define DEFAULT_FIRST and set its value to 'World'. Creator.js. In 'ComponentCreator.prototype.createView', add a comma after the definition of 'text1' and add 'text2', with its value set to DEFAULT_LAST. PropertyInspectorViewModel. Copy 'self.text1' and related code, rename everything to 'text2' and PROPERTY_ID_LAST. ViewGenerator.js. Copy the various 'text1' statements and paste them and rename to 'text2'. And then include 'text2' in the 'ViewGeneratorSupport.applyMap' construct, as shown below: var val = ViewGeneratorSupport.applyMap(template, { id: view.getId(), elementName: Constants.COMPONENT_ID, text1: text1, text2: text2}); Next, we'll work in the "html" folder: blackboxPI.html. Copy the whole "First Name" section, paste it, rename it to "Last Name", and "text1" to "text2". blackboxWrapper.html. Rewrite to include your new parameter: <$elementName$ id="$id$" params="{text1: '$text1$', text2: '$text2$'}"></$elementName$> Use the Property Inspector. When you reload extensions, go back to the Page Designer, and drag-and-drop your component again, you'll see that you can now customize both of the properties. Also note that, thanks to your code in ViewGenerator.js, you have error handling built in: What you've learned is how to extend your UI component extension to include support for the Property Inspector.

The next step is to give your citizen developers a Property Inspector for the UI component extension you're creating for them. Let's go through the whole process from start to finish, imagining you've...

UI Component Extensions for ABCS (Part 2: Reusable Components)

What we have so far, after part 1, is a custom component. What's we'd like to have is an extension to ABCS so that the component can be dragged and dropped into any application created in ABCS. In the left side of ABCS, below, provided by the hamburger button in the top left, you see an item called "Extensions": Now you're on the page below where, as you can see in the left side, you can create new UI components: Fill in the details below, which is a dialog that appears after you click the button above: Click Template above and then click "blackbox" below. When you click OK above and wait some seconds, a new UI component will be created for you, as shown below. Use the Sources tab to edit the code in the UI component. The business logic goes into "Initialiser.js", while the view goes into "blackbox.html": The other files provide related support, for example, in "Constants.js", you can tweak the display name of the new UI component. There's also files dealing with the drop dialog and property inspector that can be extended. Back in the Page Designer, you'll see your new UI component, named "Black Box" by default (below you can see I changed it to "Greeting" because I edited the "Constants.js" file), in the "Common" category, from where you can drag and drop it into the canvas. You can drag that new UI component into your canvas, below you can see I have done this twice: There's syntax coloring to help you, when editing your UI component in the browser above. On the other hand, you can also export the extension to a ZIP file and open the source files into an editor, such as NetBeans IDE, edit the files there, ZIP them up again, and upload them in the dialog above. Further reading: UI Extensions in Application Builder Cloud Service

What we have so far, after part 1, is a custom component. What's we'd like to have is an extension to ABCS so that the component can be dragged and dropped into any application created in ABCS. In the...

NetBeans

UI Component Extensions for ABCS (Part 1: Custom Components)

Once you're comfortable with Oracle JET, consider taking the next step: Application Builder Cloud Service (ABCS). No, ABCS isn't simply a drag-and-drop development environment for citizen developers. Instead, it's an architecture for software developers to establish a drag-and-drop development environment for citizen developers! In other words, you can extend ABCS specifically for your business developers, with components that you define yourself... using Oracle JET. Or, more exactly, by creating Knockout components, which underpin the concepts used in Oracle JET. Below, you see the "Hello World" scenario from the Knockout tutorials. It is part of an application created in ABCS by means of a "Custom Code" component. In the below, look on the left side in the palette, at the end, where you'll see "Custom Code":  Drag that into the canvas and then automatically the editors you see below open up, so that you can define your custom component: Above, you can see that there's an HTML view and business logic in JavaScript, using a "define" block provided by Require.js, with data binding made available by Knockout.js. With your Oracle JET background, or with a generic Knockout background, you should immediately know what to do with the above. I.e., replace the boilerplate code with something like the above, in other words, with the view and viewModel of your custom component, as shown above for the "Hello World" scenario. And above you see the application deployed directly from ABCS. Really neat, the concept of "developing for the Cloud, in the Cloud". Further reading: http://likeahouseafire.com/2016/09/17/custom-code-components-in-abcs/ Continue to part 2.

Once you're comfortable with Oracle JET, consider taking the next step: Application Builder Cloud Service (ABCS). No, ABCS isn't simply a drag-and-drop development environment for citizen developers....

NetBeans

NetBeans and Apache (Part 1)

Now that NetBeans is in the Apache Incubator, here are some feelings from my side on the process and on where we currently are. Philosophically always Apache. I've been involved with NetBeans since about 2004, when I joined Sun Microsystems in Prague. It was always the case that with NetBeans we were trying to do something bigger than serve the interests of a specific commercial entity—NetBeans has always been a platform for innovation and sharing. It's always been free and open source and it has always focused on enabling software developers all over the world to simply get started quickly and easily with Java, primarily, and over the years with other languages and technologies too. While there have been benefits to being tightly coupled to specific commercial interests, that coupling has never been part of the DNA of NetBeans. Philosophically, NetBeans has always been an Apache project and has always behaved in that way, i.e., it's always been primarily about individuals rather than commercial interests. Continual demands for more open participation. Over the years, there's been a clamoring from the community for the commercial interests behind NetBeans, i.e., Sun Microsystems and then Oracle, to open up the contribution and governance models of NetBeans to enable direct and equal participation, almost as if its users have seen NetBeans as something that always should have been treated by its commercial sponsor like an Apache project all along. The contribution and governance models have been opaque, to say the least, and it's always been the commercial sponsor (i.e., Sun and later Oracle) that has driven the NetBeans roadmap—and in the cases where community interaction on roadmap etc was slightly opened up, for specific releases, it was always the commercial sponsor that made the decision to enable that to happen. However, amazingly, despite all that, NetBeans has built up a very active and enthusiastic community all over the world, with mailing lists, forums, an advocacy group (NetBeans Dream Team), monthly NetBeans events around the world, broad usage across the industry, high usage in education, etc. In NetBeans, its users have always seen a range of high quality free tools and technologies, and an inspiring philosophy of sharing and innovation, beyond those that the commercial sponsor has found it important to promote. Shared leadership, shared responsibility. Oracle's interests are broad and diverse. Within its specific scope of interest, it is not a tool provider. Nevertheless, Oracle has a range of investments in a variety of different tools, all at the same time. That makes perfect sense, when you examine each instance of that. In some cases, the investments are historical and in others strategic. Together with that, consider how the community has changed over the years and how much stronger and cohesive open source has become. Would it not make sense to share the leadership of projects across multiple entities rather than having it locked into one specific commercial sponsor? And is that train of thought not exactly in line with the clamoring for more involvement and engagement with the community? What better way, then, than to open up the contribution and governance model via the Apache Software Foundation? Everyone who is invested in NetBeans continues to be invested in NetBeans, while its roadmap, governance model, etc, are shared between all those different entities within a model that has proven to work well. And that's where we are right now. The NetBeans proposal has been accepted and NetBeans is now in the Apache Incubator. Many things need to happen before NetBeans graduates and becomes a Top Level Project. The hurdles to cross have been examined on all sides and none seem unsolvable. There's a long journey ahead (many months at least) at the end of which the philosophy underpinning NetBeans will match the structures used to govern it. Sometimes there are win/win situations in the world and this surely is one of them. Further reading: https://wiki.apache.org/incubator/NetBeansProposal

Now that NetBeans is in the Apache Incubator, here are some feelings from my side on the process and on where we currently are. Philosophically always Apache. I've been involved with NetBeans since...

Top 5 Favorite NetBeans IDE 8.2 Features

With the release of NetBeans IDE 8.2, here are my favorite features! The Release Itself. It's always great to have a new release, a fresh start, new development environment, and to me a new release always feels faster and snappier than the last. Maybe because I simply hope this is the case or maybe because it simply is true. Well, with bunches of bugs fixed, and performance standards to comply with, a new NetBeans release should at least be as performant as the previous, and with the bugs fixed and so on, could justifiably be presumed to work even smoother and snappier than the previous release. So far, to me, it does feel even smoother and snappier than before. Multiple Cursor Support. I don't know how often I'm going to need to have multiple cursors, I can't imagine needing more than two at the same time. Still, great to have them, it certainly makes NetBeans even more fun and versatile, and, at the same time, this was one of the top P1 issues in NetBeans that users have been asking for for many years (and some even abandoned NetBeans specifically because of lack of multiple cursor support). So, hurray! Oracle JET Features. No more need to install a plugin to use Oracle JET. For the first time, Oracle JET is now a full feature of NetBeans IDE. The project templates, especially, "Quick Start Basic", and the code completion for Oracle JET components, are very helpful and it's great to not have to do anything special to get these features. Bling Bling. OK, so I'm not a heavy Docker user, nor do I use ECMAScript 6 (and even experimental ECMAScript 7) features right now. Still, though, it's great to have the latest cutting edgiest things, which really is just mostly bling bling for me, though nice to have available as needed when needed. :-) Darcula. I love the Darcula plugin and I use it all the time. While it's not available in the Plugin Manager right now, yet, for NetBeans IDE 8.2, you can go to the NetBeans Plugin Portal and just download the 8.1 version and it will work fine in 8.2: http://plugins.netbeans.org/plugin/62424/darcula-laf-for-netbeans. Not all the NetBeans IDE 8.1 plugins will work as simply as this, though some will, just give it a try. Other features and complete list are here: https://netbeans.org/community/releases/82/.

With the release of NetBeans IDE 8.2, here are my favorite features! The Release Itself. It's always great to have a new release, a fresh start, new development environment, and to me a new release...

NetBeans

Minimal Oracle JET Composite Component

Let's say you have a suite of Cloud applications and you want them to display customers in a standardized way: If that's your business scenario, then Oracle JET composite components are a perfect fit. Here's what an absolutely minimal Oracle JET composite component looks like:  The above is really trivial. Here's the content of "customer.html": <h2 data-bind="text: $props.name"></h2><h4 data-bind="text: $props.city"></<h4<hr> Here's "customer.json": { "properties": { "name": { "description": "Customer name.", "type": "string" }, "city": { "description": "Customer location.", "type": "string" } }} About the properties above, see the below: http://www.oracle.com/webfolder/technetwork/jet/jsdocs/oj.Composite.html#metadata And here's "loader.js", which connects the above two together and provides "customer" as a new HTML element: define(['ojs/ojcore', 'text!./customer.html', 'text!./customer.json', 'ojs/ojcomposite'], function(oj, view, metadata) { oj.Composite.register('customer', { view: {inline: view}, metadata: {inline: JSON.parse(metadata)} }); }); In a more complex scenario, you're also able to include CSS stylesheets and business logic defined in JavaScript, as outlined in an earlier blog entry on this topic.  OK, now ZIP up that folder, send it to whoever is working on other Cloud applications that need to make use of the "customer" element, which they can use as follows (in e.g., "library.js") after unzipping that ZIP into the relevant folder in their application: define(['ojs/ojcore', 'knockout', 'ojs/ojcomposite','jet-composites/customer/loader'], function (oj, ko) { function libraryContentViewModel() { var self = this; self.customers = [ {name: 'Billy Bob Thornton', city: 'New York'}, {name: 'Brad Pitt', city: 'Hollywood'}, {name: 'Val Kilmer', city: 'Seattle'} ]; } return new libraryContentViewModel(); }); All that the above does is load the "loader.js", include "ojs/ojcomposite" so that Oracle JET composite components are supported, and define a "customer" array. Here's the view (e.g., "library.html") of the above viewModel, using the "customer" HTML element provided by the composite component: <!-- ko foreach: customers --><customer name="{{name}}" city="{{city}}"></customer><!-- /ko --> That's pretty neat and, guess what, Oracle JET components conform to the Web Components specification, except for the Shadow DOM, which is not supported.

Let's say you have a suite of Cloud applications and you want them to display customers in a standardized way: If that's your business scenario, then Oracle JET composite components are a perfect fit....

NetBeans

Getting Started with Oracle JET Composite Components

I worked with JB Brock yesterday on setting up and using Oracle JET's new Composite Component Architecture. The aim of it all is to have reusable components that enable you to define your own HTML elements, like this, for example: <!-- ko foreach: employees --><demo-card class="oj-flex-item" name="{{name}}" avatar="{{avatar}}" work-title="{{title}}" work-number="{{work}}" email="{{email}}" background-image="{{backgroundImage}}"></demo-card><!-- /ko --> Above you see a Knockout for-each loop which iterates through 'employees' and creates a new DOM element named "demo-card" for each of them. The above is in the view, e.g., in "home.html", while "home.js", i.e., the viewModel, defines "employees" as follows: self.employees = [ { name: 'Deb Raphaely', avatar: 'images/composites/debraphaely.png', title: 'Purchasing Director', work: '5171278899', email: 'deb.raphaely@oracle.com', backgroundImage: 'images/composites/card-background_1.png' }, { name: 'Adam Fripp', avatar: null, title: 'IT Manager', work: '6501232234', email: 'adam.fripp@oracle.com', backgroundImage: null }]; In this case, the definition of "demo-card" transforms the above snippets into a view that looks like this, with a "demo-card" for each of the two employees defined above: When the user clicks on each "demo-card", it flips around, and you see the other side of the card, which presents more information about the employee. (See the above live here.) OK, so where does "demo-card" come from? Well, in "home.js", i.e., the same place where the 'employees' above are defined, my "define" block looks like this: define(['ojs/ojcore', 'knockout', 'ojs/ojcomposite', 'jet-composites/demo-card/loader'], Notice, first of all, that "ojs/ojcomposite" is included, which is new in Oracle JET 2.1.0. It defines composite components. Then, notice that something is loaded from a folder named 'jet-composites', which is a folder that looks like this: Notice "demo-card" is a folder in there, which looks like this: So, what you have is an infrastructure for creating encapsulated components, defined by JavaScript, HTML, and CSS, with properties defined in JSON. Once you have a composite component, you have created a new HTML element, in this case "demo-card", defined by "loader.js", which ties everything together: define(['ojs/ojcore', 'text!./demo-card.html', './demo-card', 'text!./demo-card.json', 'css!./demo-card', 'ojs/ojcomposite'], function(oj, view, viewModel, metadata) { oj.Composite.register('demo-card', { view: {inline: view}, viewModel: {inline: viewModel}, metadata: {inline: JSON.parse(metadata)} }); }); You can pass the composite component in a ZIP file to whoever needs to use it, who unzips the ZIP into a folder, and loads it into their viewModel as described earlier, via the "define" block of the viewModel. You can see composite components as plugins for developers, i.e., not for the end user of the app, but for the development team, enabling features to be packaged, shared, and reused. Here is a more complex example, which is a composite component called "demo-memory-game" which itself makes use of a composite component called "demo-memory-card": All the details, including all the code described above, are here in the Oracle JET Cookbook: http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=composite&demo=basic Note: When loading a composite component that includes a CSS file, remember to add 'css': 'libs/require-css/css' in your main.js file, i.e., in the "paths" section of your "requirejs.config", otherwise the composite component loader crashes when trying to execute the loading of the CSS, e.g., the 'css!./demo-card' piece. Thanks Janis Krasemann on Twitter for pointing this out. That is something I indeed did do but forgot to mention here. :-)

I worked with JB Brock yesterday on setting up and using Oracle JET's new Composite Component Architecture. The aim of it all is to have reusable components that enable you to define your own HTML...

Finegrained JShell Integration in NetBeans IDE

In addition to the generic JShell integration in NetBeans, discussed yesterday, there's more finegrained support enabling project-specific JShell snippets to be run. That means, depending on how you organize your life, no "build" will be needed anymore when you try out your code. Just hack a snippet together, run it in JShell, when/if it works, move it to your project.Each project, whether Maven-based or Ant-based, will have an "Execute Java Shell" menu item, which is shown below. When that menu item is clicked, a new VM is created, which has access to the project's path, including project-specific JShell snippets, as discussed below. Below you see a folder "nbproject/private/jshell-snippets", which contains JShell snippets that I know will be handy for experimenting with in the context of my project: Also, note that there's a folder called "startup", within "jshell-snippets", above. Anything in there will be executed automatically when the project-specific JShell starts up. In the case of Maven, you'll set a property in your POM, "org.netbeans.jshell.snippetsRoot", which points to a folder in which your snippets, including the optional "startup" folder, are found: <org.netbeans.jshell.snippetsRoot>src/jshell-snippets</org.netbeans.jshell.snippetsRoot> Once the project-specific JShell has started either via a Maven project or an Ant project, there's a small drop-down that shows an item for each of the JShell snippets, which can be run by clicking on them: Alternatively, you can do a Run/Debug project and then Run | Open Java Shell for Main Project, which connects to the VM where the project is run/debugged. The difference is the startup procedure. "Execute Java Shell" only starts the machine and waits for interaction from JShell, while "Open Java Shell" works with an existing process which starts as a regular application.

In addition to the generic JShell integration in NetBeans, discussed yesterday, there's more finegrained support enabling project-specific JShell snippets to be run. That means, depending on how you...

My JavaOne 2016

Here's where I'm speaking (in bold) some with others and some alone and what (I'm hoping) I'll definitely be attending (not in bold): Sunday: NetBeans Day Monday: 8:30 a.m. - 10:30 a.m. | Rapid Development Tools for Java EE 8 [TUT1869] | Hilton - Continental Ballroom 6 11:00 a.m. - 12:00 p.m. | Ten Essential Building Blocks of JavaScript in the Enterprise [CON6218] | Hilton - Plaza Room A 1:30 p.m. - 3:30 p.m. Booth 4:00 p.m. - 5:00 p.m. | How to Plug into NetBeans in 60 Minutes [CON5816] | Hilton - Continental Ballroom 7/8/9 7:00 p.m. - 7:45 p.m. | Java 9 Module System Support in the NetBeans IDE [BOF4512] | Hilton—Continental Ballroom 6 Tuesday: 11:00 p.m. - 12:00 p.m. | NetBeans RCP in Practice: An Ideal Platform for Scientific Computing [CON4439] | Hilton - Imperial Ballroom B 12:30 p.m. - 1:30 p.m. | Strategies for Loose Coupling in Large Java Desktop Applications [CON6219] | Hilton - Imperial Ballroom B 5:45 p.m. - 6:45 p.m. | Hands-on Lab: Learn the Basics of Oracle JavaScript Extension Toolkit [HOL5278] | Hotel Nikko - Nikko Ballroom III (3rd Floor) 7:00 p.m. - 9:00 p.m. |  Enterprise JavaScript with Oracle JavaScript Extension Toolkit [HOL7764] | Hilton - Franciscan Room C/D Wednesday: 11:00 a.m. - 11:45 a.m. | Oracle JavaScript Extension Toolkit: Open Source and Ready for You [CON5257] | Moscone West - 2016 13:00 a.m. - 14:00 a.m. | Depending on Vulnerable Libraries [CON6265] | Hilton - Golden Gate 2/315:00 a.m. - 16:00 a.m. | Safe Architecture Migration and Enforcement with Jackpot and Annotation Processors [CON5859] | Hilton - Continental Ballroom 7/8/9 16:30 a.m. - 17:30 p.m. | Ten Essential Building Blocks of JavaScript in the Enterprise [CON6218] | Hilton - Plaza Room A Upating the above, it is not complete yet.

Here's where I'm speaking (in bold) some with others and some alone and what (I'm hoping) I'll definitely be attending (not in bold): Sunday: NetBeans Day Monday:8:30 a.m. - 10:30 a.m. | Rapid...

Oracle JET

The Mechanics of Theming Oracle JET Applications

We have a requirement to have different themes for our Oracle JET application, "business" and "pleasure". The first will have images of serious business suits, the second will have party hats; the first will have grey/blue fonts and colors, the second will be polka dots or something. You want the themes to be able to be swapped in and out at build time. OK, that's the scenario. 1. Create the application. Let's imagine we start like this: yo oraclejet myapp --template=basic OK, we now have the "basic" template provided by the Oracle JET Yeoman generator and take note of the "themes" folder below, which is automatically available: 2. Install node-sass. In the "myapp" folder, we need to now run this to make the next steps possible, i.e., incorporate node-sass, a library that provides bindings for Node.js to LibSass, the C version of the popular Sass, enabling you to natively compile .scss files to css, at "incredible speed". yo oraclejet:add-sass 3. Create themes. Now, we run this in the "myapp" folder to create a new theme, note there are no quotes around the theme name: yo oraclejet:add-theme business We now have this, i.e., in the "src" folder, where you do all your coding work, there's now a "themes" folder, with placeholders for the "business" theme overrides on/changes to/extensions to the default "alta" theme: And let's create another one: yo oraclejet:add-theme pleasure Now, we have two themes in our "src" folder: 4. Build themes. Let's now build the Oracle JET application with our "business" theme: grunt build --theme=business Now we have, as expected, a "web" folder, where our application is built into, which now includes our "business" theme, while both our themes are added to the "themes" folder, so that we can see the themes that are available in one place. You could see the "themes" folder as a staging area, while within the "web" folder only the theme that will actually be served is shown: Note: grunt build --theme=<themeName>:<themePlatform> --theme=business:android, will build the app with "business" custom theme extending the android alta --theme=business, this will select the "business" theme with default, i.e., "web", platform  if no theme parameter is specified, default "alta" theme will be used to build the app   5. Serve up themed applications. Now, the time has come to serve up our themed application: grunt serve --theme=<themeName>:<themePlatform> --platform=<web | android | ios |windows> The above serves up the app using the <themeName>:<themePlatform> notation, comparable to described above for grunt build --theme=<themeName>:<themePlatform>. That's all. Now, with the mechanics out of the way, read the following: http://docs.oracle.com/middleware/jet210/jet/developer/GUID-0329F030-A317-42FC-8C1E-A0A82F5AF6AE.htm#JETDG268 http://www.oracle.com/webfolder/technetwork/jet/globalExamples-ThemeViewer.html http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=theming&demo=themename

We have a requirement to have different themes for our Oracle JET application, "business" and "pleasure". The first will have images of serious business suits, the second will have party hats; the...

NetBeans

Avoiding Hiccups in Building Oracle JET Applications

When using NetBeans IDE to work on an Oracle JET project installed using the Yeoman generator on the command line, the files in the "src" folder are incomplete without the build command being run. Of course, you can just enable the Grunt build task and that solves that issue. Just right-click on the project and choose Build: The first time you do this, you'll be prompted as follows: Say Yes and you'll be here (your version of the below may be different to mine since I'm using a development build of NetBeans IDE): Note that I checked the "Build Project" checkbox, which has "build" in there by default. When I click OK out of the dialog above, and then try to build the project again, I see the following in the Output window: "C:\nodejs\grunt.cmd" "build"Running "build" taskRunning "oraclejet-build:undefined" (oraclejet-build) task Oracle JET Grunt plugin Processing Grunt command... [Warning] Missing platform. Default to web. Theme Name:Platform - alta:web Theme Version - 2.1.0cleaning staging path.....copy files to staging directory.....copy finished...compiling sass....sass compile skipped...running theme injection task.....indexHtml theme path injection finished..running theme copy task.....theme copy finished...running injection task.....mainJs paths injection finished..Done.Done. At this point, you need to be very careful. The process above has created a "web" folder, as shown below: Note: The "web" folder is where things need to be "run" from to see the real app, while the source files should only be edited in the "src" folder. Be careful that you do not run into the issue of editing the "web" files and then losing your work when you do the next build. Be aware that the "web" folder is completely overwritten when you do a build. Only after you have done the build, can you do "grunt serve", which will serve up the application into the platform of choice, which is the browser by default.

When using NetBeans IDE to work on an Oracle JET project installed using the Yeoman generator on the command line, the files in the "src" folder are incomplete without the build command being run....

NetBeans

Application Templates in Oracle JET

Here's an overview of each of the Oracle JET application templates in Oracle JET 2.1.0.Note: Below each of the Yeoman generator commands below, you see how the project looks in NetBeans IDE. I.e., just go to File | Open Project, browse to the folder where you ran the commands below and you'll simply be able to open the project into NetBeans IDE. yo oraclejet app1 --template=blank yo oraclejet app2 --template=basic yo oraclejet app3 --template=navbar yo oraclejet app4 --template=navdrawer The "blank" template above is completely blank. It has Oracle JET wired up and a blank "index.html" content body. The starter templates, "basic", "navbar", and "navdrawer" are described in detail on the Oracle JET site here. Tip: If you're following the Oracle JET MOOC and using the Yeoman generator, you're advised to use "navbar" or "navdrawer", since these provide a set of Oracle JET modules, as can be seen above, which you can immediately start using to learn and develop your Oracle JET applications. In addition to the above, there are project templates in NetBeans IDE, if the Oracle JET Support plugin is installed. These provide different results to the above.  Via the Oracle JET Support plugin, you have the "Oracle JET Base Distribution" template which is even more blank than the 'blank' template above. It contains the Oracle JET distribution, without any template files at all, and with Oracle JET being wired up less than the 'blank' template above. Note: You also have the "Oracle JET QuickStart Basic" template, provided by the Oracle JET Support plugin in NetBeans IDE, which creates the application template that is used throughout the Oracle JET MOOC, i.e., with a "home" Oracle JET module, among other Oracle JET modules. As you can see above, the Yeoman generator does not produce a "home" module, though that doesn't matter at all, you can use any of the other Oracle JET modules that your template provides, no need to worry therefore if you're missing a "home" module when you're following instructions in a tutorial or the Oracle JET MOOC. Alternatively, you can download ZIP files here, including the "Oracle JET QuickStart Basic", here: http://www.oracle.com/technetwork/developer-tools/jet/downloads/index.html

Here's an overview of each of the Oracle JET application templates in Oracle JET 2.1.0. Note: Below each of the Yeoman generator commands below, you see how the project looks in NetBeans IDE. I.e.,...

Adding Some Color to the RebelLabs Developer Productivity Report 2016

I used to have a very nice colleague who would never disagree with me. He'd never say 'I disagree with you'. Instead, he'd always say, 'let me add some color to that', after which he'd proceed to, essentially, disagree with me. :-) [I miss you, Ashwin!] But it was a nice experience. He wasn't disagreeing, he was adding color.In that light I'd like to look at an aspect of the RebelLabs Developer Productivity Report 2016. It wasn't released very long ago and has the following results for IDE usage:On the face of it, things aren't looking so great for NetBeans! In fact, NetBeans is doing very badly indeed. You can't really talk about "the top three IDEs" anymore, there's clearly only "the top two IDEs". However, let's look a bit more closely and ask ourselves some questions. Yes, let's add some color to that!ZeroTurnaround & MeLet me start by saying I love the ZT team. I have known several members of ZT for a lot of many years.Jevgeni I remember meeting at JavaZone in Norway many years ago when he was talking about his Aranea web framework; Anton I have done several JavaOne sessions with; the JRebel plugin for NetBeans is one of the most actively developed NetBeans plugins; Igor has created the most amazing MindMap plugin for NetBeans; I've talked to Simon at several conferences; Alan and Michael I met in Denmark and I claim some role in surfacing them in the community and getting them noticed by Jevgeni (watch this cool YouTube clip with Alan, Fabrizio, and me); Oleg I spent a crazy time with in the Bering Sea; Sang, Adam, and Geert who used to work there are guys I have known forever as well. And, on top of all that, ZeroTurnaround is a NetBeans partner.So, again, I am really adding color here and seriously not trying to do anything other than that. I love ZT, OK.Tone & ContentIn the report: "Overall we received 2044 responses." Moreover, when I see the response to "What is your job description?", I don't see anything about "I am a student". In fact, the word "student" doesn't appear in the report. Nothing at all wrong with that, of course. The survey was not aimed at students at all.Already one can feel the kind of color that can be added here. Slightly over 2000 respondents, which seems small to me. And no students.Plus, it took quite a bit of motivating to get those 2000 respondents. Especially the last few hundred took some work, I saw quite a bit of activity in getting those, e.g:You know who else didn't participate? The NetBeans community. On 1 March this year, there was a brief discussion on the NetBeans Dream Team mailing list. The NetBeans Dream Team is a group of volunteers outside of the NetBeans team and outside of Oracle. They're NetBeans enthusiasts who are recognized for their activism by being invited to join the group to share insights and activities and ideas around NetBeans. We discussed the RebelLabs productivity reports. Especially the fact that the tone of the reports is definitive and assertive, despite not covering at least the simplest of these concerns, i.e., a pretty low number of self-selecting respondents, none of whom are students which is a key demographic that NetBeans has targeted from the beginning.My suggestion was that this year, in contrast to previous years where we were a bit sceptical too, we go full on for the survey, promote it to the community, to the NetBeans enthusiasts around the world, the mailing lists, etc. However, one of the people in the discussion suggested, bearing in mind our objections: "Instead of helping them with extra data points you might just publicly ask NetBeans users to NOT respond to RebelLabs surveys." I disagreed strongly because I love ZT! And ZT is a NetBeans partner, on top of that.So, we did nothing. We let it go, knowing that by not promoting this to the NetBeans community, the results would probably be like they turned out to be. The results of the survey provide a limited view on a self-selecting segment of the Java community.Reap & SowHowever, let's go a bit further. Given the limitations outlined above, which in themselves disqualify the results, or should disqualify the results from being used to say anything about the actual usage of the tools, is there an explanation for those 2044 respondents having responded in the way they did? Why did only 10% of those problematic non-student 2044 respondents pick NetBeans?JetBrains is incredibly admirable for their conviction. JetBrains supports their tools without a second of doubt. Oracle, well, not so much. Sometimes yes, sometimes no. Sometimes lots of enthusiasm, sometimes just a bit, something nothing. The last time NetBeans had an evangelism team was in the days of Roman Strobl, I guess around 2007 or so, when NetBeans was part of Sun and when there were about 10 fulltime NetBeans evangelism staff (in addition to about 6 technical writers, of which I was one) constantly and consistently promoting NetBeans. There's nothing left of that. Well, just me, plus the NetBeans Dream Team, an unpaid volunteer force to be reckoned with, but not a paid staff strategizing and planning the best way to reach developers with tools etc. Meanwhile, JetBrains has been investing in that aspect of its organization to great effect. Kudos to them.To add some color to the results, therefore, I tentatively suggest that they are a reflection of the conviction versus the ambivalence of the organizations behind those tools, as well as the staffing and strategies for promoting them. On this basis, the percentages mirror the backing that the tools have received from the organizations that sponsor them.Apples & PearsWe need to go further still and ask the "why" question. What's the reason for the different levels of enthusiasm of these organizations for their tools? JetBrains and Oracle have completely different aims, of course. JetBrains is explicitly a tooling company. The key slogan, a really good one, is: "Whichever technologies you use, there's a JetBrains tool to match."Oracle, on the other hand, is historically a database company and increasingly a Cloud company. In contrast to JetBrains, for Oracle tooling plays, at best, a supporting role, and is, at worst, an after thought. Though one would expect tooling to play a bigger role, it tends to fall a bit by the wayside in the final push to a technology release.Facebook & TwitterSo, if the ZT survey cannot accurately reflect IDE usage, is there another way to conclusively do so. No. The only thing anyone can provide are very tentative indicators.Here are some:What does the above show? One thing I find interesting is that JetBrains is spending a lot of energy while not getting as compelling a result as the other two IDEs. Also note that normally Eclipse doesn't have as much engagement on Facebook as this week. The last few weeks have been special because of Eclipse Che, generating a lot of engagement. NetBeans, though, is clearly on top in terms of Facebook likes. Note also that there's never more than one or two new items on the NetBeans Facebook page per day. Sometimes nothing. Because we don't want the news from yesterday to get lost. So we add one new item every other day or so. A different strategy to JetBrains, clearly, which also has to contend with the fact that IntelliJ IDEA is only one of their tools. They have a lot to talk about, though it doesn't seem to result in a lot of new Facebook likes.Next, let's take a look at Twitter followers. Below you see NetBeans, then JetBrains, then Eclipse. Again, NetBeans has the most followers, i.e., the most people interested in receiving tweets from one of the three IDEs is from people interested in NetBeans. Again, notice the disparity between the amount of tweets from JetBrains versus the considerably lower number of followers:Of course, someone will say, this says nothing about what people are working with. Hmmm. I wonder about that. How many Twitter accounts do you follow of tools that you're not using? And if you want to see a comparison between real tool usage, take a look at the difference between the number of people using the Chrome plugin for NetBeans versus the Chrome plugin for IntelliJ:That's a difference of about 50,000, which has been constant, plus or minus a few thousand, over the past years.If you were to want to reach as many developers as possible, with your message, or your technology via a plugin, which of the three IDEs would you immediately suspect could be used to reach the largest number of people? Over on YouTube, look at the marked difference in views between two different YouTube clips, about the same technology, i.e., Oracle Developer Cloud Service, installed in Eclipse vs. installed in NetBeans:The two YouTube clips were created in the same period. The Eclipse YouTube clip has less than 300 views, while the NetBeans equivalent has around 4000 views. Neither of those numbers are very high, which is probably because Oracle Developer Cloud Service is an extremely non-sexy topic. Nevertheless, the NetBeans views are orders of magnitude higher, clearly.Of course, I am not arguing that NetBeans is the most popular IDE. I don't believe that to be true at all, in fact. Plus, that's not the point I am making here, in any way. No one can make that claim. I am simply adding color to the survey results, since these different statistics from completely different sources appear to indicate something different to what the survey suggests.Intention & AbuseWhere it becomes dangerous is where the ZT survey is used as a stick to beat an IDE with. That was never the intention of the awesome people at ZT, though it is exactly what happens when surveys are released.Surveys are always flawed and never present the full picture. Like when I argued with (ah, 'added color to') the RedMonk survey a few years ago, if we don't have the full climate picture, we shouldn't be doing the weather report. At the very least we should be extremely circumspect and not assert anything at all lest our assertions be abused in contexts for which they were never intended.

I used to have a very nice colleague who would never disagree with me. He'd never say 'I disagree with you'. Instead, he'd always say, 'let me add some color to that', after which he'd proceed...

NetBeans

Integrating Oracle Fusion Middleware MapViewer with Oracle JET

There are many map components in the world out there—and I have documented how to integrate several of them in an Oracle JET application, e.g., 3DCityDB, Mapbox, Leaflet, and LuciadRIA, as well as Oracle JET's ojThematicMap component.  However, Oracle has its own map component, as described in detail below, which includes the Oracle Maps Javascript library: http://www.oracle.com/technetwork/middleware/mapviewer/overview/index.html Oracle Fusion Middleware MapViewer is a development toolkit for incorporating interactive maps and spatial analyses. It is optimized for use with Oracle Spatial and Graph. (The related Oracle blog is blogs.oracle.com/oracle_maps_blog.) Here below is how it looks when integrated into an Oracle JET application, with many thanks to my colleague Jayant Sharma, who made it happen and provided the instructions that follow, which I have successfully used and I can report that it works. Instructions for integrating Oracle Fusion Middleware MapViewer with Oracle JET, assuming you have set up an Oracle JET application, e.g., via the Oracle JET QuickStart Basic template: Add the Oracle Maps V2 kit into js/libs as a folder named 'oraclemaps'. The kit can be downloaded from here and specifically here: http://download.oracle.com/otn/other/mapviewer/12c/12211/v2_122110_full.zip Modify "main.js" to include the various Oracle map libraries, in the requires.config "path" and "shim" sections. I.e., add these entries in the "paths" section: //File paths for Oracle Maps HTML5 API'omapsv2-hammer': 'libs/oraclemaps/v2/jquery/jquery.hammer-full.min','omapsv2-i18n-properties': 'libs/oraclemaps/v2/jquery/jquery.i18n.properties-min-1.0.9','omapsv2-mousewheel.min': 'libs/oraclemaps/v2/jquery/jquery.mousewheel.min','omapsv2-rtree': 'libs/oraclemaps/v2/rtree/rtree-min','omapsv2-fortknox': 'libs/oraclemaps/v2/fortknox-libs/fortknox-canvas', 'omapsv2_core': 'libs/oraclemaps/v2/oraclemapsv2_core' ...and these in the "shim" section: //Oracle Maps HTML5 API dependencies'omapsv2-i18n-properties': ['jquery'],'omapsv2-hammer': ['jquery'],'omapsv2-mousewheel.min' : ['jquery'], 'omapsv2_core': { deps: ['jquery','hammerjs','omapsv2-fortknox','omapsv2-rtree','omapsv2-hammer','omapsv2-i18n-properties','omapsv2-mousewheel.min'], exports: 'OM'} Modify the view of an Oracle JET module, e.g., "home.html", in the way it's done for the MapBox example, i.e., rewrite "home.html" to be the following and include "css/styles.css" containing "#map { width:100%; height:100%; }":  <STYLE TYPE="text/css"><!-- @import url(css/styles.css);--></STYLE><div id='map'></div> Modify the viewModel of an Oracle JET module, e.g., "home.js", to be as follows, and read the comments below to understand the code: define(['ojs/ojcore', 'knockout', 'omapsv2_core'], function (oj, ko) { function mainContentViewModel() { var self = this; self.handleAttached = function () { /* */ if (OM !== undefined) {//Where to load Oracle Maps HTML5 API resource files (fonts, css and icons et al): OM.gv.setResourcePath("js/libs/oraclemaps/v2");//Default http method when fetching remote geospatial contents: OM.gv.setHttpMethod("GET"); } else console.log('OM not loaded'); var X = -77; var Y = 38.9; var initialZoom = 11;//This function adds various map controls to the provided OM.Map instance: var addMapControls = function (myMap) {//defines various properties for the navigation control: var navConfig = { orientation: 1, style: OM.control.NavigationPanelBar.STYLE_ZOOM_BUTTONS_ONLY, anchorPosition: 1 };//creates the navigation control: var navigationControl = new OM.control.NavigationPanelBar(navConfig);// navigation control (and other map controls) are typically added //to the map as map decorations: myMap.addMapDecoration(navigationControl);//defines the basic properties for the map scale bars: var sbConfig = { format: "BOTH", anchorPosition: 4, endMarks: false };//defines the display style of the scale bars: var sbStyle = { thickness: 5, color: '#257db3', shadow: true };//creates the actual scale bar instance and sets the display style: var scaleBar = new OM.control.ScaleBar(sbConfig); scaleBar.setStyle(sbStyle);//adds the scale bar to the map as another map decoration: //myMap.addMapDecoration(scaleBar); }; var showMap = function () {//This is the DIV that will display the map; it needs to be passed into //the map instance: var mapDiv = document.getElementById('map'); if (!mapDiv) { console.log("Map container DIV not found!"); return; }//Creates a new map instance. Notice we are not supplying a Universe //like in helloworld.js, since the universe will be defined when we //add the tile layer to the map. Every tile layer includes its own //universe definition as part of the tile layer's configuration: var map = new OM.Map(mapDiv, {mapviewerURL: ''});//This is how we create an Oracle eLocation tile layer: by creating //a new instance of the OM.layer.ElocationTileLayer class. Check //the <a href="https://apidoc/index.html">API Doc</a> for other built-in tile //layers such as Bing maps: var tileLayer = new OM.layer.ElocationTileLayer("elocation");//Adds the tile layer to the map: map.addLayer(tileLayer);//creates a point object located at the given longitude and latitude: var point = new OM.geometry.Point(X, Y);//Adds various map controls to the map: //console.log('adding mapControls'); addMapControls(map);// set the initial map zoom level and center (same as the location marker): map.setMapCenter(point); map.setMapZoomLevel(initialZoom);//Now we can complete the initialization of the map. You must //only call this method once. Note however map layers can //be added even after calling this method: map.init(); }; //showMap // console.log('call showMap'); showMap(); /* */ }; // handleAttached } return new mainContentViewModel(); }); That's it. Run the project and you'll see the same as in the screenshot above.

There are many map components in the world out there—and I have documented how to integrate several of them in an Oracle JET application, e.g., 3DCityDB, Mapbox, Leaflet, and LuciadRIA, as well as O...

Oracle JET

Translating Oracle JET Applications

The Oracle JET MOOC starts on Monday. When we talk about Oracle JET we always say that it solves "enterprise challenges". One of these is internationalization/localization/translation of JavaScript applications. Recently I started playing with the translation features of Oracle JET and they're pretty impressive. Really, if you want to create JavaScript applications that need to be translated, you should look no further than Oracle JET. Let's start by looking at the result of a small sample I've been working on. Here's an application that can be switched to 4 different languages, with a screenshot of 3 of them below:  Everything to achieve the above is documented in "Internationalizing and Localizing Applications" in the Oracle JET Developer Guide. This topic is also dealt with in the 3rd week of the Oracle JET MOOC. There are several bits and pieces involved in this sample:  Bundled translations for Oracle JET components. Oracle JET components, such as the date/time picker that you see above, have already been translated. The translations are found in libs/oraclejet/dist/js/libs/oj/resources/nls. Custom translation bundles. Aside from the Oracle JET components, which have already been translated, Oracle JET provides a facility for storing and loading your own translations. Below, you can see a folder called "resources/nls", with subfolders for each of the languages I am supporting:In "main.js", I have this, which registers the "resources/nls/l10" structure and merges it with the translations that are provided by Oracle JET: config: { ojL10n: { merge: { 'ojtranslations/nls/ojtranslations': 'resources/nls/l10' } }} The most important file in "resources/nls" is the file named "l10.js", which could be named anything at all, so long as it matches the registration in "main.js" shown above. It looks like this, in my case: define({ "root": { "date": "Date:", "greeting": "Good Morning"}, "ar": true, "fr": true, "cs": true});In each of the folders that have been enabled above, i.e., "ar", "fr", and "cs", translations of the above texts are found, e.g., in "ar":Now, anywhere in our viewModel, we can use this statement to retrieve the greeting of the current locale: oj.Translations.getTranslatedString('greeting') RTL Support. Bidirectional features are included too, read here, simply by setting the "dir" attribute of the "html" element to "rtl" and back to "ltr". Dynamic Locale Switching. Via the buttons you see above, the locale can be switched, as described here. Following from the above, the complete code for the viewModel is as follows, focused on enabling the switching between locales, which will cause the translation bundles to be loaded dynamically: define(['ojs/ojcore', 'knockout', 'ojs/ojbutton', 'ojs/ojdatetimepicker'], function (oj, ko) { function mainContentViewModel() { var self = this; self.formats = ko.observableArray(["english"]); self.date = ko.observable(); self.greeting = ko.observable("Good Morning"); self.localeDate = ko.observable(); self.localeDate(oj.Translations.getTranslatedString('date')); self.localeGreeting = ko.observable(); self.localeGreeting(oj.Translations.getTranslatedString('greeting')); self.setLang = function (data) { var newLang = ''; switch (data) { case 'Arabic': newLang = 'ar-EG'; self.formats(["arabic"]); break; case 'Czech': newLang = 'cs-CZ'; self.formats(["czech"]); break; case 'French': newLang = 'fr-FR'; self.formats(["french"]); break; default: newLang = 'en-US'; self.formats(["english"]); } oj.Config.setLocale(newLang, function () { $('html').attr('lang', newLang); if (newLang === 'ar-EG') { $('html').attr('dir', 'rtl'); } else { $('html').attr('dir', 'ltr'); } self.localeDate(oj.Translations.getTranslatedString('date')); self.localeGreeting(oj.Translations.getTranslatedString('greeting')); $('#dateInput').ojInputDateTime('refresh'); } ); }; } return new mainContentViewModel(); }); And here's the view: <div data-bind="ojComponent: {component: 'ojButtonset', checked: formats}"> <!--Arabic--> <label for="arabic">Arabic</label> <input data-bind="click: function(){setLang('Arabic');}" type="checkbox" value="arabic" id="arabic"/> <!--Czech--> <label for="czech">Czech</label> <input data-bind="click: function(){setLang('Czech');}" type="checkbox" value="czech" id="czech"/> <!--French--> <label for="french">French</label> <input data-bind="click: function(){setLang('French');}" type="checkbox" value="french" id="french"/> <!--English--> <label for="english">English</label> <input data-bind="click: function(){setLang('English');}" type="checkbox" value="english" id="english"/></div><br/><br/><span style="font-size: 50pt" id="greeting" data-bind="text: localeGreeting"></span><br/><span data-bind="text: localeDate"></span><input id="dateInput" type="text" data-bind="ojComponent: { component:'ojInputDateTime', value: date, datePicker: {changeMonth: 'none', changeYear: 'none'} }"/> That's it. And here's the sample code shown above: https://github.com/GeertjanWielenga/OJETCourse/tree/master/Part-024 A next step is to generate all the buttons automatically from JavaScript, i.e., there should be some way to provide new buttons to switch to new languages easily, without having to code them in HTML, i.e., in the viewModel, find the lists of available translation locales and create the buttons, and their logic, based on that. 

The Oracle JET MOOC starts on Monday. When we talk about Oracle JET we always say that it solves "enterprise challenges". One of these is internationalization/localization/translation of...

Oracle JET

Sign Up Free, Today: Oracle JET MOOC

A lot of work has gone into the preparation of something completely different—an enterprise JavaScript MOOC (massive open on-line course) via Oracle JET, which will start coming Monday, 22 August. Oracle JET is a set of best practices, recommendations, architectures, templates, and components for enterprise JavaScript applications. There are over 1,000 subscribers to the MOOC so far. The MOOC will take 3 weeks of your time, the first week starting on Monday, 22 August. Each week is defined by one lesson, which is in 10 parts, each part consisting of a YouTube clip, each clip lasting no longer than about 10 minutes, together with self-study and homework assignments. Each of the two following weeks a new lesson will be made available. Each lesson ends with a quiz. Successful completion of all quizzes results in a certificate of completion.  Lesson 1, entitled "Taking Off with Oracle JET", takes you on a tour of the reasoning behind Oracle JET and an exploration of its underpinnings. By the end of that lesson, you're able to create Oracle JET applications. You'll have learned about Oracle JET modules, components, and layouts. You'll have a really great basis for creating enterprise JavaScript applications. Lesson 2, entitled "Exploring the Skies with Oracle JET", gives you a structured approach to learning from the Oracle JET Cookbook, which is filled with a range of enterprise components, e.g., graphs and tables, and shows you how to use them and integrate them into your Oracle JET applications. Lesson 3, entitled "Into the Clouds with Oracle JET", shows you how to integrate with the world around Oracle JET, i.e., 3rd party components, internationalization, accessibility, security, etc. Want to get a quick feel for how the MOOC will be? Part 1 (of 10 parts, which will be released next week) of the first lesson is already available: Sign up here!

A lot of work has gone into the preparation of something completely different—an enterprise JavaScript MOOC (massive open on-line course) via Oracle JET, which will start coming Monday, 22 August....

Most Unique Feature of NetBeans IDE!

What's NetBeans all about, what makes it special, why would anyone use NetBeans rather than something else, what are its key features, what distinguishes NetBeans from other tools, etc etc etc. Set aside those questions for a moment and take a look at this photo taken last week at JCrete: That's a small part of the NetBeans community around the world, most of the above are members of the NetBeans Dream Team. And the enthusiasm that jumps out at you is why NetBeans is special. Yes, the Maven integration in NetBeans is awesome; yes, NetBeans makes working with Git a piece of cake; yes, if you're doing Java EE then NetBeans should really be your weapon of choice, etc etc etc. And NetBeans is also awesome when you build software on top of it. But, beneath it all, is a group of fun people from all over the world—who have all kinds of different hobbies and interests, one of which is software development, which they all do in one way or another in/with/on NetBeans IDE. In the pic, taken by Stephen Chin, are: back row: Jose Pereda (Spain), John Kostaras (Greece), Paul Anderson (USA), Gail Anderson (USA), Jaroslav Tulach (Czech Republic), Kirk Pepperdine (Hungary), Sven Reimers (Germany), Timon Veenstra (Netherlands) front row: Sven Ruppert (taking the place of Ivar Grimstad, who couldn't be found), Geertjan Wielenga (Netherlands), Toni "Crazy Screaming Guy" Epple (Germany), Zoran Sevarac (Serbia)

What's NetBeans all about, what makes it special, why would anyone use NetBeans rather than something else, what are its key features, what distinguishes NetBeans from other tools, etc etc etc. Set...

OAuth and Oracle JET

OAuth is an open protocol to allow secure authorization in a simple and standard method from web, mobile, and desktop applications. Oracle JET includes a helper library for working with OAuth, though not OAuth itself, i.e., Oracle JET does not ship with OAuth. Instead, it provides a helper class that helps you manage OAuth tokens and requests, rather than including the OAuth client libraries that are needed. Also, there is documentation for the OAuth helper library in the Oracle JET Developer Guide, in a chapter named Using oj.OAuth in Your Oracle JET Application. In your "define" block, you need to include "ojs/ojmodel", since that's where the OAuth class is provided. The OAuth class provides the methods you can use to initialize the oj.OAuth object, verify initialization, and calculate the authorization header based on client credentials or access token. Once you have included "ojs/model", you initialize "oj.OAuth", as described in the chapter, e.g.: self.myOAuth = new oj.OAuth('X-Authorization'); When you use the Oracle JET Common Model, you'll find the "oj.Collection.extend" enables you to reference your "oj.OAuth" object. Also see the related JavaScript documentation: http://www.oracle.com/webfolder/technetwork/jet/jsdocs/oj.OAuth.html Here's all the code for a real "define" block that includes OAuth for working with Twitter. Take note of the bits in bold below, which are the statements relating to OAuth: define(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojmodel', 'ojs/ojtable', 'ojs/ojcollectiontabledatasource'], function (oj, ko, $) { function HeaderViewModel() { var self = this; self.TweetCol = ko.observable(); self.datasource = ko.observable(); self.serviceURL = 'https://api.jublo.net/codebird/1.1/search/tweets.json'; self.myOAuth = new oj.OAuth('X-Authorization'); self.parseTweet = function (response) { return { id_str: response['id_str'], text: response['text'], userName: response['user']['name'] }; }; var Tweet = oj.Model.extend({ urlRoot: self.serviceURL, parse: self.parseTweet, idAttribute: 'id_str' }); var myTweet = new Tweet(); var TweetCollection = oj.Collection.extend({ url: self.serviceURL + '?q=NetBeans', model: myTweet, oauth: self.myOAuth }); self.getData = function () { self.datasource(null); self.TweetCol(new TweetCollection());self.myOAuth.setAccessTokenRequest( JSON.parse(sessionStorage.getItem('credentials')) ); self.TweetCol().fetch({ success: function () { self.datasource( new oj.CollectionTableDataSource(self.TweetCol()) ); }, error: function (jqXHR, textStatus, errorThrown) { console.log('Error in fetch: ' + textStatus); } }); }; } return new HeaderViewModel(); }); In "main.js", the "credentials.js" file is loaded: var prop;$.ajax({ url: 'js/credentials.json', dataType: 'json', async: false, success: function (data) { sessionStorage.setItem('credentials', JSON.stringify(data)); }, error: function (req, status, err) { console.log('something went wrong', status, err); }}); The "credentials.js" file has this content: {    "client_id": "blabla",    "client_secret": "blabla",    "bearer_url": "https://api.jublo.net/codebird/oauth2/token",    "access_token": "blabla"} Above, Codebird is used. Codebird is a library that is commonly used to manage OAuth2 connections to Twitter. And, instead of setting up your own code, you can use Codebird's proxy service. In the "define" block above, notice the "self.getData" at the end, which ties everything together, and is called from the view: <button data-bind="click: getData, ojComponent: { component: 'ojButton', label: 'Get Data'}">Get Data</button><hr><table data-bind="ojComponent: { component: 'ojTable', data: datasource, columnsDefault: {headerStyle: 'text-align: left; white-space:nowrap;'}, columns: [ {headerText: 'User ', field: 'userName'}, {headerText: 'Text', field: 'text'} ]}"></table> That's it. A complete sample scenario that uses OAuth with Oracle JET.

OAuth is an open protocol to allow secure authorization in a simple and standard method from web, mobile, and desktop applications. Oracle JET includes a helper library for workingwith OAuth, though...

JBoss Data Virtualization with Oracle JET

I met with Cojan van Ballegooijen who is involved with the Red Hat JBoss Data Virtualization project. Read about that here: http://www.jboss.org/products/datavirt/overview I'm interested in setting up a scenario where Oracle JET could provide a dashboard on top of a VDB (virtual database). Here's the steps we took to get started. We started by downloading the 6.3.0 Beta of JBoss Data Virtualization: http://developers.redhat.com/products/datavirt/download. After running "java -jar" on the JAR downloaded above, we had installed the product and had a folder named "EAP-6.4.0". In the folder "quickstarts/dynamicvdb-datafederation", there's a folder "src/teiidfiles", which we copied into the root, i.e., into the "EAP-6.4.0" folder. In the folder "standalone/configuration", there's a file named "standalone.xml", where we tweaked the reference to "jboss.dir" so that it pointed to the hardcoded location of the EAP-6.4.0 folder, i.e., there was a problem with slash escaping on Windows of the "jboss.dir" reference and to workaround that we hardcoded the path, for the data source with the jndi-name "java:/accounts-ds". Then we ran "bin/standalone.bat", the process started, the "teiidfiles" were loaded, and at this location we saw the JSON payload: http://localhost:8080/odata4/Portfolio/Accounts/CUSTOMER?$format=json OK, great, we have the JSON, which provided the data from the VBD. Once we have JSON, the step to an Oracle JET dashboard is trivial, since Oracle JET has all kinds of hooks for working with JSON. However, there's one stumbling block at this point and that is that authentication is needed for accessing our data. It seems that Keycloak is needed in this scenario: https://access.redhat.com/documentation/en/red-hat-jboss-data-virtualization/6.3/security-guide/chapter-11-oauth-based-security-for-odata That's the next step. Once that's done, then we have here a nice scenario for creating user interfaces on top of virtual databases created via JBoss Data Virtualization.

I met with Cojan van Ballegooijen who is involved with the Red Hat JBoss Data Virtualization project. Read about that here: http://www.jboss.org/products/datavirt/overview I'm interested in setting up a...

JSX in NetBeans IDE 8.2

JSX is a XML-like syntax extension to ECMAScript without any defined semantics. Many more details about it can be found here: https://facebook.github.io/jsx/ JSX is popular in the React community which "recommend[s] using JSX because it is a concise and familiar syntax for defining tree structures with attributes. It's more familiar for casual developers such as designers." Many more details about that can be found here: https://facebook.github.io/react/docs/jsx-in-depth.html Many NetBeans IDE users have been asking for JSX support in NetBeans IDE, since they are using React: https://netbeans.org/bugzilla/show_bug.cgi?id=250778 As you can see from the above, the NetBeans team has added parsing and lexing support for JSX over the past few days. Let's take a look at the result, using this repo as an example project to try out JSX support in NetBeans IDE: https://github.com/reactjs/react-tutorial Here's what I see in a very (very very) recent NetBeans IDE build (click to enlarge the image): Contrast the above to the same file opened in the current release of NetBeans IDE, i.e., NetBeans IDE 8.1, to see the difference: Great news, isn't it? :-) At this point, don't expect extensive support for JSX or for React. However, as you can see above, at least you can now edit your files without there being error markings everywhere, which made NetBeans IDE impossible to work with when working with JSX.

JSX is a XML-like syntax extension to ECMAScript without any defined semantics. Many more details about it can be found here: https://facebook.github.io/jsx/ JSX is popular in the React community which...

Gallery Demos for JavaScript: JQuery UI Accordion

Continuing from the first part, let's now move towards modularity via Require and data bindings via Knockout.  Here is the application: https://github.com/GeertjanWielenga/GalleriaDemos/tree/master/Galleria2-Knockout/app The project structure is like this, which looks a lot like the structure of an Oracle JET application, though an Oracle JET template was not the starting point of the below. Instead, I started with a plain ordinary HTML/JavaScript application and built up the structure from there, i.e., as a normal JavaScript application: Here the JQuery UI Accordion component is used, which looks as follows in this case:  To make sure that the versions of the various libraries work together, instead of getting hold of JQuery, JQuery UI, Require, and Knockout separately, I'm getting hold of all of them at once via Oracle JET in 'bower.json': "oraclejet": "2.0.2" Each gallery makes use of a Knockout component created in the project, which is used as follows:  <div data-bind="component: {name:'galleria', params: { uniqueID: '1', images: [ 'images/galleria1.jpg', 'images/galleria3.jpg', 'images/galleria4.jpg' ] }}"></div> In the next part, we'll look at a different gallery component and set up the same kind of project structure to see how things work there.

Continuing from the first part, let's now move towards modularity via Require and data bindings via Knockout.  Here is the application: https://github.com/GeertjanWielenga/GalleriaDemos/tree/master/Galle...

Timeline in Oracle JET

Let's take the "ojTimeline" component from the Oracle JET component library, as described here in the Oracle JET Cookbook, while taking note of the format of the related JSON file here. Then, downloading that file into our Oracle JET application and changing the details in the JSON file, let's recreate the NetBeans Roadmap in Oracle JET, with this result: Here's the business logic in JavaScript, i.e., the "define" block, including a selection listener: define(['text!../../seriesOneData.json', 'knockout', 'ojs/ojtimeline'], function (file, ko) { function mainContentViewModel() { var self = this; self.selected = ko.observable("Nothing is selected."); var content = JSON.parse(file); self.series = ko.observableArray(content)(); self.optionChangeListener = function (event, data) { for (var i = 0; i < content.length; i++) { if (content[i].id == data['value']) { self.selected(content[i].title); } } }; } return new mainContentViewModel(); }); And here's the HTML view that renders the above: <div data-bind="ojComponent:{ component: 'ojTimeline', majorAxis: {scale: 'years'}, minorAxis: {scale: 'quarters'}, start: new Date('Oct 1, 2013').toISOString(), end: new Date('Oct 31, 2016').toISOString(), optionChange: optionChangeListener, selectionMode: 'single', series: [{ id: 's1', emptyText: 'No Data.', items: series, label: 'NetBeans Roadmap' }],}" style="width: '100%'; height: 250px"></div><hr><h2>Selected: <span data-bind="text: selected"></span></h2>

Let's take the "ojTimeline" component from the Oracle JET component library, as described here in the Oracle JET Cookbook, while taking note of the format of the related JSON file here. Then,...

JQuery UI Datepicker Widget and Oracle JET

The jQuery UI Datepicker is a popular component. Let's integrate it into an Oracle JET application. Oracle JET is an open application architecture, together with a set of components, based on open source libraries, providing a logical framework within which components such as the jQuery UI Datepicker can be organized: For background on this topic, see this YouTube clip by JB Brock: https://www.youtube.com/watch?v=XcPcaSbaHFg Take the following steps: Get the 'datepicker.js', from somewhere. For example, use Bower to add 'jquery-ui' to your project. In 'main.js', point to the folder where all the 'ui' components are found: 'jqueryui': 'libs/jquery-ui/ui/',  Reference the CSS file below in your 'index.html': <link rel="stylesheet" href=" //code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"/> In your viewModel, add the 'datepicker' component in the 'define' block, while creating an observable property to hold the selected date and a callback function to handle selection: define(['ojs/ojcore', 'knockout', 'jqueryui/datepicker'], function (oj, ko) { function mainContentViewModel() { var self = this; self.selectedDate = ko.observable(); self.dateSelector = function (dateText, inst) { self.selectedDate(dateText); }; } return new mainContentViewModel(); }); In your view, use the 'datepicker' component (while making sure to use the 'jqueryUI' binding, as pointed out in the YouTube clip above), using the "onSelect" option provided by the datepicker as a link to the view above, while providing a span element to display the selected date: <div data-bind="jqueryUI: { component: 'datepicker', onSelect: dateSelector }"></div><hr>Selected date: <span data-bind="text: selectedDate"></span> That's it! Now you should see the datepicker and you should also see that the selected date is shown too. Helpful links: http://api.jqueryui.com/datepicker http://stackoverflow.com/questions/17008293/turn-on-today-button-on-date-picker

The jQuery UI Datepicker is a popular component. Let's integrate it into an Oracle JET application. Oracle JET is an open application architecture, together with a set of components, based on open...

Plotting Data on World Maps with Oracle JET

Our requirement is to use Oracle JET to show data on a world map, e.g., the number of employees in our organization working in various countries around the world. Below you see an example—three different ranges represented by colors on the map: To get to the above point, let's start with the simplest imaginable world map scenario with Oracle JET's built-in maps for ojThematicMap. Here's the view: <div id='thematicMap-container'> <div id='thematicMap1' data-bind="ojComponent:{ component: 'ojThematicMap', basemap: 'world', areaLayers: layers }" style="height:500px;width:100%"> </div></div> Here's the viewModel: define(['ojs/ojcore', 'knockout', 'ojs/ojthematicmap'], function (oj, ko) { function mainContentViewModel() { var self = this; self.layers = [{layer: 'countries'}]; } return new mainContentViewModel(); }); And here's the map that results from the simple code above: However, you're more than likely to be in a situation where you're getting data from somewhere, e.g., XML or JSON, with info that you'd like to display on the map. Here's a GeoJSON file that we can use as the starting point of our scenario: https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json We'll do the same thing as the earlier blog entry about Brazil, i.e., include the file above into your application, as explained earlier. Now, open the file, and add some more data into it, imagining that this data needs to be visualized on the map. The data you add needs to be in the "properties" section of some/each of the entries in the file. Below, you see that I have added "employees:2000" to the entry for United States of America. Do the same for a few of the other countries, i.e., add some random data into various properties sections to simulate some additional data that we want to be able to work with: Now, we're in a scenario very similar to this one: http://www.oracle.com/webfolder/technetwork/jet/uiComponents-thematicMap-default.html Adapting our scenario to the sample above, here's the view: <div id='thematicmap-container'> <div id='thematicmap1' data-bind="ojComponent:{ component: 'ojThematicMap', basemap: 'Foo', mapProvider: mapProvider, areaLayers: layers }" style="width:100%; height:400px;"> </div> <div id='legend1' data-bind="ojComponent: { component: 'ojLegend', halign: 'center', orientation: 'horizontal', title: 'No. of Employees', titleHalign: 'center', titleStyle: 'font-size:14px;font-weight:bold;', textStyle: 'font-size:14px;', sections: legendSections }" style="width:100%; height:50px;"> </div></div> And here's the viewModel: define(['text!../countries.geo.json', 'ojs/ojcore', 'knockout', 'ojs/ojthematicmap', 'ojs/ojlegend'], function (geo, oj, ko) { function mainContentViewModel() { var self = this; self.mapProvider = { geo: JSON.parse(geo), propertiesKeys: { id: 'name', longLabel: 'name' } }; self.legendSections = [{items: [ {text: "0-500", color: '#FF0000'}, {text: "501-1000", color: '#0000CC'}, {text: "1001-2000", color: '#3AA54F'} ]}]; var getEmployeeColor = function (employees) { if (employees <= 500) return '#FF0000'; else if (employees <= 1000) return '#0000CC'; else if (employees <= 2000) return '#3AA54F'; }; var getStateId = function (state, stateIdMap) { for (var id in stateIdMap) { if (stateIdMap[id] == state) return id; } };var getEmployeeData = function (dataContext) { var areaData = []; var features = JSON.parse(geo).features; for (var i = 0; i < features.length; i++) { var name = features[i]["properties"]["name"]; var employees = features[i]["properties"]["employees"]; areaData.push({ id: 'a1', location: getStateId(name, dataContext.ids), color: getEmployeeColor(employees) }); } return areaData; }; self.layers = [ { layer: 'countries', areaDataLayer: {id: 'adl1', areas: getEmployeeData} }]; } return new mainContentViewModel(); }); The trickiest bit above is the parsing of the JSON. Take a look, in particular, at the piece of code in bold above.

Our requirement is to use Oracle JET to show data on a world map, e.g., the number of employees in our organization working in various countries around the world. Below you see an...

Integrating iTunes into Oracle JET

Here's a search string for iTunes: https://itunes.apple.com/us/rss/toppaidapplications/limit=10/genre=6014/json Let's integrate that into an Oracle JET application, with this result: After a bit of fiddling with the parsing of the JSON, this is how I built up the table above. Here's the view: <table data-bind="ojComponent: {component: 'ojTable', data: dataSource, columns: [ {headerText: 'Name', field: 'name'}, {headerText: 'Price', field: 'price'} ] }"></table> Here's the viewModel:  define(['ojs/ojcore', 'knockout', 'ojs/ojtable'], function (oj, ko) { function homeContentViewModel() { var self = this; self.data = ko.observableArray(); $.getJSON("https://itunes.apple.com/us/rss/toppaidapplications/limit=10/genre=6014/json"). then(function (json) { var entry = json.feed.entry; $.each(entry, function () { self.data.push({ name: this['im:name'].label, price: this['im:price'].label }); }); }); self.dataSource = new oj.ArrayTableDataSource( self.data, {idAttribute: 'name'} ); } return homeContentViewModel;}); Next steps would be to replace the hardcoded search string with some UI elements so that the user can specify the search string at runtime.A reference that helped me with the above:http://stackoverflow.com/questions/4925760/selecting-a-json-object-with-a-colon-in-the-key

Here's a search string for iTunes: https://itunes.apple.com/us/rss/toppaidapplications/limit=10/genre=6014/json Let's integrate that into an Oracle JET application, with this result: After a bit of...

Oracle

Integrated Cloud Applications & Platform Services