Tuesday, April 30, 2013

Upload and download images via JAX-RS

As students have been asking me how they can perform image uploads and downloads in their modern (HTML5 front-end + RESTful back-end) web applications, I've written an example application that shows how this can be done using JAX-RS.


Source code


Setup

  • Download the source code and open the NetBeans project contained within.
  • Edit the class MessageService as follows:
    • Change the constant BASE_DIR to point to an existing directory on your server (or localhost) where you want to store the images.
    • Change the constant MAX_SIZE_IN_MB to the maximum allowed size you want to use. You will not be able to upload or download images larger than this size.
  • Deploy the application to GlassFish.
  • Drop some images (with extension .jpg or .png and not larger than the maximum allowed size) into the BASE_DIR folder you configured or use upload.html to upload some images (see below).


Using the webservice

The webservice uses the following URLs:
  • http://localhost:8080/fileserver/resources/images
    • GET this URL to get a list of available images (filenames wrapped in a JSON array).
    • POST to this URL to upload an image. The server will store this image and pick a random filename for it.
  • http://localhost:8080/fileserver/resources/images/{filename}
    • GET this URL to download the image with the given filename.
If you change any of these, make sure you update the BASE_URL variables in upload.js and download.js as well.


Using the front-end

The front-end consists of the following pages:
  • http://localhost:8080/fileserver/upload.html
    • Use this page to upload an image via an HTML form.
  • http://localhost:8080/fileserver/download.html
    • Use this page to get a list of available images and to download them.

If you have any questions or find a bug, feel free to send me an email, or leave a comment!

Friday, April 12, 2013

(Preview) Reminders: the RESTful web version with HTML5 and JAX-RS

Because I'll be teaching mostly web applications for the remainder of the semester, I decided to rewrite my JavaFX + JPA example 'Reminders' as a web application.

I have used a clean separation of back-end (RESTful web services) and front-end (responsive web application). On the back-end, Java EE (JAX-RS, EJB, JPA) takes care of all the business logic and persistence. The front-end is built using HTML5, jQuery and Twitter Bootstrap.

Some notes:
  • This preview version does not yet support user accounts, authentication or authorisation, but that's #1 on my to-do list.
  • I only used Safari (OS X) and Mobile Safari (iOS 6) for testing.
  • The date and time picker isn't very responsive. On mobile devices, manually enter the date in the text field. It should work just fine.

Have fun playing around with this, and let me know if something isn't working for you!


Screenshots:




How to use this application:

First, you need to set up the database. There's two ways to do this:
  1. In NetBeans, go to the Services window. Under Databases, right-click Java DB and create a new database with the following settings:
    • Name: Reminders
    • Username: APP
    • Password: APP
  2. Or create your own empty database and edit glassfish-resources.xml and  persistence.xml to use this database.
Second, edit script.js. On the first line, replace the contents of BASE_URL with the URL where your web services will be hosted. Even if you're running it on localhost, it's best to replace localhost with your IP address, so you can test with multiple devices.

Then, simply deploy and run the application. The database schema will be created upon first use. Once this is done, you can edit persistence.xml to set the table generation strategy to none.


Source code:

Saturday, January 26, 2013

Reminders: a JavaFX and JPA demo application

This time around, I wrote a somewhat more serious demo application, called 'Reminders' (guess what it does). It's cool in oh so many ways:

  • JPA is used for persistence, together with bean validation to check constraints before persisting an entity.
  • FontAwesome is used for its cool icons. They look great and because they are text, you can easily change their size or color.
  • Advanced (from my perspective at least) CSS is used to completely change the look and feel of ListView and Button nodes.
  • It has neat dialog windows. The code for these should be pretty reusable.
  • It includes a 'location picker' written in JavaScript, but seamlessly incorporated into JavaFX thanks to the WebView.
  • It uses JFXtras for its CalendarTextField, which, truth be told, works great but looks hella-ugly.

Screenshots:






How to use this application:

First, you need to set up the database. There's two ways to do this:
  1. In NetBeans, go to the Services window. Under Databases, right-click Java DB and create a new database with the following settings:
    • Name: Reminders
    • Username: APP
    • Password: APP
  2. Or create your own empty database and edit persistence.xml to use this database. Make sure you add the correct JDBC driver to the project.
Then, simply run the application. The database schema will be created upon first use. Once this is done, you can edit persistence.xml to set the table generation strategy to none.

The required libraries are found in the lib folder. You will also need EclipseLink and the Java DB Driver (if you chose option 1), but NetBeans already has those bundled with it.

Source code:


I hope you have fun with this. Let me know if something isn't working for you, or if you can't figure out the source code. As always, you can find me at myfirstname dot mylastname at icloud dot com (I already have plenty of spam, thanks).

Wednesday, December 5, 2012

Teaching JavaFX, Part 2

In the second (and final) part of our workshop, we built the following example:


You can find the documented source code (FX_Ogly) here:
https://docs.google.com/folder/d/0B-q-VDW3dbtyQ3RMbkd3cjhacVU/edit

This example covered using MVC with FXML and Scene Builder, using controls and layout panes, using properties and binding and styling nodes with CSS. It also includes a bit of math, for your pleasure (everyone likes math, right ?).

I hope students enjoyed this introduction to JavaFX and will find some time to play around with it. Many advocates say JavaFX makes programming fun again, and I couldn't agree more.

Monday, December 3, 2012

Teaching JavaFX, Part 1

I just finished teaching my first hands-on JavaFX workshop.
We covered (or at least introduced) adding nodes to the scenegraph, handling events, creating animations and using the Builder pattern.

You can find the resulting application (FX_Guybrush), with documented source code here:
https://docs.google.com/folder/d/0B-q-VDW3dbtyQ3RMbkd3cjhacVU/edit



I hope students liked it !

Up next: properties and binding, MVC with Scene Builder and FXML, controls, layout panes and styling with CSS.

Thursday, November 29, 2012

Understanding the Decorator pattern

For those of you who struggle with design patterns, I hope the following steps can help you understand the Decorator pattern and why it can be useful.


Step 1: Understand its purpose

The Decorator pattern is all about extending a class, without actually extending (inheriting from) it. If you still wonder why inheritance isn't always your best choice to add functionality to a class, read the following points:
  • With inheritance, you add functionality to just one class: the one you inherit from. If you want to add the same functionality to more than one class, then inheritance is not the way to go.
  • Inheritance is static. If you want to dynamically add functionality to objects at runtime, then inheritance is not the way to go.
  • If you inherit from a class, you are dependent on the implementation of your superclass. It's not too hard for changes in a superclass to break a subclass.
If none of these points pose a problem for your particular application, then inheritance might just be the right tool for the job. Otherwise, do read on.

Step 2: Start with the basics

So how do you extend a class without inheriting from it ? Well, it's easy: just create a new class and give that class an attribute of the old class. This new class can add whatever functionality it wants to and use the methods of the old class when it needs to.

A basic design might be as follows:


Here, class MyDecorator has an attribute of type MyClass. The implementation of MyDecorator might be as follows:

public class MyDecorator {

  private MyClass myClass;

  public MyDecorator(MyClass myClass) {
    this.myClass = myClass;
  }

  public void doSomething() {
    // add some functionality
    // ...

    // delegate something to myClass
    myClass.doSomething();

    // add some more functionality
    // ...
  }
}

This basic design allows you to dynamically extend the functionality of an object of type MyClass by wrapping it with an object of type MyDecorator when needed. In this basic design, composition and delegation have replaced inheritance.


Step 3: Add some polymorphism

The design in step 2 got rid of inheritance but still lacks some of the benefits of a full Decorator pattern. For example: we're still not able to add the same functionality to more than one class. To achieve this, we modify our design as follows:


We introduce an interface MyInterface and give MyDecorator an attribute of this type, instead of a concrete subtype. Now the functionality of MyDecorator can be added to every class that implements MyInterface.

Step 4: Take it all the way

Even though we already achieved the desired results in step 3, the Decorator pattern has one more trick up its sleeve. That trick is to make your decorator classes and the classes they decorate have a common supertype. In our example, we simply make MyDecorator implement MyInterface as well: 


This technique has two major benefits:
  1. Because decorators and regular classes have the same supertype, you can use a decorated object wherever you'd use an undecorated one.
  2. Because decorators and regular classes have the same supertype, the objects that get decorated, can be decorated objects themselves. As a result, you can chain decorators together and decorate an object with as many decorators as you like.
Tada !

I hope you learned something from all this, and will remember it whenever you start using inheritance for something it's not suited for. Just please don't start replacing every inheritance hierarchy with a chain of decorators. If you do, you might just be suffering from pattern fever.

For more information, I can recommend the following reads:
  • Head First Design Patterns (Freeman & Freeman), Chapter 3
  • Effective Java, 2nd ed. (Bloch), Item 16

Tuesday, November 27, 2012

Enter Jumpman

I am happy to announce the first playable version of Jumpman ! Get it here and try it out:
https://docs.google.com/folder/d/0B-q-VDW3dbtyQ3RMbkd3cjhacVU/edit

The native bundles come with their own JRE, no need to install or update Java.

Please note the following:

  • I wrote this game to learn about JavaFX and casual game programming.
  • The intended goal of this game is to teach casual game programming in an object-oriented fashion using JavaFX.
  • This is not supposed to be the next Angry Birds, so don't request feature X, Y or Z.

The source code is provided as-is and is currently undocumented. You are free to use this code however you like, as long as you give credit where credit is due.

The roadmap for Jumpman includes the following:

  • Provide a graphical level designer.
  • Replace the artwork with something that will not get me sued. Art students are welcome to participate in developing artwork and setting a theme for the final game.
  • Allow levels and highscores to be submitted online.
  • See if we can get the final game published on the Mac App store.
  • Hope Oracle will support JavaFX on iOS and Android.

A series of blog post explaining some of the parts of the game will follow once the game is near completion. Other features than the ones listed above will probably not be added, in favor of spending more time making accessible learning examples.

Have fun playing around with this, and let me know if you think you've found a bug !
You can reach me at firstname dot lastname at icloud dot com.