Skip to main content

Passing Dialog Input to the Main View and Database

Posted by pkeegan on May 27, 2008 at 8:33 PM PDT

This is the fourth in a series of posts on creating a Java database application. In my last few posts, I started with skeleton code generated by the IDE and provided my own customizations, including adding a dialog to use for data entry and binding those fields with a table on the main form. In this post, I finish coding the connection between the dialog and the main form. I'll also add an Edit Client button and its corresponding Action code to the main form.

First let's hook up the buttons in the EditClient dialog with appropriate event-handling code. We already have save() and refresh() actions that are provided with the skeleton application. We will code the dialog so that the buttons reuse these actions. We can accomplish this by setting up a boolean property in the dialog that returns true when the Save Record button is pushed and returns false when Cancel is selected. Based on the value that is returned when the dialog is closed, the the save() or the refresh() action will be run from the main view class.

To set up the property, do the following:

  1. Open up the EditClient file and select the Source view.
  2. Place the cursor somewhere below the block of generated code that contains the initComponents() method.
  3. Press Alt-Insert and choose Add Property.
  4. In the Add Property dialog, type clientConfirmed as the property name.
  5. Set the type to boolean.
  6. Make sure the Generate Getters and Setters checkbox is selected.
  7. Click OK to close the dialog box and generate the code.

We'll set this property's value in event handling code for the buttons. Let's create the event listeners and handlers now:

  1. Switch to the Design view for the EditClient class.
  2. Select the Save button in the EditClient form.
  3. In the Properties window, click the Events button.
  4. Click the ellipsis (...) button next to the actionPerformed property.
  5. In the Handlers for actionPerformed dialog box, add a handler called saveNewClient.
  6. Within the saveNewClient method in the Source Editor (where the cursor jumps after you create the new handler), type the following code:
    setClientConfirmed(true);
    setVisible(false);
  7. Repeat steps 2-5 for the Cancel button and call its handler cancelNewClient.
  8. In the cancelNewRecord method, type the following:
    setClientConfirmed(false);
    setVisible(false);

Navigate to the newRecord() method and add the following code to the bottom of the method:

        if (ec.isClientConfirmed()) {
            save().run();
        } else {
            refresh().run();
        }

In the RefreshTask inner class, Thread.sleep is called four times to slow down the rollback code to better demonstrate how Swing Application Framework tasks work. We don't need this code for this application, so delete those four statements. Similarly, we don't need a try/catch block here, so delete the try and catch statements as well (but leave the rest of the body of the try block).

Since the save() and refresh() actions act on any changes made during the application's session, we will want to make the dialog modal and make the tables in the main form uneditable. We also need to make the dialog modal so that when the user presses either the Save or Cancel button, the setVisible() method doesn't return until the event handler (which includes the setClientConfirmed method) has run.

To make the dialog modal:

  1. Open the Design view of the EditClient class.
  2. Select the dialog.
  3. In the Properties window, click Properties and select the checkbox for the modal property.

To make the main form's Clients table uneditable:

  1. Open the main view class in the Source Editor and select the Design view.
  2. Right-click the top table and choose Table Contents.
  3. In the Customizer dialog, select the Columns tab.
  4. For each column, clear the Editable checkbox.
  5. Click Close.

You can now run the application and click New Client to add a new record. When you press Save in the New Client dialog, the record is saved. When you press Cancel, the new record you have changed is rolled back.

This is all well and good, but by disabling the editability of the table on the main form, we can no longer edit existing records. To solve this, we'll add an Edit button to the main client form so that we can edit existing records. For event-handling, we'll take advantage of the Swing Application Framework's Action facility.

To add the button and its corresponding event-handling code, do the following:

  1. Drag the New Client Button a bit to the left.
  2. Drag a button from the palette into the opening just created.
  3. Right-click the button and choose Set Action.
  4. In the Action field, select Create New Action.
  5. For Action Method, type editClient.
  6. For Text, type Edit Client.
  7. Click the Advanced Tab and select recordSelected 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.

  8. Click OK to close the dialog box.

    The Source view of the file should appear with the cursor in the following new method:

        @Action(enabledProperty = "recordSelected")
        public void editClient() {
        }
  9. Within the method, paste the following code:
            setSaveNeeded(true);
            JFrame mainFrame = ClientAndPurchaseApp.getApplication().getMainFrame();
            EditClient ec = new EditClient(mainFrame, false);
            ec.setCurrentRecord(list.get(masterTable.getSelectedRow()));
            ec.setVisible(true);
            if (ec.isClientConfirmed()) {
                save().run();
            } else {
                refresh().run();
            }
    

Most of that code is copied straight from the newRecord action. The key difference is the line ec.setCurrentRecord(list.get(masterTable.getSelectedRow()));, which populates the current record in the dialog with the currently selected record.

The Client part of the application is almost completely set. You should be able to freely add, edit, and delete records from your CLIENTS table using the specialized GUI we have created.

One last detail: the main form still has the title of Database Application Example, and it's not obvious where to change. Hint: it's not within the GUI Builder.

To change the title of the main frame of the application:

  1. In the Projects window, select the project's node and choose Properties.
  2. In the Project Properties dialog box, select the Application node.
  3. Edit the Title property and any other properties that are important to you.
masterdetail4-projpropertiesapp.png

Now when you run the application, most of the key elements are in place. In the screenshot below, you can see the Edit Client dialog as it appears after having selected a record and pressed the Edit button.

masterdetail4-nearfinishedapp.png

I could continue with customization of the bottom part of the main form and other fine tuning of the application, but I'll save most of those details for the tutorial and individual blog posts with more atomic examples. As always, keep your questions coming and I'll try to deal with as many of them as I can.

Related Topics >>

Comments

Hello Mr Peegan very nice projects create all soruce ...

Hello Mr Peegan

very nice projects
create all soruce codes and run apllicaton click new record and run editclient but click save button this have an error pls help for errors

[EL Info]: 2014-02-15 10:51:53.905--ServerSession(31543991)--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b
[EL Info]: connection: 2014-02-15 10:51:55.505--ServerSession(31543991)--file:/C:/Users/ERDINC/Documents/NetBeansProjects/ANTREPORECORD/build/classes/_antrepostoklari?zeroDateTimeBehavior=convertToNullPU login successful
[EL Warning]: 2014-02-15 10:54:04.661--UnitOfWork(20303323)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'ACIKLAMA' cannot be null
Error Code: 1048
Call: INSERT INTO antrepostoklari.giristablo (ACIKLAMA, ANTREPO_BEYANNO, BIRIM_FIYATI, DOVIZ_CINSI, ESYA_CINSI, FATURA_TUTARI, FATURANO_TARIHI, GBRUT_KG, GELDIGI_ULKE, GKAP_ADEDI, GNET_KG, GONDERICI_FIRMA, GTIP_NO, KAP_SEKLI, MARKASI, MENSEI, TARIHI) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
bind => [17 parameters bound]
Query: InsertObjectQuery(antreporecord.Giristablo[ sıra=null ])

Hello Patrick I have folowing this article, and my problem ...

Hello Patrick I have folowing this article, and my problem is data wont enter in table as new inport. Maybe a bit loong to use this tutorial but i just wondering what i am missing ?

hi i want to use the detail view only without using jtable to bind my object i want directly bind the domain objects properties to the gui form and of course i want to add create new object too.... netbeans uses following form of binding list > jtable > seledcted element > domain object how to acheive this object > gui fiels please help me on this

Hi Patrick, thank you so much for answering. I already read your other texts before deciding to write you and thanks to them I learned how to quickly bind objects and use validators. It really is a fantastic feature !
To explain my question let's look at the ClientEditor example: if we put this line immediately after initComponents() is called :
" client.setAge(300); "
it will alter the age of the client object, and it will be synced with the gui... BUT it will NOT get validated the first time ! the valid age is between 1..200, 300 is obviously an invalid value. If one then manually deletes the 300 from the gui, only after that the validator seems to function. My question was if there is a way to trigger validation immediately, or to give an explicit order to validate ? Thank you again, keep up the great work ! dalibor

Hello Patrick, Is the validator of a binding object notified the first time the binding is created? If not, is there a way to explicitly validate it? I would like to bind a JTextField to a field in a POJO, and when the field is empty it should become colored (to mark that is invalid). Currently, it becomes colored only after I type something in it and cancel it with backspace. It would be nice to have it colored immediately after it gets initialized. I looked at the example in NetBeans (ClientEditor) and I noticed that if one sets the person's age to 300 (an invalid value) after the initComponents() method, it will not be marked as invalid. Why is that? Thank you for your time, I really don't know where to ask :) dalibor

Hi Dalibor. You can specify a validator in the Advanced tab of the binding dialog. The validator class must implement the validate method of org.jdesktop.beansbinding.Validator. More on that can be found in the Javadoc (from the IDE, choose Help -> Javadoc References -> Beans Binding). Once you write the validator class, compile it, and then drag it onto the form (actually drag it to the white area around the form) to add it to the form as a bean. It will then become available to you in the Bind dialog to add as a validator. The Client Editor example you mention is a great place to look to see how validators and converters work. The AgeValidator class handles the validation. Also, I wrote about converters and validators here: http://weblogs.java.net/blog/pkeegan/archive/2007/11/beans_binding_c.html and here: http://www.netbeans.org/kb/60/java/gui-binding.html