• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Sunday, 15 Nov 2009 06:06

Uxstupid Just a quick note that the email address to which you may submit your JavaFXpert RIA Exemplar Challenge entry has been created.  It is:

ria-exemplar-challenge [at] javafxpert.com

Please visit the original post to see the description and rules for this challenge.

Happy designing and developing!

Judges Jim Weaver, Jasper Potts, Romain Guy and Stephen Chin

Author: "Jim Weaver"
Send by mail Print  Save  Delicious 
Date: Sunday, 15 Nov 2009 05:29

I posed the question "Should There be Enterprise RIA Style Guidelines?" in late 2008, and received some valuable feedback/discussion.  Based upon that feedback, I'm replacing my question with the following challenge:

"Create an application in JavaFX that exemplifies the appearance and behavior of a next-generation enterprise RIA (rich internet application)".

Here are the rules to this JavaFXpert RIA Exemplar Challenge:

1) Each application must be created in JavaFX by a team consisting of two participants: A graphic designer, and an application developer.  Both participants on the winning team will be recognized, and will share the prize.

2) The code must be offered as open source, in the form of the updated Berkeley Software Distribution License.  The code for the winning entry will be added to the open source JFXtras project samples library.

3) The entries must be submitted in the form of a NetBeans or an Eclipse project by 00:00 GMT on 10 January 2010 to ria-exemplar-challenge@javafxpert.com.  The entries will be judged by two JavaFX developers (Jim Weaver and Stephen Chin), and two graphics designers (Jasper Potts and Romain Guy).  The criteria for judging will be how well we feel that the entry "exemplifies the appearance and behavior of a next-generation enterprise RIA".

4) The winning entry will be announced on 20 January 2010 on this JavaFXpert.com blog.

5) The prize, which is a cash award of USD 2000 (USD 1000 for each one of the two participants), will be awarded after the winning team is announced.

If you have any questions about this contest, please leave a comment on this blog post.

Thanks, and have fun with the contest!

Jim Weaver
JavaFXpert.com

Author: "Jim Weaver" Tags: "JavaFXpert RIA Exemplar Challenge"
Send by mail Print  Save  Delicious 
Date: Saturday, 14 Nov 2009 18:02

Devoxx-logo-learnfx Java Champion, JavaOne Rock Star, and all-around good guy Stephen Chin is going to teach JavaFX and give away stuff at Devoxx 2009 in Antwerp, Belgium.

He'll first teach a university session to get you up to speed on the JavaFX platform, and later in the week will show you how to build Rich Internet Applications for the enterprise.

Leading up to both these sessions Stephen will post a question via the LearnFX application (see this blog post for more info on LearnFX).  To win a prize, all you have to do is:

  1. Answer the question correctly using the LearnFX client
  2. Come to the next Devoxx session that Stephen Chin is speaking at
  3. Winners will be selected by a random drawing from all the correct responses

To run the LearnFX application, make sure that you have a recent version (update 14 or later) of Java SE 6, and simply click on the blue brain LearnFX icon in the Devoxx logo at the top of this post.  Please don't tell Stephan Janssen (the Devoxx conference organizer) that I desecrated his logo. :-)

Break a leg, Stephen!

P.S. Last year I posted the Whack-a-Janssen game in honor of the great job that Stephen Janssen does (with the awesome help of Valérie Hillewaere and Kristien Leyn) in organizing Devoxx.

Launch-whack-a-janssen

Take a whack at this now-retro game!

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, Educational JavaFX Sc..."
Send by mail Print  Save  Delicious 
Date: Friday, 06 Nov 2009 00:39

Readers of this blog know that I like to hold contests to make things fun and encourage participation (e.g. see the 2000 USD JavaFXpert RIA Exemplar Challenge that ends 10 January, 2010).  In keeping with that sentiment, some JavaFX questions relevant to my presentation will be tweeted by @projavafxcourse to the twitterverse during the Øredev 2009 RIA Enterprise Application Developing with JavaFX session.

Oredev-javafx-contest

The seven people that earn the highest scores by tweeting fast, correct, answers to these questions will each win a copy of the Pro JavaFX book.  Six of these books will be composed of bits (e-books), and one will be composed of atoms.  The atom-based book is reserved for the person with the highest score of those present in the audience, but the e-books will be awarded (via an emailed Apress coupon) to the winners regardless on their location during the session.  This session starts on Friday,  November 6 at 3:35pm CET, lasting until 4:25pm, so please have your Twitter client ready.  When you tweet an answer, be sure to reply to the original tweet with your answer. 

On a technical note, all correct answers consist of one word or character, and the software that checks for a correct answer trims the spaces from the end of the reply and then uses the string found between the final space and the end of the reply.  So, if you want to put other words in your reply, presumably to give your followers a clue about what your terse message is, just make sure that your answer is at the end of your response.  For example, you might reply to the question:

The name of the layout class that arranges UI nodes horizontally is ____

with this message:

Answering a JavaFXpert presentation question with HBox

Brain_blue_32 If you want to use an application that I'm developing for the purpose of responding to these questions, please make sure that you have a recent version (update 14 or later) of Java SE 6 and click the LearnFX icon over on the left. 

When the application starts up, the most recent question is displayed as shown in the screenshot below.  If the question is still active (i.e. the answer has not been revealed), then the text box will be enabled, allowing you to enter an answer and click the Send button or press the Enter key.  Responses that have been received appear as well, along with the the Twitter profile image, screen name, and indication of whether the question is correct (if the answer has been revealed -- if not, a question mark will be displayed).

   LearnFX-ss

The first time that you run the application, you'll need to click the configuration icon to open the configuration dialog shown below, in which you can enter your Twitter screen name and password, as well as some preferences.  This information is stored on your local machine, and automatically loaded on subsequent invocations of the application.

LearnFX-Config-ss

Until the contest begins, there is a sample question available if you wish to give this application a try before the real questions begin appearing.  By the way, when you use the LearnFX client, your tweet is a reply to the projavafxcourse user, and the message contains the following with the question ID, and answer that you supply, added to the end:

@projavafxcourse Answering JavaFXpert question http://bit.ly/2dn1kK

The bit.ly link in the message may be clicked by your followers to see what your strange tweet is about :-)

There is a WidgetFX version of this application in the works that I'll release and blog about in a subsequent post.  By the way, I'd like to publicly thank Steven Herod for the Twitter API this application uses, which he donated to the open source JFXtras project.

Regards, and good luck!  Please leave a comment if you have any questions,

Jim Weaver

Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, Educational JavaFX Sc..."
Send by mail Print  Save  Delicious 
Date: Tuesday, 20 Oct 2009 21:14

Sten Anderson, winner of the Sun JavaFX Coding Challenge with his Music Explorer FX app, has just released a version for JavaFX Mobile.  Sten donated the source code to the JFXtras project, and has provided a write-up in his blog which includes a Java Web Start link.

MEFX_Similar

Music Explorer FX Mobile Edition is a great resource/reference for creating JavaFX Mobile apps, so check it out!

Enjoy, and thanks Sten,

Jim Weaver

Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, JavaFX Mobile, JFXtra..."
Send by mail Print  Save  Delicious 
Date: Tuesday, 13 Oct 2009 19:22

In the JavaFXpert RIA Exemplar Challenge announcement, I stated that the graphic design judge would be chosen and disclosed soon.  I am pleased to say that there will actually be two very high-caliber graphic design judges for this contest: Jasper Potts and Romain Guy.  As if these guys needed an introduction:

Jasper-potts Jasper Potts is a developer on the JavaFX & Swing teams at Sun Microsystems, and lives in Bath, UK. He is currently working on the new JavaFX UI controls and graphics frameworks, and was the bloke that created the JavaFX Charts API.  Jasper, and Richard Bair, have an excellent JavaFX blog at fxexperience.com, where Jasper has already begun providing tips for the RIA Exemplar Challenge participants.


Romain-guy Romain Guy is the co-author of the ground-breaking Filthy Rich Clients book, and is a user interface toolkit engineer at Google on the Android project. Romain lives in San Francisco, California, and has a blog named Curious Creature that contains some stunning photographs, very recently of the Colorado River at sunset.  He also has a "French, goofier version of Curious Creature" named #ProgX.



Steve-chin Stephen Chin, a Pro JavaFX book co-author, is going to help me judge the RIA Exemplar Challenge entries from a developer perspective.  Stephen is the leader (with Keith Combs), of the WidgetFX and JFXtras projects.  Stephen is very active in the leadership of the JavaFX community, having recently founded the Silicon Valley JavaFX User Group, and has a JavaFX/Java blog at steveonjava.com.


All three are internationally recognized experts and speakers, and I am very pleased to have them help me judge the RIA Exemplar Challenge.  Please be sure and enter the challenge!

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX - General, JavaFXpert RIA Exempla..."
Send by mail Print  Save  Delicious 
Date: Tuesday, 06 Oct 2009 23:35

One of the student winners of the the JavaFX Coding Challenge is Kazuki Hamasaki, who created the CalcFX program.  CalcFX is a deceptively functional (and incredibly useful) calculator, and is now one of the Java Web Start shortcuts on my desktop.

Calcfx


Kazuki: If you're reading this, please create a desktop icon for CalcFX so that it doesn't blend in with the usual coffee-cup icons deposited by Java Web Start.  For those wondering, just put the following line subordinate to the information element of the JNLP file:

<icon href="some_icon.png" width="64" height="64"/>

Congrats, and nice work, Kazuki!

Jim Weaver

Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, JavaFX Apps, WidgetFX"
Send by mail Print  Save  Delicious 
Date: Monday, 28 Sep 2009 22:49

If you've hung around senior [-citizen] programmers (or are one), you've no doubt heard tales such as "we only had 4K of memory, and had to make use of every byte/bit".  For your amusement and edification, here's a picture from thegreatgeekmanual.com of the first Apple II (circa 1977), which sported 4K of RAM:

Apple-II

Josh Marinacci's latest JavaFX Studio Challenge is a bit reminiscent of these good old days, in that he is encouraging us to create a cool JavaFX program that "must not be more than 30 lines of code or 3000 characters (your choice)".

The deadline for submitting your entry for this JFXStudio Challenge is midnight Wednesday night (30 September 2009). The challenge is to create something cool in only 30 lines of JavaFX Script code, using the theme of 'Time'. To give you some ideas Josh has posted his own entry. Take a look for some inspiration!

Screen shot 2009-09-28 at 6.32.26 PM

Speaking of contests, the winners of the WidgetFX Developers Contest were announced yesterday, and I'd like to convey my congratulations to Pär Dahlberg (ScreenshotFX widget), Yannick Van Godtsenhoven (RadioFX widget), and Larry Dickson (Weather widget).  A screenshot of these widgets in the WidgetFX dock is shown on the right. I'm using the RadioFX widget as I'm writing this to listen to an internet music channel that plays baroque music.

Regards, and congratulations again to these winners!

Jim Weaver


Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, JavaFX Apps, WidgetFX"
Send by mail Print  Save  Delicious 
Date: Friday, 25 Sep 2009 20:20

If you've been following this blog recently, you know that I've been developing an application in the SpeedReaderFX category that helps me quickly keep up on new happenings in world events, technology, gadgets, music, and social networks.  SpeedReaderFX is located in the JFXtras open source project, and also serves as an example of using JFXtras classes with JavaFX.

One of the newest enhancements made to the SpeedReaderFX program takes advantage of the Picker control that David Armitage created in the JFXtras project.  Here's a screen shot of a program in the JFXtras project that he created to demonstrate and test the Picker control varieties:

Screen shot 2009-09-25 at 12.28.40 PM

SpeedReaderFX uses the spinner-style variation of the Picker control, shown in the Thumb Wheel row of the screen shot above.  This enables SpeedReaderFX users to quickly choose how many entries of a given feed-type (e.g. Yahoo News feeds), to display in the scrolling table.  The screen shot below shows a portion of the SpeedReaderFX Criteria dialog in which the Pickers appear:

Screen shot 2009-09-25 at 12.54.15 PM

As noted previously in the Picker demo screen shot, the user can operate the mouse wheel, as well as the keyboard or mouse buttons, to select the desired number.

6a00e54f133d6988340120a574de26970b-800wi

For more information about the SpeedReaderFX application, check out the first post in the SpeedReaderFX category of this blog.  To run the application, click the SpeedReaderFX icon located on the left side of this paragraph.

By the way, since this dialog is getting pretty crowded, Dean Iverson is creating some UI design comps in which each feed type will have its own page.  I've also received other ideas from readers that I plan to implement, and would like to express my appreciation for your continued input!

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX - General, JavaFX Apps, JFXtras, ..."
Send by mail Print  Save  Delicious 
Date: Friday, 18 Sep 2009 22:28

When adding more feeds to the SpeedReaderFX application's Criteria dialog, I found that some of them don't *quite* comply with RSS/Atom formats.  For example, I thought it'd be cool to have RSS feeds from Engadget and Gizmodo (what self-respecting geek wouldn't want those feeds?)  I also wanted to have a daily dose of Dilbert delivered, but in these three cases the JavaFX RSS API reported that the dates for the feed items were just prior to the OS epoch.

SpeedReaderFX_screenshot_geektoys

Naturally, I consulted the RSS/Atom Smasher himself (Rakesh Menon) and he instructed me in the ways of creating a custom feed parser, which I added to SpeedReaderFX.  Here's a partial screenshot of the Criteria dialog where you can select the Gizmodo, Engadget, TechCrunch, and Dilbert feeds:

SpeedReaderFX_screenshot_criteria_geektoys

SpeedReaderFX_logo95X60 For more information about the SpeedReaderFX application, check out the first post in the SpeedReaderFX category of this blog.  To run the application, click the SpeedReaderFX icon located on the left side of this paragraph.

By the way, one of the next things that SpeedReaderFX needs is a GUI makeover (I've received lots of helpful feedback in that regard, and my graphical skills are admittedly weak).  Please leave a comment to this post if you have ideas or graphic comps that would make this look more like an iPhone app.  SpeedReaderFX is a sample in the open source JFXtras project, and your contributions to the appearance of this application would be much appreciated and acknowledged on this blog.

Enjoy!
Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX Apps, JFXtras, SpeedReaderFX"
Send by mail Print  Save  Delicious 
Date: Friday, 11 Sep 2009 19:21

Speedreader_icon_128x128 Some of you may remember the advertisements for the Evelyn Wood Reading Dynamics course back in the 1970s.  Here's a flashback in which Steve Allen (an excellent former host of the Tonight Show), is interviewing students of this course.  Gotta love those '70s hairstyles :-) 

This course promised to increase reading speed and comprehension, partially (as I recall) by using the technique of scanning a page while limiting eye movement. 

Evelyn-Wood-Reading-Dynamics-Outlook

The ability to digest new information quickly is at least as important now as it was 20+ cranks of Moore's Law ago.  RSS and Atom feeds have provided mechanisms to publish information as it becomes available, and social networking tools such as Twitter have HTTP-based APIs.  Because it is time consuming to visit various sources of new information, I've begun developing a tool named SpeedReaderFX to present information obtained via RSS, Atom, and social networking APIs in one place.

Here's a screen shot of SpeedReaderFX as it is displaying new items of interest:

SpeedReaderFX_screenshot_1

In the screen shot above, there are tweets from interesting people (Josh Marinacci and Dean Iverson), a picture taken by some fortunate soul viewing a beautiful Australian sunrise, a video containing stunning new pictures from the Hubble telescope, and an article about an expensive bottle of wine.  These are displayed in the very impressive Table component that Stephen Chin and Keith Combs are creating for the open source JFXtras project.  A future post will explain how to use the JFXtras Table component, using this SpeedReaderFX program as the example.

The popup menu shown above enables the user to hide a given feed (l8r, Dean!), or open the URL associated with an item in a browser (in this case, Dean's Twitter post).  Note that because JavaFX does not yet have a popup menu, I leveraged the menu bar/menu capabilities of the JFXtras project to make this slightly odd-looking popup menu.  If a popup menu isn't available in the next version of JavaFX, one will be created in the JFXtras project.

To inform SpeedReaderFX about your items of interest, choose the Channels>Configure menu option.  The Criteria dialog will appear (a portion shown below), enabling you to specify user names, tags, and blog feeds for various feed sources and social networks.

SpeedReaderFX_screenshot_criteria  

The prompts in the shorter text boxes indicate the type of information that may be typed into the box.  For example, you'll separate the search tags in a Flickr text box with commas.  The program has some text boxes filled in with examples, but you can overwrite them.  A not-too-distant future version of this program will automatically save your criteria when exiting, and will load it again upon start-up.  The SpeedReaderFX category of this blog will contain posts that point out some JavaFX code behind new functionality, as well as catching you up on some of the code used so far in this program.  For example, I'll cite the JavaFX library that Rakesh Menon created to read the YouTube Data API, which I'm using in this program.

Selecting a check box causes the associated information source to be read and displayed in the table shown previously, with its items interspersed with items from other sources in reverse chronological order.  Deselecting a check box removes the associated items from the table, which is the same result as the Hide this feed popup menu item discussed earlier.

When you're finished with the Criteria dialog, click the Close button in the upper right corner, or select the Channels>Configure menu option again.  By the way, the View menu has a couple of options that help you manage the application's window, given that you'll be opening up content in a browser.  One menu item is the self-explanatory Always on Top, and the other one enables you to Hide the Date Published Column.

Now that you know how to use SpeedReaderFX, please give it a whirl by clicking the Web Start Launch button below.  As always, please leave a comment if you have any questions or comments.

Webstartsmall2

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX SDK 1.2, JavaFX Tips and Tricks, ..."
Send by mail Print  Save  Delicious 
Date: Monday, 17 Aug 2009 22:32

As I mentioned the previous article in this series, the next step in the development of the BandmatesFX program will be to enable the user to navigate more general information than just musicians and bands.  In this article, I've added the ability to navigate soccer players and their teams.  In addition, the program (whose working title is now Topic Map Navigator), can be deployed as a full-browser-page JavaFX applet.  Shown below is a screenshot of the program running in a Chrome 2.0 browser, and it also runs in FireFox 3.5+ and Internet Explorer 7+.  You'll usually need have Java SE 6 update 10+ in order for the applet to run in the browser (e.g. on Mac with Java 1.5 this app opens in its own window).

TopicMapNavigator

One of the features of this program is that it opens a web page when you right-click on an image.  Deploying this program in the browser makes this a tighter experience, because the page appears on top of the Topic Map Navigator program.  When you subsequently close the web page, the program is revealed again.  The screenshot below shows the result of clicking the secondary mouse button on the picture of Lionel Messi, and then clicking the Wikipedia link from his Freebase web page that appears. You may also recall from previous articles in this series that clicking the primary mouse button on an image moves that person to the top of the app.

TopicMapNavigator_wikipedia

If you have a late-model Chrome, FireFox or Internet Explorer browser, and Java SE 6 update 10+, go ahead an run this program as a JavaFX applet.  If not, you can launch the program via Java Web Start by clicking the Launch button below.  Note: Please leave a comment if you have any difficulty deploying this JavaFX applet, providing your hardware/OS/browser/Java version information.  I'll report these difficulties to the JavaFX JIRA issue tracker, as I'd like for the JavaFX applet deployment experience to be as solid as it is when deploying with Java Web Start.

Webstartsmall2

Exercising Resizing

In order for the JavaFX applet to occupy the full browser page, we change the width and height of the applet to 100% in the HTML file as shown in the snippet below.

  javafx(
    {
      archive: "TopicMapNavigator.jar",
      draggable: true,
      width: "100%",
      height: "100%",
      code: "org.jfxtras.topicmapnav.ui.TopicMapNavMain",
      name: "TopicMapNavigator",
      loading_image_url: "http://www.jmentor.com/JavaFX_1-2/TopicMapNavigator/images/guitar.png",
      loading_image_width: 500,
      loading_image_height: 350
    }
  );

When the browser page is resized, the width and height values of the JavaFX Stage change dynamically.  You can bind to these values and control the appearance of the program, using layout classes that are provided with JavaFX.  In addition, the JFXtras project has some classes such as ResizableScene, ResizableCustomNode, ResizableHBox and ResizableVBox that make quick work of responding to a resized Stage.  For example, the Topic Map Navigator program uses these classes, and the resizable Shelf class, to automatically reposition and scale the cover flows when the user resizes the program.

Regards, and please let me know if you have any questions,

Jim Weaver

Author: "Jim Weaver" Tags: "Cool JavaFX Stuff, Freebase Contributing..."
Send by mail Print  Save  Delicious 
Date: Thursday, 13 Aug 2009 04:28

Jonathan Giles has announced the release of the JavaFX Menubar that he created for the JFXtras project.  To demonstrate how to use it, I've added a menu to the BandmatesFX program that I've been developing in this series of blog posts

By the way, my grand scheme for the BandmatesFX program is for it to become what I'm calling an image-based knowledge navigation facility.  It's going to be an open-source JFXtras example, where Sten Anderson (JavaFX Coding Challenge winner) and others will collaborate with me in its continued design and development.  A baby step in that direction has been to add the ability to reference space mission information so that users can interact with astronauts and missions in the same way they can now interact with musicians and bands.  Here's a screenshot of the program with the JFXtras menu:

BandmatesFX_astronauts  

As you can see from the screenshot, there are a couple of items in the View menu, enabling the user to toggle the following states:

  • The Google Map menu item controls whether the map shown above is visible.
  • The Topics with No Image menu item controls whether topics (e.g. astronauts, missions, musicians, and bands) that don't have an associated image in the Freebase database) will be displayed.

Go ahead and launch the application using the Java Web Start Launch button below, consulting past articles such as this one in the series for instructions on how to use it.  Note: Now that there is a Help menu, it'd probably be a good idea for me to put the instructions in a help facility :-P

Webstartsmall2

Here's the menu-related code in this program:

var menubar: MenuBar;
menubar = MenuBar {
  width: bind sceneRef.width;
  menus: [
    // View Menu
    Menu {
      text: "View"
      items: [
        CheckedMenuItem {
          text: "Google Map"
          checked: bind showLocationMap with inverse
          graphic: bind if (showLocationMap) {
            ImageView {
              image: Image {
                url: "{__DIR__}images/lightbulb_on.png";
              }
            }
          }
          else {
            ImageView {
              image: Image {
                url: "{__DIR__}images/lightbulb.png";
              }
            }
          }
        },
        CheckedMenuItem {
          text: "Topics with No Image"
          checked: bind showTopicsThatHaveNoImage with inverse
          action: function() {
            obtainGroupsForArtist(artistToSearch);
          }
          graphic: bind if (showTopicsThatHaveNoImage) {
            ImageView {
              image: Image {
                url: "{__DIR__}images/lightbulb_on.png";
              }
            }
          }
          else {
            ImageView {
              image: Image {
                url: "{__DIR__}images/lightbulb.png";
              }
            }
          }
        }
      ]
    },
    // Help Menu
    Menu {
      text: "Help"
      items: [
        MenuItem {
          text: "About"
          action: function() {
            Alert.inform("About BandmatesFX",
                         "Developed by Jim Weaver/JFXtras team to "
                         "demonstrate JFXtras (and Freebase) features.");
          }
          graphic: ImageView {
            image: Image {
              url: "{__DIR__}images/about.png";
            }
         }
        }
      ]
    }
  ]
}

Jonathan has done a great job in defining a simple API, as well as creating an appearance for these menus that blend well with the Caspian skin in the JavaFX 1.2 UI controls.  Thanks Jonathan!

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "Freebase Contributing Artists App, JavaF..."
Send by mail Print  Save  Delicious 
Date: Sunday, 09 Aug 2009 03:11

In this episode of the building the BandmatesFX application series, I'm going to show you how to add the following functionality to a JavaFX application:

  1. Showing a splash page before the main functionality of the program starts.
  2. Handling mouse events on the individual images in a JFXtras Shelf (cover flow) control.
  3. Detect whether the JavaFX program is running as an applet in the browser.
  4. Open a web page in a browser, whether running as an applet or from Java Web Start.
  5. Use the GoogleMap custom node from Sergey Surikov's open source CRUDfx project (the treasure trove mentioned in the title) to display an interactive Google map in a JavaFX program.

Before we get into how to do these things, take the newest iteration of the BandmatesFX app for a spin, making sure that you test out the new functionality mentioned above.

Webstartsmall2

There are some pointers after the screenshot below to help you along.

BandmatesFX_Axl  

  • After invoking the BandmatesFX app, start typing (for example) Axl Rose and notice that a list appears suggesting William Bailey (Axl's given name). 
  • Click on William in the list, and the screen should look almost like the screenshot above. Note: After this was posted, I altered the queries so that if an image of an artist or band isn't available in Freebase (and therefore not in Wikipedia), it will show a placeholder image.
  • Hover the mouse on the images in each of the cover flows, noticing that the name of the band or artist appears in a popup window on the upper left side of the images.
  • Click the secondary mouse button on any of the images, and the Freebase.com page for that band or artist should appear in the browser.
  • Look at the map in the upper right portion of the application, noticing that Axl was born in Lafayette, Indiana (which is about 80 miles from where I live).  Try clicking on the map and dragging the mouse, which should expose other parts of Indiana and the United States.
  • Recall from the last article in this series that clicking the artist that is in the center of the bottom Shelf will move his/her picture to the top of the app.  The bands and artists in the cover flows will be replaced accordingly.  Trivia: According to the screenshot above, the given name of the Guns N' Roses lead guitarist is Saul Hudson (who is more widely known as Slash).

Some Example Code Snippets

Here are some code snippets behind the new functionality:

/**
* Use the availability of the eval function (that uses the browser's
* JavaScript engine), as an indicator that we're running as an applet
*/
def runningAsApplet:Boolean = AppletStageExtension.eval("2+3") != null;

var splashStageRef:Stage;

/*
* Show a "splash" page (Stage) while the main Stage is performing some startup
* functionality.  At the end of this script, this splash screen will be removed
* with the following lines of code:
*
*   if (not runningAsApplet) {
*     splashStageRef.close();
*   }
*
* Note: To show a splash page when tunning as an applet, use the following
*       loading_image_* lines in a script tag of the HTML file:
*
*   javafx(
*       {
*             archive: "BandmatesFX.jar",
*             draggable: true,
*             width: 1000,
*             height: 700,
*             code: "javafxpert.BandmatesMain",
*             name: "BandmatesFX",
*             loading_image_url: "http://www.jmentor.com/JavaFX_1-2/BandmatesFXnext/images/guitar.png",
*             loading_image_width: 1000,
*             loading_image_height: 700
*       }
*   );
*
*/
if (not runningAsApplet) {
  splashStageRef = Stage {
    title: "BandmatesFX Splash Page"
    style: StageStyle.TRANSPARENT
    scene: Scene {
      width: 1000
      height: 700
      content: {
        ImageView {
          image: Image {
            url: "http://www.jmentor.com/JavaFX_1-2/BandmatesFXnext/images/guitar.png"
          }
        }
      }
    }
  }
}

...some code omitted...

/*
* This instantiates the GoogleMap custom node that Sergey Surikov developed
*/
googleMapRef = GoogleMap {
  focusTraversable: true
  width: IMAGE_HEIGHT
  height: IMAGE_HEIGHT
  zoom: 4.0
  // Make the up and down arrows affect the zoom level of the map
  onKeyPressed:function(ke:KeyEvent):Void {
    println("googleMapRef.zoom:{googleMapRef.zoom}");
    if (ke.code == KeyCode.VK_UP) {
      googleMapRef.zoom += 1;
    }
    else if (ke.code == KeyCode.VK_DOWN) {
      googleMapRef.zoom -= 1;
    }
  }
},

...some code omitted...

/*
* To change the geographic location shown by the GoogleMap node, change its
* latitude and longitude variables.
*/
googleMapRef.latitude = if (latStr == "") 0.0 else Float.parseFloat(latStr);
googleMapRef.longitude = if (longStr == "") 0.0 else Float.parseFloat(longStr);

/*
* Here is the Shelf that contains the images of the bands for the chosen artist
*/
Shelf {
  reflection: false
  showScrollBar: false
  showText: true
  centerEventsOnly: false
  imageUrls: bind for (grp in freebaseResult.result.musicGroupMemberMembership) {
    "{freebaseImageURL}{grp.group.id}?maxheight={IMAGE_HEIGHT}"
  }
  imageNames: bind for (grp in freebaseResult.result.musicGroupMemberMembership) {
    grp.group.name;
  }
  /*
   * When the secondary mouse button is pressed on an image, open a page
   * in the browser for that band.  If running as an applet, use the
   * javafx.stage.AppletStageExtension class.  If running as a Java Web Start
   * application, the use the BasicService class (located in jnlp.jar)
   * to open the web page.
   */
  onImagePressed:function(se:ShelfEvent):Void {
    if (se.mouseEvent.button == MouseButton.SECONDARY) {
      def fbId = freebaseResult.result.musicGroupMemberMembership[se.index].
                 group.id;
      if (runningAsApplet) {
        AppletStageExtension.showDocument("http://www.freebase.com/view/{fbId}",
                                          "_blank");
      }
      else {
        def basicService:BasicService =
            ServiceManager.lookup("javax.jnlp.BasicService") as BasicService;
        def url:URL = new URL("http://www.freebase.com/view/{fbId}");
        basicService.showDocument(url);
      }
    }
  }
  /*
   * When the mouse enters an image, make a popup visible that contains the
   * name of the band represented by the image.
   */
  onImageEntered:function(se:ShelfEvent):Void {
    println("Entered image:{se.index}, obj:{se.mouseEvent.node}");
    println(freebaseResult.result.musicGroupMemberMembership[se.index].
       group.name);
    infoBoxName = freebaseResult.result.musicGroupMemberMembership[se.index].
       group.name;
    infoBoxVisible = true;
    infoBoxPosX = se.mouseEvent.node.localToScene(se.mouseEvent.node.layoutBounds).minX;
    infoBoxPosY = se.mouseEvent.node.localToScene(se.mouseEvent.node.layoutBounds).minY;
  }
  /*
   * When the mouse exits an image, make the popup invisible
   */
  onImageExited:function(se:ShelfEvent):Void {
    println("Exited image:{se.index}");
    infoBoxVisible = false;
  }
  index: bind groupOneIndex with inverse
  thumbnailWidth: IMAGE_HEIGHT
  thumbnailHeight: IMAGE_HEIGHT
  layoutInfo: LayoutInfo {
    width: bind sceneRef.width
    height: IMAGE_HEIGHT + 120
  }
},


As always, please leave a comment if you have any questions.

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "Freebase Contributing Artists App, JavaF..."
Send by mail Print  Save  Delicious 
Date: Wednesday, 05 Aug 2009 23:45

Three_dog_night Prolific reviewer highway_star had this to say about the Three Dog Night Captured Live at the Forum album (paraphrased a bit).

"Three Dog Night was one of the seventies' most popular groups. Even though most of their songs were composed by other songwriters (Paul Williams, Hoyt Axton, Randy Newman and Nilsson to name a few), the combination of three excellent lead singers and a fantastic backup band ensured that they had more hits than most bands. This concert recorded on September 12th, 1969 at The Forum in Los Angeles, is one of the best concerts this reviewer has ever heard."

As an aside, I was surprised to find out that Randy Newman wrote the Three Dog Night hit song entitled "Mama Told Me Not to Come" :-O

At any rate, if you missed Three Dog Night live at the Forum, as a consolation I can highly recommend the JFXtras and WidgetFX presentation captured live at the SDForum

SDForum_preso

If you want to keep up on the latest additions to these JavaFX open source projects, then watch the video of this presentation in which Stephen Chin and Keith Combs skillfully walk you through the very cool and useful features!

Regards,
Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX - General, JFXtras, WidgetFX"
Send by mail Print  Save  Delicious 
Date: Friday, 24 Jul 2009 06:34

So far in this Freebase Contributing Artists App series, we've been developing a JavaFX application that enables the user to navigate connections among musicians.  I'm calling this application BandmatesFX, and it uses the JSONHandler feature of the JFXtras open source library to easily query the Freebase.com database.

Note: While using this app, I noticed that drummer Aynsley Dunbar has played with lots of bands over the years, so he's a good starting point for trying to navigate to another given musician in six or less degrees.  Try, for example, to navigate from Aynsley Dunbar to Roy Orbison.  Here's one way in five degrees:

  1. Aynsley Dunbar played in The Animals, with Andy Summers
  2. Andy Summers played in The Police, with Sting
  3. Sting played in Band Aid, with Paul McCartney
  4. Paul McCartney played in The Quarrymen (and of course The Beatles), with George Harrison
  5. George Harrison played in The Traveling Wilburys, with Roy Orbison

Today I'm going to point out some enhancements to this application, and the updated code, which are reflected in the following screenshot:

BandmatesFX_Aynsley_small


These enhancements include:

  • The user can type in an artist name, and with each keystroke the Freebase database web service is invoked, returning suggested names from which the user can choose.
  • Band and artist pictures are presented in a cover-flow style, using the JFXtras Shelf component.  In addition, the JFXtras TitledBorder component is employed to enclose and label the cover-flows.
  • When the user clicks the central image in the bottom (e.g. Steve Smith in the screenshot above), that artist becomes the featured artist at the top of the page.  The group cover-flow images are updated to reflect the groups in which the artist has played, and the member cover-flow images contain the artists that have played in the currently selected group.

One of the cool feature of the JFXtras Shelf component is that the mouse wheel moves the images horizontally on the Shelf, enabling the user to navigate even more quickly than clicking on one of the images.  Before invoking this application from the Web Start link at the end of this article, take a look at the main script of the program (named BandmatesFX.fx) in the listing below:

/*
* BandmatesMain.fx
*
* Uses Freebase and JFXtras with JavaFX to explore connections
* between musical artists
*
* Developed by James L. Weaver to demonstrate using JavaFX and JFXtras
*/

package javafxpert;

import javafx.io.http.HttpRequest;
import javafx.animation.transition.*;
import javafx.geometry.HPos;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ListView;
import javafx.scene.control.TextBox;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.stage.Stage;

import org.jfxtras.data.pull.*;
import org.jfxtras.scene.border.TitledBorder;
import org.jfxtras.scene.control.Shelf;

/**
* Height of the images that we'll be working with
*/
def IMAGE_HEIGHT:Integer = 140;

/**
* Artist for which we're searching bandmates
*/
var artistToSearch:String = "/en/aynsley_dunbar";

/**
* Name for which we're finding matches and ids
*/
var nameToFind:String = "Aynsley Dunbar";

var textBoxRef:TextBox;
var listViewRef:ListView;
var selectedNameIndex = bind listViewRef.selectedIndex on replace {
  def selectedId = freebaseSearchResult.result[selectedNameIndex].id;
  if (selectedId != "") {
    println("selectedId:{selectedId}");
    nameToFind = freebaseSearchResult.result[selectedNameIndex].name;
    obtainGroupsForArtist(selectedId);
  }
};

/**
* Hover text that contains the name of the artist or group
*/
var nameHoverText:String;

/**
* A reference to the HTTP request, for the purpose of monitoring progress
*/
var req:HttpRequest;

/**
* The root class that will hold the object graph from the JSON results
*/
var freebaseResult:FreebaseResult;

/**
* The root class that will hold the object graph from the JSON results
*/
var freebaseSearchResult:FreebaseSearchResult;

/**
* The base URL for the freebase query
*/
def freebaseURL = "http://www.freebase.com/api/service/mqlread?";

/**
* The base URL for a freebase search request
*/
def freebaseSearchURL = "http://www.freebase.com/api/service/search?";

/**
* The base URL to get a freebase image
*/
def freebaseImageURL = "http://img.freebase.com/api/trans/image_thumb";

var artistsNode:Node;

/**
* Fade in transition for artists
*/
def shelfFadeIn = FadeTransition {
  node: bind artistsNode
  duration: 1500ms
  fromValue: 0.2
  toValue: 1.0
}

/**
* Indexe into groups list
*/
var groupOneIndex:Integer on replace {
  shelfFadeIn.playFromStart();

  // Choose the middle one
  def numArtists:Integer = sizeof freebaseResult.result.
                          musicGroupMemberMembership[groupOneIndex].
                          group.musicMusicalGroupMember;
  artistTwoIndex = if (numArtists > 1) numArtists / 2 else 0;
  
  groupOneName = freebaseResult.result.
                 musicGroupMemberMembership[groupOneIndex].group.name;
};

/**
* Name of the currently selected band
*/
var groupOneName:String;

/**
* Index into artists list
*/
var artistTwoIndex:Integer;

/**
* Create a search query and invoke the JSON handler
*/
function obtainIdForArtistPartialName(artistPartialName:String) {
  listViewRef.visible = true;
  nameToFind = artistPartialName;
  def partialName = artistPartialName.replace(" ", "+");
  var searchUrl = "{freebaseSearchURL}prefix={partialName}&type=/music/artist&limit=10&mql_output=[\{\"id\":null,\"name\":null\}]";

  println("searchUrl:{searchUrl}");
  var albumHandler:JSONHandler = JSONHandler {
    rootClass: "javafxpert.FreebaseSearchResult"
    onDone: function(obj, isSequence): Void {
      freebaseSearchResult = obj as FreebaseSearchResult;
      println("# of search results:{sizeof freebaseSearchResult.result},freebaseSearchResult:{freebaseSearchResult.code}");
      req.stop();
    }
  };
  req = HttpRequest {
    location: searchUrl
    onInput: function(is: java.io.InputStream) {
      albumHandler.parse(is);
    }
  };
  req.start();
}

/**
* Create the Freebase query and invoke the JSON handler
*/
function obtainGroupsForArtist(artistFreebaseId:String) {
  listViewRef.visible = false;
  artistToSearch = artistFreebaseId;
  var queryUrl = "{freebaseURL}query=\{\"query\":"
    " \{ "
    "   \"/common/topic/image\": [\{ "
    "     \"id\": null "
    "   \}], "
    "   \"/music/group_member/membership\": [\{ "
    "     \"group\": \{ "
    "       \"name\": null, "
    "       \"id\":   null, "
    "       \"/common/topic/image\": [\{ "
    "         \"id\": null "
    "       \}], "
    "       \"/music/musical_group/member\": [\{ "
    "         \"member\": \{ "
    "           \"name\": null, "
    "           \"id\":   null, "
    "           \"/common/topic/image\": [\{ "
    "             \"id\": null "
    "           \}] "
    "         \} "
    "       \}] "
    "     \} "
    "   \}], "
    "   \"id\":   \"{artistFreebaseId}\", "
    "   \"name\": null, "
    "   \"type\": \"/music/artist\" "
    " \} \}";

  println("queryUrl:{queryUrl}");
  var albumHandler:JSONHandler = JSONHandler {
    rootClass: "javafxpert.FreebaseResult"
    onDone: function(obj, isSequence): Void {
      freebaseResult = obj as FreebaseResult;
      println("# of bands:{sizeof freebaseResult.result.musicGroupMemberMembership}");
      req.stop();

      // Choose the middle one
      def numGroups:Integer = sizeof freebaseResult.result.musicGroupMemberMembership;
      groupOneIndex = if (numGroups > 1) numGroups / 2 else 0;
    }
  };
  req = HttpRequest {
    location: queryUrl
    onInput: function(is: java.io.InputStream) {
      albumHandler.parse(is);
    }
  };
  req.start();
}
var sceneRef:Scene;

Stage {
  title: bind "BandmatesFX - {nameToFind}"
  scene: sceneRef = Scene {
    width: 1000
    height: 700
    content: [
      ImageView {
        image: Image {
          url: "http://www.popsci.com/files/imagecache/article_image_large/files/articles/guitar.gif"
        }
        fitWidth: bind sceneRef.width
        preserveRatio: true
        opacity: 0.1
      },
      VBox {
        nodeHPos: HPos.CENTER
        layoutY: 10
        spacing: 10
        content: [
          HBox {
            spacing: 10
            content: [
              ImageView {
                image: bind Image {
                  url: "{freebaseImageURL}{artistToSearch}?maxheight={IMAGE_HEIGHT}"
                }
              },
              VBox {
                content: [
                  textBoxRef = TextBox {
                    promptText: "Enter artist name"
                    text: bind nameToFind with inverse
                    columns: 20
                    font: Font.font(null, 14)
                    action:function():Void {
                      if (nameToFind != "" and (req.percentDone == 0.0 or req.percentDone == 100.0)) {
                        obtainIdForArtistPartialName(nameToFind);
                      }
                    }
                    onKeyTyped:function(ke:KeyEvent) {
                      println("req.percentDone:{req.percentDone}");
                      if (textBoxRef.rawText != "" and (req.percentDone == 0.0 or req.percentDone == 100.0)) {
                        obtainIdForArtistPartialName(textBoxRef.rawText);
                      }
                    }
                  },
                  listViewRef = ListView {
                    visible: false
                    height: 100
                    items: bind for (rslt in freebaseSearchResult.result) {
                      rslt.name
                    }
                    layoutInfo: LayoutInfo {
                      width: bind textBoxRef.width - 10
                      height: 80
                    }
                  }
                ]
              },
              ProgressIndicator {
                progress: bind req.progress
              },
              Label {
                text: bind nameHoverText
                font: Font.font(null, FontWeight.BOLD, 18)
              }
            ]
          },
          TitledBorder {
            text: bind "{nameToFind} played in these groups:"
            font: Font.font(null, FontWeight.BOLD, 14)
            lineColor: Color.GREY
            node: Shelf {
              reflection: false
              showScrollBar: false
              showText: true
              imageUrls: bind for (grp in freebaseResult.result.musicGroupMemberMembership) {
                "{freebaseImageURL}{grp.group.id}?maxheight={IMAGE_HEIGHT}"
              }
              imageNames: bind for (grp in freebaseResult.result.musicGroupMemberMembership) {
                grp.group.name;
              }
              index: bind groupOneIndex with inverse
              thumbnailWidth: IMAGE_HEIGHT
              thumbnailHeight: IMAGE_HEIGHT
              layoutInfo: LayoutInfo {
                width: bind sceneRef.width
                height: IMAGE_HEIGHT + 120
              }
            }
          },
          artistsNode = Panel {
            content: bind for (grp in freebaseResult.result.musicGroupMemberMembership) {
              TitledBorder {
                text: bind "{groupOneName} has had the following members:"
                font: Font.font(null, FontWeight.BOLD, 14)
                lineColor: Color.GREY
                node: Shelf {
                  visible: bind indexof grp == groupOneIndex
                  reflection: false
                  showScrollBar: false
                  showText: true
                  imageUrls: bind for (mmbr in freebaseResult.result.
                                           musicGroupMemberMembership[indexof grp].
                                           group.musicMusicalGroupMember) {
                    "{freebaseImageURL}{mmbr.member.id}?maxheight={IMAGE_HEIGHT}"
                  }
                  imageNames: bind for (mmbr in freebaseResult.result.
                                           musicGroupMemberMembership[indexof grp].
                                           group.musicMusicalGroupMember) {
                    mmbr.member.name
                  }
                  onCenterImagePressed:function(me:MouseEvent):Void {
                    var mmbr = freebaseResult.result.
                               musicGroupMemberMembership[indexof grp].
                               group.musicMusicalGroupMember[artistTwoIndex];
                    nameToFind = mmbr.member.name;
                    artistToSearch = mmbr.member.id;
                    obtainGroupsForArtist(mmbr.member.id);
                  }
                  index: bind artistTwoIndex with inverse
                  thumbnailWidth: IMAGE_HEIGHT
                  thumbnailHeight: IMAGE_HEIGHT
                  layoutInfo: LayoutInfo {
                    width: bind sceneRef.width
                    height: IMAGE_HEIGHT + 120
                  }
                }
              }
            }
            layoutInfo: LayoutInfo {
              width: bind sceneRef.width
              height: IMAGE_HEIGHT + 120
            }
          }
        ]
      }
    ]
  }
}
obtainGroupsForArtist(artistToSearch);


To try out this application, click the Web Start link below.  Since this application is a work in progress, I'll give you a couple of pointers:

  • When typing the name of an artist in the text box, each key invokes a web service, so wait until the progress indicator is solid before typing the final character (I'll make this smoother in a future iteration).
  • Not all artists are in groups, and I'm not doing the necessary exception handling yet to catch this in the response from Freebase.  I know that many artists such as Eric Clapton, Bob Dylan, and Steve Winwood work, as well as any artist that you can click in the bottom cover flow (by definition they are members of a group).

Webstartsmall2

For more background on this application, see the previous article in this series.  As always, please leave a comment if you have any questions.  Also, if you have any suggestions for future enhancements, please leave a comment as well.

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "Freebase Contributing Artists App, JavaF..."
Send by mail Print  Save  Delicious 
Date: Tuesday, 21 Jul 2009 21:26

Phil_dodds Philip Dodds was a brilliant audio engineer, an e-learning pioneer, and operated the synthesizer in Close Encounters of the Third Kind (he's the one in the middle of the picture shown from the movie).  Philip used to say that "working code trumps all theories", which is very relevant to the the JavaFX examples repository library announcement that Stephen Chin made this morning.

This repository, which is located in the JFXtras Community Site, contains working code and Web Start links for a growing number of examples in JavaFX books and blogs.

Jfxtras_portal_mockup_community_version_031

You are cordially invited to take a look at the examples in the site, and contribute your own JavaFX examples!  To get you started, here's the link to the site that contains a Color Picker example from the Pro JavaFX book.

Color_picker_snowflake_jfxtras

Regards,

Jim Weaver

Author: "Jim Weaver" Tags: "JavaFX - General, JFXtras"
Send by mail Print  Save  Delicious 
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader