Geertjan is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Hello EclipseLink + BeansBinding on the NetBeans Platform

01.19.2009
| 14452 views |
  • submit to reddit
Let's now take the next logical step, folllowing from the previous two parts (part 1, part 2). "And what exactly," you might be wondering, "is the next logical step?" Well, the next logical step is to create a NetBeans Platform application that uses JPA to access a database, while using Beans Binding to synchronize that database with a Swing component so that the database can be viewed as follows:

Above, Beans Binding is used in two different ways. Firstly, it is used to synchronize the JTable with the JPA query. Secondly, Beans Binding is used to synchronize the two JTextFields with the JTable. Thanks to the support in NetBeans IDE for JPA and Beans Binding, we will create the above application without typing a single line of code. In other words, everything will be generated via the various generators provided by NetBeans IDE. More than likely, especially since all these generators entail usage of the dreaded NetBeans blue blocks (which are a pain to work with), you probably don't want to take this approach in production code. However, despite that, the generators are useful in the prototyping phase of your applications, firstly because they show that the above effect can be created at all, and without much trouble (because potentially you've been wondering whether something like this is possible at all), and secondly because you can copy the generated code and use it in your own real life application, i.e., by copying the generated code and then reusing it, you'll not be working with the blue blocks anymore, while still benefiting from the fact that the generated code is correct.

Hence, the blue blocks are not a serious constraint in the approach that will be described here. There is, however, a truly serious objection that should be noted before continuing: the approach taken here does not leverage the true brilliance of the NetBeans Platform. Why? Because we're using a JTable to display the JPA query. It would be far more useful to use one of the NetBeans-specific Swing components instead of a JTable, i.e., one of the NetBeans Platform "explorer views". The NetBeans explorer views are alternative Swing components to the JTable and, as will be shown, are many times more effective than anything the JTable can do for you. However, this aspect will be focused on in a separate part of this sequence of topics. For now, we will assume that the JTable is an effective Swing component and that using it is the correct approach to take.

So, let's get started.

  1. Follow the Steps from the Earlier Article. Start by doing everything outlined in EclipseLink on the NetBeans Platform. You should end up with a NetBeans Platform application consisting of 4 modules: the UI integration module, the JPA entity integration module, the EclipseLink integration module, and the database server integration module.

  2. Remove the Code in the TopComponent Constructor. The UI integration module consists of a TopComponent with a JTextArea that displays the data from the database. The code that makes this possible is found in the TopComponent constructor. Delete that code completely. Also delete the JTextArea itself. In the next steps, instead of the JTextArea, we will drag-and-drop a JTable from the Palette and, in the very next step, we will, instead of the code in the constructor, drag-and-drop some Persistence components from the Palette. Therefore, instead of typing code manually, everything will be generated from the Palette, as pointed out in the introductory paragraphs above.

  3. Drag and Drop the Persistence Components from the Palette. When you look in the Palette (Ctrl-Shift-8), you should find an interesting grouping of Persistence components, highlighted below:

    I only discovered these a day or so ago. All three of the components above are needed in the scenario described in this article. Drag and drop each of them onto the TopComponent. Once you have done this, you will not see anything in the TopComponent. However, open the Inspector (first open the TopComponent in the Design view, then open the Inspector from Window | Navigating | Inspector) and you should see this:

    Good. Now you have the Persistence components available.

    Tip: It is extremely important that the three components are added in the order shown above. In other words, the Entity Manager component needs to be first, the Query component needs to be second, and the Query Result component needs to be third. You can simply drag and drop the three components in the Inspector (i.e., in the screenshot above, just drag the three components into the correct order). Why? Because the order shown above is the order in which the components are initialized, which is extremely important. For example, if the Entity Manager is initialized after the Query, then the Query (which uses the Entity Manager) will return null from the Entity Manager.

  4. Set the Properties of the Persistence Components. Next, in the Inspector shown above, right-click each of the three Persistence components, one by one, and set their properties, as follows:

    • Entity Manager. Set the "persistenceUnit" property to "EntityLibPU". Remember that that is the name of the persistence.xml in the entity classes module.

    • Query. Set the "query" property to "SELECT c FROM Customer C". Set the "entityManager" property to the name of the entity manager, which in this case is "entityManager".

    • Query Result. Set the "query" property to the name of the query, which in this case is "query". In the "Type Parameters" property (in the Code tab of the Properties sheet), set <Customer>.

    To summarize the above instructions graphically, look at the screenshots below:

    Great. You're done. You have now set up the Persistence components via the UI in NetBeans IDE. Also, you have enabled the NetBeans Beans Binding support to recognize these components so that they can be bound (in the upcoming steps in this article) to columns in the JTable that you will create in the next step.

  5. Drag and Drop the JTable and JTextFields from the Palette. Now drag and drop a JTable from the Palette, as well as two Strings and two JTextFields. In the next steps, we will hook these up to the Persistence components. For example, we will bind the "elements" of the JTable to the rows returned by the Query Result that we created in the previous step:

    We will also bind the "text" property of the JTextFields to Beans Binding expressions obtained from the JTable. But, that will all come in the following steps. For now, simply lay out your UI on the TopComponent, as shown above: a JTable, two Strings, and two JTextFields. For now, also don't worry about the column names that you see above. These will be set automatically when we bind the JTable to the Query Result.

  6. Bind the JTable to the Query Result. In the Design mode of the TopComponent, right-click the JTable and then choose Bind | elements. In "Binding Source", choose "list", which is the Query Result you defined earlier:

    Next, right-click the JTable again and choose Table Contents. Now, in the Columns tab, you should be able to map columns in the JTable to columns from the Query Result:

  7. Bind the JTextFields to the JTable. In Design mode, right-click each of the JTextFields in turn and choose Bind | text. Then you can map the JTextField to the JTable and, more specifically, to a particular column in the JTable, using the UI provided by NetBeans IDE:

  8. Deploy the Application. Start the database server and deploy the application. You should now see the following:

    Select a new row in the JTable and then notice that the JTextFields are automatically updated.

You now have a NetBeans Platform application that accesses a database and displays its results in a JTable. The JTable, in turn, is a Master Table, with details being shown in the JTextFields below, which are bound to columns in the JTable. This is a nice further development of our EclipseLink integration with the NetBeans Platform, though now (as pointed out at the start), we should begin leveraging the Swing explorer views, instead of the JTable. The reason why, and the procedure how, will be discussed in the next part. In addition, we will also be adding some important features, such as Save functionality, following NetBeans Platform idioms, which are definitely preferable in this context.

 

AttachmentSize
fig-1-combo.png46.33 KB
fig-2-combo.png8.44 KB
fig-3-combo.png7.5 KB
fig-4-combo.png9.23 KB
fig-5-combo.png10.9 KB
fig-6-combo.png9.78 KB
fig-7-combo.png15.17 KB
fig-8-combo.png17.37 KB
fig-9-combo.png7.22 KB
fig-10-combo.png15.15 KB
fig-11-combo.png9.49 KB
Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Richard Osbaldeston replied on Mon, 2009/01/19 - 6:36pm

Might be foolishly falling into one of your traps here but what about the inherent EDT issues? You appear to be binding JPA domain objects to Swing components and I'd strongly suspect either your doing all the db queries in the EDT (bad practise for any network traffic) or JPA is working on a different thread in which case beansbindings won't provide any EDT thread safety (one of its many failings - yes I am a broken record) and the produced code is buggy & unsafe as it's updating Swing from outside the EDT..?

Will you be supplying the code/project at some stage? I could be wrong.. at the very least these articles should mention the EDT at some point.

Is this an inherent problem with making anything too high level or user friendly is that the developer becomes too abstracted from the basic responsibilities of the underlying code produced.

Geertjan Wielenga replied on Tue, 2009/01/20 - 8:40am

Hi Richard, thanks for the comments. See here for similar concerns about Beans Binding:

http://weblogs.java.net/blog/fabriziogiudici/archive/2008/01/beansbinding_no.html

Also, from the next step in this series onwards, I will not be using Beans Binding at all anymore (its future seems fragile, so I'd rather not rely so heavily on it in this series that will hopefully be useful to someone in real life), so questions relating to Beans Binding should not be relevant anymore.

On the JPA side, which will of course continue to be a fundamental part of this application, I will be monitoring the situation, and evaluating the application as it develops, so that any EDT issues, threading issues, and the like, will be identified and openly discussed in this series. For the moment, I won't be discussing these aspects, but will do so one or two topics from now.

Finally, yes, all the code will be made available, from about two topics onwards. Hope that is sufficient response for the moment.

Wade Chandler replied on Tue, 2009/01/20 - 8:32pm in response to: Geertjan Wielenga

OK, lots of little details here.

Just because Beans Binding doesn't itself offer tie in to the EDT doesn't mean that beans can't be designed to be used that way, fire events on the EDT, or that calling logic must be called from some other thread to set a property. Often in Swing development we have to fire property changes from the EDT to enable valid tie in to the UI.

It isn't a weakness of Beans Binding necessarily as much as a flexibiity in most to many cases. It could have some utilty to allow specific bindings to always do that for us automatically however and that would make it more useful. The Swing bindings to modeled components is a different story. For the modeled components it just needs to be better.

As for NB and binding these things. NB is great for most bindings at the moment. For instance, this binding where you bind the selected element name to the text field. Perfectly OK and will be run on the EDT by the fact the property change occurs on the EDT.

Now, binding non-swing beans presents different challenges, but no more than expected per the way Swing is threaded. One needs to call the property on the EDT to make things correct. However, binding properties outside the EDT is a perfectly valid use case as well to keep different things insync automatically.

The other stuff here could be designed better. Binding in NB of persistent units and those bean wrappers have multiple issues at the moment.

One, the query takes place on the EDT. Something in almost all cases a no no, especially here. To much for the UI. It is all put into initComponents. I don't know who thought that up.

Next, partly the fault of the Beans Binding Swing Bindings, the Swing components already have a good model to be hooked to.  The Beans Bindings for Swing models is what is needed. Instead, forcing List, as is done now, is pretty darn silly, but only in that folks don't really know how to work around complex lazy loadings, and especially when presented short cuts such as the ObservableCollections class. That is a limitation of the binding framework that should be addressed.

Setting a model is good for the EDT, grabbing individual values, etc as well. Updating the model and loading its data behind the scenes off the EDT and then later call table model changed events on the EDT is best for the model; same for some well designed implementations of ObservableList. Real simple things which are not supported really well by bindings at the moment, but the same could be said that there are no good lazy loaded implmenetations of TableModel either, but once one understands how to build them it really is pretty simple.

Those Swing bindings for modeled components expect limited data sets if using the defaults from ObservableCollections, that or use more RAM, and to get some kind of a proxy ObservableList implementation that performs lazy loading is apparently foreign to folks, at least more foreign than a lazy loading a TableModel though I must say it seems many Swing developers, and even old school COM or Borland VCL developers, don't understand this either, so it can be hard for someone to understand how to make Beans Binding work well with Lists and large datasets off and on the EDT as needed.

Maybe I'll get around to writing some good code I can share along with a tutorial which folks can use to update the form module or I can depending on the future of the Beans Binding framework. That or I'll update form myself. The updates would include lazy loading of data and fetching portions of the data sets by users as needed an on the fly. It really takes some good example code for folks to deeply understand all the little issues involved here.The tutorial I'm talking about possibly writing would work well for developers to use to make IDEs better, but would work equally well for folks working on a project without using the IDE fluff in that case.

Learning Java replied on Thu, 2010/06/17 - 6:27am

This worked great for me, but now I have spent many hours just trying to include a WHERE clause in the query. I just want to filter my jTable using a value from my workOrderIDjTextField. I am pretty new to Java, so I am probably making a dumb mistake.

I have tried entering the following in the Query Dialog window...

SELECT w FROM WorkOrderDetailsList w WHERE w.workOrderId = :workOrderId Error: java.lang.IllegalStateException: Query argument workOrderId not found in the list of parameters provided during query execution.

The error seems clear, but I have tried many ways to include my parameter to make this work and searched the lists for an answer, but keep getting errors.

Thanks for any help. This seems like it should be a simple thing to do?

Tom

Carla Brian replied on Sun, 2012/05/06 - 11:15am

 If you run through the static weaver with eclipselink.weaving set to false, do your classes
appear to be weaved.  You should be able to compare the sizes of the class files
before and after the weaving step to get a general idea. - Incredible Discoveries

Cecilio Peral replied on Sun, 2012/09/30 - 4:14am

Hi Geertjan

Thanks for the great job evangelizing Netbeans and Netbeans Platform!

I've tried to follow this tutorial and everything goes well until I'm trying to bind JTable elements with List of results.

I can open the Bind elements wizard but i don't see "Import data to form" button, so Ican't bind the resultset List to the JTable.

It looks like the IDE is not recognizing that this a JTable or some libraries are missing.

I'm working with NetBeans 7.2 over Ubuntu 12.04.

Any help/clue will be really appreciated.

Cecilio

Bryan Low replied on Sun, 2013/02/24 - 4:54am

Bartley Ridge facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Bartley.

Bartley New Launch 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.