 |
Beans Binding Between Separate Forms
Posted by pkeegan on May 21, 2008 at 07:45 PM | Comments (15)
Continuing from my last post, I'll show the next steps in the creation of this simple (but not too simple) client purchase application. This time, our main focus is in creating a separate dialog which we will use for data entry. We'll need to do a few tricks so that input from the dialog is propagated to the main form and then the database.
But first we'll need to clear up a few loose ends. As I alluded to last time, I use AUTO_INCREMENT attributes for the ID columns of the CLIENTS, COUNTRIES, and ORDERS tables. This means that whenever a new row is added to those tables, that row's AUTO_INCREMENT field is given a unique value (the value of the last new record + 1). For me using AUTO_INCREMENT is a handy way to ensure having unique records.
When you generate the skeleton of the application in the New Java Desktop Application wizard, the IDE generates two entity classes (Clients.java and Orders.java) that represent database tables with the same names. However, these entity classes are missing code to deal with the AUTO_INCREMENT fields. Without that code, you will get errors when trying to enter new records. To fix that:
- Open the Clients.java class.
- Navigate to the line after the one containing
@Id.
- Enter the line
@GeneratedValue(strategy=GenerationType.IDENTITY).
- Press Ctrl-Shift-I to generate the necessary import statements for this annotation.
- Repeat the process for Orders.java.
Note: You can also use code completion here. It takes three selections to get the entire line, but the import statements are generated for free.
Once you have added these annotations, you can run the application and start adding data. Click the top New button to add a client. With a client selected, click the bottom New button to add an order for that client. Click Save to push your changes to the database. Click Refresh to back out any unsaved changes.
I like tables for browsing data, but I think they leave something to be desired for data entry. So for this application, we'll add dialogs for data entry.
To create and populate the JDialog, follow these steps:
- Right-click the package that contains your classes and choose New | Other. Select Swing GUI Forms | JDialog Form template and name it
EditClient.
- From the Palette window drag, drop, and arrange components for the customer's personal details.
You should have JLabels for each of the following fields: first name, last name, address, city, state, zip code, country, and phone number. You should have JTextFields for each of those fields, except for country, for which we will use a JComboBox.
- Edit the display text for JLabels.
- Add two buttons and name them Save and Cancel.
- (Optional) Rename all of the components you have added to more memorable names, such as
firstNameLabel. You can do this inline in the Inspector window.
The resulting layout should look something like what you see below.
Now we need to bind the various fields to the corresponding columns in the table. We can't bind directly to components from other forms in the Bind dialog box, so we'll have to create an intermediary property of type Clients to hold the record. When the user presses New, the property will be given the value of the currently selected record.
We can quickly generate the bean property with the IDE's bean support:
- At the top of the design area of the EditClient form, click the Source tab. Click somewhere within the class, such as above the variable declaration block.
- Press Alt-Insert (or right-click and choose Insert Code) and choose Add Property.
- In the Add Property dialog, name the property
currentRecord, give it the type Clients, select Generate Getter and Setter, and select Generate Property Change Support.
- Click OK to generate the property.
We now need to customize the generated setCurrentRecord method. Replace the body of the method with these three lines:
Clients oldRecord = this.currentRecord;
this.currentRecord = currentRecord;
propertyChangeSupport.firePropertyChange("currentRecord", oldRecord, currentRecord);
Now we need to add code to the New action to open the dialog and clear the currentRecord property when a user wants to add a new record:
JFrame mainFrame = ClientAndPurchaseApp.getApplication().getMainFrame();
EditClient ec = new EditClient(mainFrame, false);
ec.setCurrentRecord(c);
ec.setVisible(true);
For now, we won't code the Save and Cancel buttons on the dialog (we've had enough digressions!). I'll cover that in an upcoming post.
With those preliminaries out of the way, we can proceed with the binding of the text fields. We'll be binding the text property of each text field to the corresponding property of the Clients object represented by currentRecord.
To bind a dialog text field to the appropriate property of currentRecord:
- Right-click a text field and Choose Bind | text.
- In the Bind dialog box, select Form as the Binding Source (note that Form is at the very bottom of the drop-down list).
- In the Binding Expression drop-down list, expand the
currentRecord node and select the property corresponding to the text field that you are binding.
- Click OK to close the Bind dialog box.
Do this procedure for each of the text fields in the dialog. For now, don't bind the JComboBox to anything. We'll need to do some other preparation to get that to work properly. I'll cover that in my next post.
Now you should be able to run the application, press the first New button, and enter data in the dialog. The Save and Cancel buttons on the dialog don't do anything yet, but we can save the records from the main frame. In the next post, we'll clear up some of these loose ends so that the application behaves more like applications that we are used to.
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
hi, there is an error in the tutorial, the editClient its not a jframe , its a jDialog. good job.
Posted by: ics on May 22, 2008 at 12:36 AM
-
Patrick, I am new to Netbeans 6.1 and Java; following through your tutorial on Binding Between Separate Forms, I encounter the following error - all the lines import javax.persistence.
report package doesn't exist.
In Libraries for the Project, I notice Glassfish is not included, is this significant? Would appreciate your help.
John
Posted by: jdross on May 29, 2008 at 06:56 AM
-
Hi Patrick, re my earlier comment, I am referring to the tutorial Input on a New Desktop Java Database Tutorial not the Binding Between Separate Forms.
Posted by: jdross on May 29, 2008 at 07:01 AM
-
Patrick, sourced the problem "package doesn't exist" to the following missing libraries:
toplink-essentials
toplink-essentials-agent
mysql-connector-java-5.1.5-bin.jar
These somehow didn't come in with the wizard creating the code for the application.
Once I added the above libraries manually, everything worked as expected.
Good work on the project
Posted by: jdross on May 29, 2008 at 08:39 AM
-
Patrick, can you explain the reference to c in ?
ec.setCurrentRecord(c);
as it's not clear to me where the variable is declared
Posted by: jdross on June 02, 2008 at 06:48 AM
-
Hi jdross, regarding the missing libs, did you start with the Java Desktop Application project template (from the previous blog entry)?
Regarding, the c, c is an instance variable for the new record. It is declared in the first line of the newRecord() method:
clientpurchaseapp.Clients c = new clientpurchaseapp.Clients();
Posted by: pkeegan on June 02, 2008 at 08:03 AM
-
Patrick, thanks for that response. As I mentioned I'm new to Java. Finding your tutorial very helpful. Can't say what happened, you're probably right about missing the Java Desktop Application project template as I was skipping the database setup you are using and was using one of my own.
Thanks for the line on the c variable. Just figured it out.
Have one more question if I may? I appreciate your patience, but I can't seem to get the EditClient form to synchronise with the main form.
Am I misunderstanding something here in the tutorial:
"We now need to customize the generated setCustomerRecord method. Replace the body of the method with these three lines:"
Regards and thanks
Posted by: jdross on June 02, 2008 at 09:40 AM
-
How does it fail? What happens? BTW, have you continued through the end of this series of tutorials? The actual synchronization of the dialog and the form don't happen until the last blog in this series
Posted by: pkeegan on June 02, 2008 at 10:10 AM
-
Patrick, In your tutorial "Binding JComboBox's Elements and Selected Item" you mention
Enter values into the various text fields and choose a country from the combo box.
Notice that the values that you enter in the dialog box also appear in the top table in the main form , including the country you selected from the combo box.
I don't see what I enter in the Editclient form echoed in the main form, but I'll work through to number four and let you know.
I'm not sure where to place :
Clients oldRecord = this.currentRecord;
this.currentRecord = currentRecord;
propertyChangeSupport.firePropertyChange("currentRecord", oldRecord, currentRecord);
Now we need to add code to the New action (?)to open the dialog and clear the currentRecord property when a user wants to add a new record:
JFrame mainFrame = ClientAndPurchaseApp.getApplication().getMainFrame();
EditClient ec = new EditClient(mainFrame, false);
ec.setCurrentRecord(c);
ec.setVisible(true);
Posted by: jdross on June 02, 2008 at 11:35 AM
-
Hello Patrick, I think you have a wrong method name under "Add Property" screenshot - "setCustomerRecord" should be "setCurrentRecord". Thanks for the tutorial.
Posted by: janhalasa on June 03, 2008 at 03:14 AM
-
Oops, I refer to setCustomerRecord, but I really mean setCurrentRecord. So put it in the line after
public void setCurrentRecord(Clients currentRecord) {
I'll fix this now.
Posted by: pkeegan on June 03, 2008 at 03:17 AM
-
Patrick, thanks for the tutorial, which I've just completed. Everything worked as you said in the end. I figured out you meant:
Navigate to the newRecord() method in the Clients class and add the following code to the bottom of the method:
for "Now we need to add code to the New action"
Overall, the exercise was great. I am wondering if you could do a tutorial on sorting and filtering on the Main form? Thanks once again.
Posted by: jdross on June 03, 2008 at 04:14 AM
-
Hi Patrick, I was following the thru' your tutorial, and I've generated the bean property using Netbeans 6.1, and I've copy and pasted the codes for the setCurrentRecord method in the EditClient.java. But Netbean high-lighted an error saying that "cannot find symbol variable propertyChangeSupport". I tried Ctrl-Shift-I to fix imports, but to no avail. What could be the cause? Thank you very much in advance for your kind assistance.
Posted by: nchin on June 18, 2008 at 09:51 AM
-
Oops, I found the problem, it was my mistake for not selecting the "Generate Property Change Support". Sorry.
Posted by: nchin on June 18, 2008 at 10:23 AM
-
Hello Keegan, when i add @GeneratedValue(strategy=GenerationType.IDENTITY) I get an error:
SEVERE: Application class keegan.KeeganApp failed to launch
javax.persistence.PersistenceException: Exception [TOPLINK-7144] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: SEQ_GEN_SEQUENCE: platform DatabasePlatform doesn't support NativeSequence.
I'm using H2 Engine database.
Posted by: lstr on June 18, 2008 at 10:13 PM
|