Testwww - Creating A Custom Java Desktop Database Application - NetBeans 6.5 Tutorial
Testwww - Creating A Custom Java Desktop Database Application - NetBeans 6.5 Tutorial
This tutorial guides you through the creation of a complete desktop database application that enables its user to browse and
edit customer records and purchase history. The resulting application includes the following main features:
A main view that enables users to browse customer records and customer purchases.
Separate dialog boxes for entering new records or modifying existing records.
Contents
Introduction
Setting Up the Database
Creating the Application Skeleton
Customizing the Master/Detail View
Adding Dialog Boxes
Activating the Save and Cancel Buttons in the Dialog Boxes
Currency Rendering, Date Verifying, and Search
See Also
To complete this tutorial, you need the following software and resources.
Introduction
This application takes advantage of the following technologies:
The Java Persistence API (JPA), which helps you interact with a database using Java code.
Beans Binding, which enables you to keep Swing component properties synchronized.
The Swing Application Framework, which simplifies basic application functions such as persisting session information,
handling actions, and managing resources.
The tutorial makes use of IDE wizards and other code generation features to provide much of the boilerplate code. It also
shows you how to customize the generated code and hand code other parts of the application.
This tutorial takes approximately 2 hours to complete. For a shorter tutorial that shows the creation of a less customized user
interface, see Building a Java Desktop Database Application.
Below is a screenshot of the working application that you will have when you complete the tutorial.
Setting Up the Database
Before creating any application code, you need to set up the database. You can then take advantage of wizards that generate
much of the application code based on the structure of the database.
The instructions in this tutorial are based using a MySQL database that you create with this SQL script.
Note: You can use other database management software, but doing so might require making some adjustments to the
SQL script. In addition, you will need to create the database from outside of the IDE.
To set up the IDE to work with MySQL databases, see the Connecting to a MySQL Database page.
1. In the Services window, right-click the MySQL Server node and choose Start.
6. If the Advanced tab of the dialog box opens, click OK to close the dialog box.
-->
7. Scroll down to the node for connection that you have just created. The node should have the icon.
8. Right-click the connection node and choose Execute Command.
9. Copy the contents of the MyBusinessRecords SQL script and paste them into the SQL Command 1 tab of the Source
Editor.
10. Click the Run SQL button ( )in the toolbar of the Source Editor to run the script.
Output of the script should appear in the Output window.
The database structure was designed with normalization and referential integrity in mind. Here are some notes on the
structure:
The SQL script specifies the InnoDB storage engine in order to handle the foreign keys in this database. MySQL's
default storage engine, MyISAM, will not work with this tutorial.
The data is split among several tables to reduce duplication and the possibility for inconsistencies. Some tables are
connected to each other through foreign keys.
All of the tables use MySQL's AUTO_INCREMENT attribute so that there is a unique identifier for each row in those
tables. This identifier is created by the database management software, so your application and/or your application's
user do not have to create this identifier. (So that the AUTO_INCREMENT is used correctly within the application, the
IDE adds the @ G e n e r a t e d V a l u e ( st r a t e g y = G en e r a t i o n T y pe . I D E N T I T Y annotation for that column in the table's
entity class. This ensures that the application does not try to submit a value for that column when you create a new
record.)
The foreign key in the ORDERS table is there to link each order record with a customer. In the application's user
interface, ORDER records are only displayed for the selected CUSTOMER.
The ON CASCADE DELETE attribute for the foreign key to the CUSTOMERS class ensures that a customer's orders are
also deleted when a customer is deleted.
The foreign key in the CUSTOMERS table points to a COUNTRIES table. You will use this relationship in the application
to enable the user to select a customer's country from a combo box.
The ORDERS table has a foreign key to the PRODUCTS table. When adding a new order record, the user will be able to
choose a product from a combo box.
The COUNTRIES and PRODUCTS tables are pre-populated with data so that you can choose from those tables when the
user of the application is adding customer and order records.
Though this tutorial does not cover it, you might find it useful to create separate applications to populate the
COUNTRIES and PRODUCTS tables. Such applications could be created with the Java Desktop Application project
template and would not require additional hand-coding.
A main application frame that contains tables for customer details and customer orders.
A main application class that handles basic application life-cycle functions, including persisting of window state between
sessions and resource injection.
For some database structures, you can get a working application as soon as you exit the wizard. However, in this tutorial you
will use some constructs for which you need to customize the generated code, such as AUTO-INCREMENT and one-to-many
relationships.
3. In the Name and Location page of the wizard, follow these steps:
1. Type C u s t o m e r R e c o r d s in the Project Name field.
2. Select the Database Application shell.
3. Click Next.
Move the ID entry from the Columns to Include column to Available Columns.
Click Next.
5. In the Detail Options page, follow these steps:
Click the Table radio button to create a JTable for the ORDERS table.
Move the ID entry from the Columns to Include column to Available Columns.
6. Click Finish to exit the wizard.
The Customers and Orders entity classes, which represent the data from the CUSTOMERS AND ORDERS database
tables.
The main form with two JTable components that provide a master/detail view of the CUSTOMERS and ORDERS
database tables. The view also contains buttons which are connected to actions for creating, deleting, and saving
records.
The master table is bound to a list of Customers objects. That list of objects represents all of the rows of the
CUSTOMERS database table.
The detail table is bound to a collection of Orders objects. That collection represents all of the rows of the ORDERS
database table that are linked with the currently selected customer in the master table.
At this point you can choose Run > Run Main Project to see the main application window. However, the application does not
yet function properly, because the database has some attributes for which the wizard did not generate necessary code. You will
add this code in the next section of the tutorial.
1. In the Projects window, select the project's node and choose Properties.
2. In the Project Properties dialog box, select the Application node.
4. If desired, modify the other properties as well, such as Description, and Splash Screen.
Customize the Customers entity class to refer to the Countries entity class.
Customize the Orders entity class to refer to the Products entity class.
Update the binding code for the master and detail tables in the main form so that the Countries and Products entity
classes are used.
1. Create entity classes for the Countries and Products tables by right-clicking the c u s t o m e r r e c o r d s package and choosing
New > Entity Classes from Database.
2. Select the countries table and click the Add button.
4. Click Next.
To establish the relation between the Customers and Countries entity classes:
4. In the setCountry I d ( ) method, change the types of c o u n t r y I d and o l d C o u n t r y I d from Integer to Countries.
To establish the relation between the Orders and Products entity classes:
@Basic(opt i o n a l = f a l s e )
@Column(na m e = " P R O D U C T _ I D " )
private in t p r o d u c t I d ;
5. In the setProduct I d ( ) method, change the types of the p r o d u c t I d parameter and the o l d P r o d u c t I d variable from
int to Products.
2. In the Design view of the class, right-click the top table and choose Table Contents.
6. Change the Title from Country Id to Country . This affects the column heading in the running application.
In the Products table, there is a productId column, which is based on the PRODUCT_ID column from the ORDERS table. You
could just modify the binding to show the product model and avoid a C l a s s C a s t E x c e p t i o n . However, it would be useful to
show the data corresponding with the product in additional columns.
1. In the Design view of the CustomerRecordsView class, right-click the bottom table and choose Table Contents.
4. Change the Expression to $ { p r o d uc t I d . b r a n d} . After you do so, the type should also change to String.
7. Select the row that has just been added to the table.
9. For Expression, select productId > prodType from the drop-down list.
10. Click the Insert button again and select the newly added row.
12. For Expression, select productId > model from the drop-down list.
13. Click the Insert button again and select the newly added row.
15. For Expression, select productId > price from the drop-down list.
At this point, the application is partially functional. You can run the application and add, edit, delete, and save records.
However, you can not yet properly modify the fields that are based on the Countries and Products entity classes. In addition,
you have some work to make the Order Date field behave in a more user-friendly way.
You could make some adjustments to the Country and Model columns to use combo boxes that are bound to their respective
tables. That would enable the user to select those fields without having to hand enter them. Instead, you will use dialog boxes
as data entry mechanisms for these tables to make it harder for the user to accidentally delete data while browsing it.
Create dialog boxes to edit data for each of the tables on the main form.
Create intermediary beans to carry the data between the dialogs and form.
1. Unpack the zip of file of utility classes and unzip its contents on your system.
2. On your system, copy all of the files from the zip file and paste them into the folder that contains the project's
c u st o m e rr e c o r d s folder.
3. If your classes are in a different package than c u s t o m e r r e c c o r d s , adjust the package statement in each of the files
you have just added to the project.
5. Click OK.
9. Click OK.
1. Right-click the package that contains your classes and choose New > Other. Select Swing GUI Forms > JDialog Form
template and name it C u s t o m e r E d i t o r .
2. From the Palette window drag, drop, and arrange components for the customer's personal details.
Add labels for each of the following fields: first name, last name, address, city, state, zip code, country, and phone
number.
Add text fields for all of the above fields, except for Country.
For Country, add a combo box.
5. (Optional) Rename all of the components you have added to more memorable names, such as f i r s t N a meLab el . You
can do this inline in the Inspector window.
The resulting layout should look something like what you see below.
Note: For a detailed guide to using the GUI Editor's layout features, see Designing a Swing GUI in NetBeans IDE.
1. At the top of the design area of the CustomerEditor form, click the Source tab. Click somewhere within the class, such
as in the line below the constructor.
2. Press Alt-Insert (or right-click and choose Insert Code) and choose Add Property.
3. In the Add Property dialog, name the property c u r r e n t R e c o r d , give it the type C u s t o m e r s , select Generate Getter and
Setter, and select Generate Property Change Support.
You now need to customize the generated s e t C u r r e n t R e c o r d method to fire a property change notification.
Custom e r s o l d R e c o r d = t h i s . c ur r e n t R e c o r d ;
this.c u r r e n t R e c o r d = c u r r e n t Re c o r d ;
proper t y C h a n g e S u p p o r t . f i r e P r op e r t y C h a n g e ( " c u r r e n t R e c o r d " , o l d R e c o r d , c u r r e n tRecord);
Now you need to add code to open the Customer Editor dialog box when the user clicks the New Customer button. In addition,
you need code to clear the c u r r e n t R e c o r d property.
JFrame m a i n F r a m e = C u s t o m e r R ec o r d s A p p . g e t A p p l i c a t i o n ( ) . g e t M a i n F r a m e ( ) ;
Custom e r E d i t o r c e = n e w C u s t om e r E d i t o r ( m a i n F r a m e , f a l s e ) ;
ce.set C u r r e n t R e c o r d ( c ) ;
ce.set V i s i b l e ( t r u e ) ;
You can now proceed with the binding of the dialog box's fields. You will bind the t e x t property of each text field to the
corresponding property of the C u s t o m e r s object represented by c u r r e n t R e c o r d . Similarly, you will bind the combo box's
s e l e c te d I t e m property to the c ou n t r y I d property of c u r r e n t R e c o r d . You will bind the combo box's e l e m e n t s property to a
list of Countries entities.
5. In the Bind dialog box, select Form as the Binding Source. (Note that Form is at the very bottom of the drop-down
list.)
6. In the Binding Expression drop-down list, expand the c u r r e n t R e c o r d node and select the property corresponding to
the text field that you are binding.
2. Click Import Data to Form, select the database connection, and select the Countries table. c o u n t r i e s L i s t should
appear as the binding source. Click OK.
3. Right-click the combo box again and choose Bind > selectedItem.
4. Select Form as the binding source and currentRecord > countryId as the expression. Click OK.
The combo box is almost ready to work properly in the dialog. It is set up to draw its values from the COUNTRIES database
table, and the item that the user selects is then applied to the country field in the current record. However, you still need to
customize the rendering of the combo box, since the values bound to the combo box are Countries objects, not simple names.
You will do that by specifying a custom cell renderer. (For JTables and JLists, the beans binding library enables you to specify
display expressions, thus avoiding the need to create a custom renderer. However, that feature does not exist yet for combo
boxes.)
1. In the Project's window, right-click CountryListCellRenderer and choose Compile File. Compiling the file enables you to
treat it as a bean that you can add to the form by dragging and dropping from within the IDE's GUI builder.
2. Select the CustomerEditor form in the Source Editor and select the Design view.
3. Drag the class from the Projects window to the white space surrounding the form, as shown in the screenshot below.
Doing so adds the renderer to your form as a bean, much like dragging a component from the Palette adds that
component to your form.
4. In the form, select the combo box.
6. Scroll to the rende r e r property and choose c ou n t r y L i s t C el l R e n d e r e r 1 from the drop-down list for that property.
Now you should be able to run the application, press the first New button, and enter data in the dialog. You should also be
able to select a country from the Country combo box. The Save and Cancel buttons on the dialog do not do anything yet, but
you can save the records from the main frame. You will code those buttons later.
A label to display the date format that needs to be entered. Give this label the text ( M M M D D , Y Y YY - e.g.
A p r 1 7, 20 0 8 ) . If you plan to use a different date format, add text that corresponds to the format that you
plan to use.
Now that the Order Editor has its visual design, you need to do the following things:
Create an intermediary bean to carry the record values back to the main form.
Connecting the Order Editor Dialog Box With the Main Form
As you did for the CustomerEditor dialog box, you will have to create an intermediary bean property of type Orders to hold
the record. When the user presses Enter Order, the property will be given the value of the currently selected order record.
1. At the top of the design area of the OrderEditor form, click the Source tab.
2. Click somewhere within the class, such as in the line below the constructor.
3. Press Alt-Insert (or right-click and choose Insert Code) and choose Add Property.
4. In the Add Property dialog, name the property c u r r e n t O r d e r R e c o r d , give it the type O r d e r s , select Generate Getter
and Setter, and select Generate Property Change Support.
Orders o l d R e c o r d = t h i s . c u r r en t O r d e r R e c o r d ;
this.c u r r e n t O r d e r R e c o r d = c u rr e n t O r d e r R e c o r d ;
proper t y C h a n g e S u p p o r t . f i r e P r op e r t y C h a n g e ( " c u r r e n t O r d e r R e c o r d " , o l d R e c o r d , c urrentOrderRecord);
Now you need to add code to open the Order Editor dialog box when the user clicks the Enter Order button. In addition, you
need code to clear the currentOrderRecord property.
JFrame m a i n F r a m e = C u s t o m e r R ec o r d s A p p . g e t A p p l i c a t i o n ( ) . g e t M a i n F r a m e ( ) ;
OrderE d i t o r o e = n e w O r d e r E d it o r ( m a i n F r a m e , f a l s e ) ;
oe.set C u r r e n t O r d e r R e c o r d ( o ) ;
oe.set V i s i b l e ( t r u e ) ;
4. Select the v a l u e property and click the ellipsis (...) button that is next to the property.
5. In the Bind dialog box, select Form as the binding source, and select currentOrderRecord > orderDate as the binding
expression.
6. Select the combo box for the product and click the ellipsis (...) button for the e l e m e n t s property.
10. Click the ellipsis (...) button for the combo box's s e l e c t e d I t e m property.
11. Select Form as the binding source, and select currentOrderRecord > productId as the binding expression.
14. Select Form as the binding source, and select currentOrderRecord > quantity as the binding expression.
15. Select the price's formatted field.
17. Select Form as the binding source, and select $ { c ur r e n t O r d e r R e c o r d . p r o d u c t I d . p r i c e } as the binding expression.
4. In the formatterFactory property editor, select d a t e in the Category column. Then select D e f a u l t in the Format
column.
5. Click OK to exit the dialog box.
8. In the formatterFactory property editor, select c u r r e n c y in the Category column. Then select D e f a u l t in the Format
column.
Now when you run the application and select an item, the price and currency fields should display as currencies.
Likewise, you should change the default value for quantity, since 0 is an invalid value. You could create a validator here, but
for now it is simpler and more practical to simply set a reasonable default value.
To pre-populate the date and quantity fields in the Order Editor dialog box:
o.setOrder D a t e ( n e w j a v a . u t i l . D a t e( ) ) ;
o.setQuant i t y ( 1 ) ;
Now when you run the application, the current date should appear in the Date field when you open the dialog box and the
default quantity should be 1.
You will set this property's value in event handling code for the buttons.
6. Within the saveCus t o m e r method in the Source Editor (where the cursor jumps after you create the new handler), type
the following code:
s etCustomerCon f i r m e d ( t r u e ) ;
s etVisible(fal s e ) ;
7. Repeat steps 2-5 for the Cancel button and call its handler c a n c e l C u s t o m e r .
s etCustomerCon f i r m e d ( f a l s e ) ;
s etVisible(fal s e ) ;
In the CustomerRecordsView class, navigate to the n e w R e c o r d ( ) method and add the following code to the bottom of the
method:
i f ( c e . isCus t o m e r Co n f i r m e d ( ) ) {
s a v e().r u n ( ) ;
} else {
r e f resh( ) . r u n () ;
}
Since the s a v e() and ref r e s h ( ) actions act on any changes made during the application's session, you should make the
dialog modal and make the tables in the main form uneditable. Another reason to make the dialog modal is so that when the
user presses either the Save or Cancel button, the s e t V i s i b l e ( ) method does not return until the event handler (which
includes the setCustomer C o n f i r m e d method) has run.
3. In the Properties window, click Properties and select the checkbox for the m o d a l property.
5. Click Close.
You should now be able to create new records and save them from the Customer Editor. You should also be able to create a
new record and cancel from the Customer Editor.
In the RefreshTask inner class, T hr e a d . s l e e p is called four times to slow down the rollback code to better demonstrate how
Swing Application Framework tasks work. You do not need this code for this application, so delete those four statements.
Similarly, you do not need a try/catch block here, so delete the t r y and c a t c h statements as well (but leave the rest of the
body of the t r y block).
You will set this property's value in event handling code for the buttons.
6. Within the saveOrd e r method in the Source Editor (where the cursor jumps after you create the new handler), type
the following code:
s etOrderConfir m e d ( t r u e ) ;
s etVisible(fal s e ) ;
7. Repeat steps 2-5 for the Cancel button and call its handler c a n c e l O r d e r .
s etOrderConfir m e d ( f a l s e ) ;
s etVisible(fal s e ) ;
In the CustomerRecordsView class, navigate to the n e w D e t a i l R e c o r d ( ) method and add the following code to the bottom of
the method:
i f ( o e . isOrd e r C o n fi r m e d ( ) ) {
s a v e().r u n ( ) ;
} else {
r e f resh( ) . r u n () ;
}
1. Open the CustomerRecordsView class in the Source Editor and select the Design view.
2. Right-click the bottom table and choose Table Contents.
5. Click Close.
4. Delete the deleteD e t a i l R e c o r d ( ) method and replace it with the new version of the method:
@Action(en a b l e d P r o p e r t y = " d e t a i lR e c o r d S e l e c t e d " )
public voi d d e l e t e D e t a i l R e c o r d ( ) {
Object [ ] o p t i o n s = { " O K " , " C an c e l " } ;
int n = J O p t i o n P a n e . s h o w C o n f ir m D i a l o g ( n u l l , " D e l e t e t h e r e c o r d s p e r m a n e n t l y ?", "Warning",
J O p t i o n P a n e . Y E S _ N O _ O PT I O N , J O p t i o n P a n e . W A R N I N G _ M E S S A G E , n u l l ) ;
if (n = = J O p t i o n P a n e . Y E S _ O P T IO N ) {
in t i n d e x = m a s t e r T a b l e . ge t S e l e c t e d R o w ( ) ;
cu s t o m e r r e c o r d s . C u s t o m e r s c = l i s t . g e t ( m a s t e r T a b l e . c o n v e r t R o w I n d e x T o M o d el(index));
Li s t < c u s t o m e r r e c o r d s . O r d er s > o s = c . g e t O r d e r s C o l l e c t i o n ( ) ;
in t [ ] s e l e c t e d = d e t a i l T ab l e . g e t S e l e c t e d R o w s ( ) ;
Li s t < c u s t o m e r r e c o r d s . O r d er s > t o R e m o v e = n e w A r r a y L i s t < c u s t o m e r r e c o r d s . O rders>(selected.len
fo r ( i n t i d x = 0 ; i d x < se l e c t e d . l e n g t h ; i d x + + ) {
s e l e c t e d [ i d x ] = d e t a il T a b l e . c o n v e r t R o w I n d e x T o M o d e l ( s e l e c t e d [ i d x ] ) ;
int count = 0;
I t e r a t o r < c u s t o m e r r e c or d s . O r d e r s > i t e r = o s . i t e r a t o r ( ) ;
w h i l e ( c o u n t + + < s e l ec t e d [ i d x ] ) {
iter.next();
}
c u s t o m e r r e c o r d s . O r d e rs o = i t e r . n e x t ( ) ;
toRemove.add(o);
e n t i t y M a n a g e r . r e m o v e (o ) ;
}
os . r e m o v e A l l ( t o R e m o v e ) ;
ma s t e r T a b l e . c l e a r S e l e c t i on ( ) ;
ma s t e r T a b l e . s e t R o w S e l e c t io n I n t e r v a l ( i n d e x , i n d e x ) ;
li s t . r e m o v e A l l ( t o R e m o v e ) ;
sa v e ( ) . r u n ( ) ;
} else {
re f r e s h ( ) . r u n ( ) ;
}
}
However, you can no longer edit existing records, because disabled editing of the tables in the main form. To solve this, you
will add Edit buttons to the main customer form so that you can edit existing records. For event-handling, you will take
advantage of the Swing Application Framework's Action facility.
3. Drag a button from the palette into the opening just created.
4. Right-click the button and choose Set Action.
5. In the Action field, select Create New Action.
8. Click the Advanced Tab and select r e c o r d S e l e c t e d for the Enabled Property.
This generates an annotation attribute to ensure that the button and any other trigger for the action (e.g. a menu
item) are only enabled when a record is selected.
setSav e N e e d e d ( t r u e ) ;
JFrame m a i n F r a m e = C u s t o m e r R ec o r d s A p p . g e t A p p l i c a t i o n ( ) . g e t M a i n F r a m e ( ) ;
Custom e r E d i t o r c e = n e w C u s t om e r E d i t o r ( m a i n F r a m e , f a l s e ) ;
ce.set C u r r e n t R e c o r d ( l i s t . g e t (m a s t e r T a b l e . c o n v e r t R o w I n d e x T o M o d e l ( m a s t e r T a b l e .getSelectedRow()))
ce.set V i s i b l e ( t r u e ) ;
if (ce . i s C u s t o m e r C o n f i r m e d ( ) ) {
save() . r u n ( ) ;
} else {
refres h ( ) . r u n ( ) ;
}
Most of that code is copied straight from the n e w R e c o r d action. The key difference is the line
c e . s e tC u r r e ntRecord(l i s t. g e t ( m a s t e r T a b l e . c o n v e rt R o w I n d e x T o M o d e l ( m a s t e r T a b l e . g e t S e l e c t e d R o w ( )))); , which
populates the current record in the dialog with the currently selected record.
The Customer part of the application is almost completely set. You should be able to freely add, edit, and delete records from
your CUSTOMERS table using the specialized GUI you have created.
1. In the Design view of the CustomerRecordsView class, delete the Refresh and Save buttons.
8. Click the Advanced Tab and select d e t a i l R e c o r d S e l e c t e d for the Enabled Property.
setSav e N e e d e d ( t r u e ) ;
int in d e x = m a s t e r T a b l e . g e t S el e c t e d R o w ( ) ;
custom e r r e c o r d s . C u s t o m e r s c = l i s t . g e t ( m a s t e r T a b l e . c o n v e r t R o w I n d e x T o M o d e l ( i ndex));
List<c u s t o m e r r e c o r d s . O r d e r s > o s = c . g e t O r d e r s C o l l e c t i o n ( ) ;
JFrame m a i n F r a m e = C u s t o m e r R ec o r d s A p p . g e t A p p l i c a t i o n ( ) . g e t M a i n F r a m e ( ) ;
OrderE d i t o r o e = n e w O r d e r E d it o r ( m a i n F r a m e , f a l s e ) ;
oe.set C u r r e n t O r d e r R e c o r d ( o s . ge t ( d e t a i l T a b l e . g e t S e l e c t e d R o w ( ) ) ) ;
oe.set V i s i b l e ( t r u e ) ;
if (oe . i s O r d e r C o n f i r m e d ( ) ) {
sa v e ( ) . r u n ( ) ;
} else {
re f r e s h ( ) . r u n ( ) ;
}
Now when you run the application, all of the key elements are in place. You can create, retrieve, update, and delete records for
customers and orders. In the screenshot below, you can see the Order Editor dialog as it appears after having selected a
record and pressed the Edit Order button.
The section below shows some other things that you can do to enhance and fine tune the application.
To render the Price field with currency formatting in the main view:
1. In the Projects window, right-click the C u r r e n c y C el l R e n d e r e r class and choose Compile File.
4. Right-click the lower table in the form and choose Table Contents.
Now when you run the application, the price should appear with a dollar sign ($), a decimal point, and two digits after the
decimal point.
First of all, add a label and a text field for the search field as shown below.
1. In the Projects window, right-click the R o w S o r t e r To S t r i n g C o n v e r t e r class and choose Compile File.
2. Drag the class from the Projects window and drop it in the white area surrounding the form.
3. In the Inspector window, select the r o w S o r t e r T o S t r i n g C o n v e r t e r 1 node and set its t a b l e property to
m a st e r T ab l e .
You will use this converter when you create the binding.
1. In the main form, right-click the Search text field and choose Bind > text.
2. In the Bind dialog, select ma s t e r T a b l e as the binding source and r o w S o r t e r as the expression.
Now when you run the application, you should be able to type in the Search Filter field and see that the list of rows is reduced
to only rows that contain text matching what you have typed.
However, adding this search feature creates a side effect. If you use the search and then click New Customer, an exception
appears because the code to select the new row is determined according to number of records in the database table, not
according to the number of records currently displayed in the table.
i nt row = list . s i z e ( ) - 1 ;
with:
i nt row = mast e r T a b l e . g e t R o w C o u n t ( ) - 1 ;
1. In the Projects window, right-click the DateVerifier class and choose Compile File.
2. Open the OrderEditor and switch to Design view.
3. Drag the DateVerifier class from the Projects window to the white space that surrounds the form.
4. Select the formatted text field for the Date.
5. In the Properties window, click the Properties tab, and select the d a t e V e r i f i e r 1 from the combo box for the Input
Verifier property. This property appears within the Other Properties section of the tab.
See Also
For a more general introduction to using the IDE's GUI Builder, see Introduction to GUI Building.
For a more comprehensive guide to the GUI Builder's design features, including video demonstrations of the various features,
see Designing a Swing GUI in NetBeans IDE.
To see how you can use the Java Desktop Application project template to build a database application with a Master/Detail
view, see Building a Java Desktop Database Application.
For other information on Java application development in the IDE, see the Basic IDE and Java Programming Learning Trail.
For more information on Beans Binding, see the Beans Binding project page on java.net.
For more information on beans binding in the IDE, see the Binding Beans & Data in a Desktop Application.
For information on using Hibernate for a Swing application's persistence layer, see Using Hibernate in a Java Swing Application.
For general tips and tricks on using the GUI Builder in NetBeans IDE, see the GUI Editor FAQ and Patrick Keegan's web log.