Well, I've bitten the bullet and decided to move my blog over to Wordpress. Why? Well, one reason: offline editing. There are some good offline tools that work with both blogger.com and with wordpress.com, BUT, I haven't found any way to be able to work with images and blogger.com, whereas the tools seem to work fine with Wordpress.
Come visit the new place at http://stegemanoracle.wordpress.com.
Monday, July 02, 2007
Thursday, June 28, 2007
Frequently asked questions, or "the human Google"
I really like the JDeveloper Forum on OTN. I have a little desktop widget that uses RSS to show the latest posts as they come in. I read the forum almost like a Blog - it's always interesting, informative, and helpful to see what issues people are grappling with; lots of times, I get new ideas to try by reading posts there. I also try to answer as many of the questions that come up as I can. Why? The forum was helpful to me starting out, and, personally, I'd like to see others be successful with JDeveloper and the marketplace for JDeveloper to grow - purely for selfish reasons. I'm a consultant, and the more potential customers use JDeveloper and Oracle stuff, the more potential customers for me and the company I work for.
As I read the posts, there are some that just come up over and over and over and over. Lots of times, I'll answer the questions by doing a quick search on the forum and posting the link (hence "the human Google"). So I thought I'd compile a list of questions and answers here, sort of an unofficial FAQ. For what it's worth, I mostly use ADF Business Components and ADF Faces - not much of an EJB/Swing guy at the moment, so don't expect to see Swing/EJB questions.
By the way, if there's a better answer somewhere or something that should be added, let me know and I'll update the list - just post a comment to this entry.
Some of the questions/answers are a bit tongue-in-cheek ;)
Question: I'd like to create a page to frobdigate the whigginator. It's urgent so please help me!
Answer: Would you now? Honestly, there are a fair number of questions on the forum that are about this comprehensible. If you want a good answer, be sure to provide enough information so that the readers at least know what you're talking about.
Question: When will version xyz of JDeveloper be available?
Answer: When it's ready. I've been guilty of asking this question a few times myself.
Question: How do I convert among java.util.Date and oracle.jbo.domain.Date and java.sql.Date
Answer: Here's a good post that gives a few examples.
Question: How can I create two drop-down list boxes (af:selectOneChoice) such that when I pick a value from the first one, it changes the values in the second one - for example, when I pick the State from the first, the second one should contain a list of cities in that state?
Answer: Frank Nimphius of Oracle has written about this.
Question: I want to add security to my Faces application where I can validate the username and password against a database table. How do I do that?
Answer: Here's one way.
Question: blah blah blah OAF blah blah Oracle Applications Framework blah blah OA Framework?
Answer: Try the OA Framework forum on OTN.
Question: I want to have a gap-less sequence number as the key for my table, how
Answer: No, you don't.
Question: but I wasn't finished with my question yet.
Answer: Yes you were.
Question: OK, I understand I should use a database sequence. Why is the number negative/how do I use the sequence?
Answer: Have a read of the ADF Developer's Guide for Forms/4GL Developers, section 6.6.3.8 for starters. Then, read the rest of that document ;)
Question: How can I display images that are stored in a blob in the database?
Answer: Read this post
Question: How can I use a drop-down list (af:selectOneChoice) inside of an editable table (af:table)?
Answer: Steve Muench of Oracle did a nice screencast showing how to do that.
Question: How can I call a stored procedure from my application module code? I don't want to open a new database connection
Answer: Check out this post.
Question: I am trying to connect to my Oracle XE database and am getting errors. What do I need to do?
Answer: The Oracle XE connection information is localhost:1521:XE. Most likely, you forgot to change the SID from "ORCL" to "XE" when you set up the connection.
Question: How do I get the selected label of an af:selectOneChoice? Every time I try, I just get a number
Answer: Frank Nimphius to the rescue again.
Question: How do I highlight the selected row in an af:table?
Answer: Check out this post for a couple of answers.
As I read the posts, there are some that just come up over and over and over and over. Lots of times, I'll answer the questions by doing a quick search on the forum and posting the link (hence "the human Google"). So I thought I'd compile a list of questions and answers here, sort of an unofficial FAQ. For what it's worth, I mostly use ADF Business Components and ADF Faces - not much of an EJB/Swing guy at the moment, so don't expect to see Swing/EJB questions.
By the way, if there's a better answer somewhere or something that should be added, let me know and I'll update the list - just post a comment to this entry.
Some of the questions/answers are a bit tongue-in-cheek ;)
Question: I'd like to create a page to frobdigate the whigginator. It's urgent so please help me!
Answer: Would you now? Honestly, there are a fair number of questions on the forum that are about this comprehensible. If you want a good answer, be sure to provide enough information so that the readers at least know what you're talking about.
Question: When will version xyz of JDeveloper be available?
Answer: When it's ready. I've been guilty of asking this question a few times myself.
Question: How do I convert among java.util.Date and oracle.jbo.domain.Date and java.sql.Date
Answer: Here's a good post that gives a few examples.
Question: How can I create two drop-down list boxes (af:selectOneChoice) such that when I pick a value from the first one, it changes the values in the second one - for example, when I pick the State from the first, the second one should contain a list of cities in that state?
Answer: Frank Nimphius of Oracle has written about this.
Question: I want to add security to my Faces application where I can validate the username and password against a database table. How do I do that?
Answer: Here's one way.
Question: blah blah blah OAF blah blah Oracle Applications Framework blah blah OA Framework?
Answer: Try the OA Framework forum on OTN.
Question: I want to have a gap-less sequence number as the key for my table, how
Answer: No, you don't.
Question: but I wasn't finished with my question yet.
Answer: Yes you were.
Question: OK, I understand I should use a database sequence. Why is the number negative/how do I use the sequence?
Answer: Have a read of the ADF Developer's Guide for Forms/4GL Developers, section 6.6.3.8 for starters. Then, read the rest of that document ;)
Question: How can I display images that are stored in a blob in the database?
Answer: Read this post
Question: How can I use a drop-down list (af:selectOneChoice) inside of an editable table (af:table)?
Answer: Steve Muench of Oracle did a nice screencast showing how to do that.
Question: How can I call a stored procedure from my application module code? I don't want to open a new database connection
Answer: Check out this post.
Question: I am trying to connect to my Oracle XE database and am getting errors. What do I need to do?
Answer: The Oracle XE connection information is localhost:1521:XE. Most likely, you forgot to change the SID from "ORCL" to "XE" when you set up the connection.
Question: How do I get the selected label of an af:selectOneChoice? Every time I try, I just get a number
Answer: Frank Nimphius to the rescue again.
Question: How do I highlight the selected row in an af:table?
Answer: Check out this post for a couple of answers.
Tuesday, June 05, 2007
Who likes JDeveloper and who pooh-poohs?
Jan Vervecken started a recent thread on the OTN JDeveloper Forum entitled, "The forgotten Java IDE?" It's quickly garnered a lot of replies (57 at the current count!). It's lead me to do some thinking and some researching around the Web.
To paraphrase both Blondie aka "the man with no name" (Clint Eastwood) and Tuco (Eli Wallach) as they were wont to say in my all-time favorite movie, "There are two types of people in the world my friend, those who like JDeveloper, and those who pooh-pooh it." Well, the world is more complex than that, but it seems to be the case that a given person either loves JDeveloper, or thinks it's completely useless and irrelevant. Can both types of people be talking about the same thing?
In my experience on the OTN forums, at Java One, and from reading blogs and other Internet posts, I've been able to create some stereotypes of the two types of people, and gain some insight into the "why" of the stereotypes.
People who like JDeveloper tend to:
The hard-core java guys, on the other hand, want to fiddle with every bit and byte. Now, in my opinion, JDeveloper can do this just as well, if not better, than the other IDE's out there (Eclipse, Netbeans, IntelliJ, etc); however, most of these folks already have an established IDE preference, and changing IDE's is something that requires a conscious effort and reason to change. Thus, even though I really like JDeveloper, and think it's a world-class IDE, and would like more people to use it (selfish reasons, I guess - I want to ensure that Oracle will always be putting lots of effort into new releases), I would say to this group of people, "keep using whatever you are using." If you want a nice productive database development environment, or a nice BPEL development environment, come on over and take a look. Heck, I'd be willing to bet that most of the hard-core guys, if they would be willing to take an honest look at ADF, would find that there are some good things there for them.
As to which type of person am I... I've got some characteristics of both. I've done some Oracle Forms (mostly Forms 2.3 and Forms 3.0!) programming in my life. I actually got my start doing more hard-core C/C++ programming and did "hard-core" java before I got into ADF; so I guess I don't fit the stereotypes I've laid out here.
.....
To paraphrase both Blondie aka "the man with no name" (Clint Eastwood) and Tuco (Eli Wallach) as they were wont to say in my all-time favorite movie, "There are two types of people in the world my friend, those who like JDeveloper, and those who pooh-pooh it." Well, the world is more complex than that, but it seems to be the case that a given person either loves JDeveloper, or thinks it's completely useless and irrelevant. Can both types of people be talking about the same thing?
In my experience on the OTN forums, at Java One, and from reading blogs and other Internet posts, I've been able to create some stereotypes of the two types of people, and gain some insight into the "why" of the stereotypes.
People who like JDeveloper tend to:
- Already be Oracle customers
- Have experience with 4GL languages, especially Oracle Forms
- Use Oracle's Application Development Framework (ADF)
- Like the integrated SOA development tools in JDeveloper
- Think of themselves as "hard-core" java programmers or "java gurus"
- Dislike anything "proprietary," and thus tend to discount ADF
- Really like open source, "free" things (although, as a sidebar, my friend always used to say, "if it's free, I can't afford it")
The hard-core java guys, on the other hand, want to fiddle with every bit and byte. Now, in my opinion, JDeveloper can do this just as well, if not better, than the other IDE's out there (Eclipse, Netbeans, IntelliJ, etc); however, most of these folks already have an established IDE preference, and changing IDE's is something that requires a conscious effort and reason to change. Thus, even though I really like JDeveloper, and think it's a world-class IDE, and would like more people to use it (selfish reasons, I guess - I want to ensure that Oracle will always be putting lots of effort into new releases), I would say to this group of people, "keep using whatever you are using." If you want a nice productive database development environment, or a nice BPEL development environment, come on over and take a look. Heck, I'd be willing to bet that most of the hard-core guys, if they would be willing to take an honest look at ADF, would find that there are some good things there for them.
As to which type of person am I... I've got some characteristics of both. I've done some Oracle Forms (mostly Forms 2.3 and Forms 3.0!) programming in my life. I actually got my start doing more hard-core C/C++ programming and did "hard-core" java before I got into ADF; so I guess I don't fit the stereotypes I've laid out here.
.....
Sunday, June 03, 2007
Conditionally showing fields based upon attribute value part deux
This is the second in a two-part series showing how to conditionally show/hide fields based upon the value of another field. In case you haven't read the first part, start here.
As we left before the commercial break, we had just set up the navigation links between our emplist and empedit pages. Let's first fix up the "Edit" and "New Employee" buttons on the emplist page so that clicking them will take us to the edit page. To do this is really quite simple. For the edit button, select the button using either the visual editor or the structure window; then, use the property inspector to set the Action property to "edit," which is the navigation case you created. There's even a drop-down list in the property inspector - JDeveloper knows about the navigation cases, and thus can give you a drop-down list. Now, just do the same thing for the "New Employee" button; in this case, at run-time, the action listener (which creates the new employee record) will fire first, and then the action property causes the navigation case "edit" to fire, taking you to the empedit page.
Now, let's create the skeleton of the empedit page. First, ensure empedit.jspx is shown in the visual editor. Then, in the data control palette, drag MyEmpView1 to the empedit.jspx page and drop it. In the pop-up menu, select "Forms" and then "ADF Form" from the sub-menu. Ensure the "Include Submit Button" checkbox is selected and click "OK."
Let's next add a commit button to the page so that the changes can be saved to the database. In the data control palette, expand the AppModuleDataControl and then expand the "operations" folder from the data control - be sure it's the AppModuleDataControl's operations folder, and not the MyEmpView1's. If you have the correct one, you'll see Commit and Rollback operations. Drag the commit operation and drop it on to the empedit.jspx page next to the submit button. In the pop-up menu, choose "ADF Command Button." Finally, select the "Commit" button and use the property inspector to set the Action property to "returntolist." This will make clicking the commit button take us back to the list page as well as committing the data to the database.
Now, we've got a basic working application. Let's test it; right-click the emplist.jspx page in the applications navigator and choose "run." You should see an (empty) list of employees. Click the "New Employee" button, fill in some values, and click commit. You can also test editing an employee you create (use the "submit" button to submit changes and make ADF enable the commit button). For now, create at least two employees, one with emptype of "H" and one with emptype of "S." Here's what my emplist.jspx looks like after I did that:
There's a lot more we should to to make this a real application (adding a "Cancel" button, for example), but I'll leave that to you. What we really want to show now is how to make the Salary field hidden (and set to null in the database) when the employee type is "hourly" and make the Hourly Rate field hidden (and set to null in the database) when the employee type is "salaried." There are a number of ADF Faces controls we could use to implement this (they all start with "ShowOne"), but for this example, let's use a ShowOneRadio.
In the Component Palette, ensure the ADF Faces Core components are showing and locate the ShowOneRadio. Drag it to the empedit page and drop it between the Emptype and Salary fields (it's easiest if you use the Structure window). Use the property editor to change the label to "Employee Type." You should now have something that looks like this:
The "ShowOne" components work by having "ShowDetail" components as their children. So, locate the ShowDetail component in the Component Palette and drag one to the af:showOneRadio you just created; again, it's easiest if you use the Structure window to ensure you are dropping it on the right component. Use the property inspector to change the Text property to "Hourly." Then, repeat the same process to create another ShowDetail component with its text set to "Salaried." When you are done, the Structure should look something like this:
The next step is to put the Salary and HourlyRate fields into the appropriate ShowDetail component. To do this, just use the structure window to drag the Salary's af:inputText component to the "Salaried" showDetailItem and the Hourly Rate's af:inputText component to the "Hourly" showDetailItem. Your structure now should look like this:
If you run the application now, you'll see that clicking the Hourly or Salaried radio buttons automatically hide/show the appropriate fields; however, the value of the EMPTYPE field doesn't have anything to do with the radio buttons at this point. We'll need to write some code to make that part work.
The code that you will write needs to be in a java class known as a "managed bean." We'll let JDeveloper create the managed bean for us. If you click one of the af:showDetailItem components and look in the Property Inspector, you'll see a property called the "Disclosure Listener." This is where we will write our Java code (for you experts out there, yes, the af:showOneRadio has an attribute change listener that is a better place for the code, but for some reason, it does not fire correctly in JDev 10.1.3.1). To create the managed bean, select the Hourly showDetailItem in the Structure window and then click in the blank field next to "DisclosureListener" in the Property Inspector. You should see a button appear with an elipsis (...) in the label - click this button. You'll get a dialog that looks like this:
Click the "New..." button to create a new managed bean. Use "empedit_bean" for both the name and class and leave the scope set at request:
After clicking "OK", click the "New..." button next to the Method drop-down list. Provide a method name of "hourly_disclosed" and click "OK." The dialog now looks like this:
Click "OK" in the managed bean window. You should see a new tab at the top of the editor for the empedit_bean.java file that was just created. The code looks like this:
import oracle.adf.view.faces.event.DisclosureEvent;
public class empedit_bean
{
public empedit_bean()
{
}
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
// Add event code here...
}
}
Let's add some simple code to the disclosure listener so that we can see how it works. Change the hourly_disclosed method so that it looks like this:
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
System.out.println("The hourly type was selected");
}
else
{
System.out.println("The hourly type was not selected");
}
}
Now, let's create a disclosure listener for the Salary radio button. Just type this code into the editor:
public void salaried_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
System.out.println("The salaried type was selected");
}
else
{
System.out.println("The salaried type was not selected");
}
}
Finally, go back to the empedit.jspx page and select the af:showDetailItem for Salaried. In the property inspector, click the elipsis-button next to the DisclosureListener property and pick the empedit_bean managed bean and salaried_disclosed method:
Now, when you run the application and click the Hourly and Salaried radio buttons, you should see a pair of messages in the log window for each click. This shows us that our code is running correctly. We now just have two steps remaining. The first is to make the value in the database field EMPTYPE determine which radio button is selected. This is really quite simple. If you go back to the empedit.jspx page and select the "Hourly" af:showDetailItem, you'll notice a property in the property inspector called "Disclosed," which is set to false. What we will do is to use an Expression Language (EL) expression to set the item to be disclosed if the value of the EMPTYPE field in the database is "H." To do so, click the Disclosed property in the inspector. You should see the "Bind to data" button become available in the property inspector toolbar - it looks like this:
Click the Bind to data button; this displays JDeveloper's EL editor. In the editor, expand the ADF Bindings folder, then the bindings container. You should see an attribute binding for "Emptype." Finally, expand that binding and double-click on the InputValue property. The Expression builder should now look like this:
Complete the expression by typing so that it reads:
#{bindings.Emptype.inputValue == "H"}
Remember before when we set the default value of the field EMPTYPE to "H?" This is so we didn't have to code for the special NULL case here, although it's not too difficult. Now, repeat the same process for the Salaried af:showDetailItem, except the "disclosed" property should be:
#{bindings.Emptype.inputValue == "S"}
At this point, if you run your application and edit the two employees you created earlier (one hourly and one salaried), you should see the correct radio button selected and the correct field shown.
We now just have some cosmetic issues to clean up (we still have the EMPTYPE field on the screen) and one remaining problem: clicking the Hourly and Salaried radio buttons do not change the value of the EMPTYPE field - we haven't written the code to make this happen yet. Let's start by getting rid of the EMPTYPE field. If you just click on the EMPTYPE af:inputText and delete it, it will also delete the binding in the underlying page definition, which will make our page break, because we use that binding. Here's a little trick that I use to avoid this behavior. Before you delete the af:inputText item, open the page definition for empedit.jspx by right-clicking in an empty area of the empedit.jspx page and choosing Go to Page Definition. Now, you can go back to the empedit.jspx page and delete the EMPTYPE field. Now, just switch back to the page definition and close it, answering "no" when prompted to save changes.
The last item remaining is to set the value of the EMPTYPE field as we click the radio buttons for Hourly and Salaried employees. This code will go into the disclosure listeners. Let's code a simple utility method into our backing bean that will allow us to set the employee type, and we can call that utility method from the disclosure listeners. For good measure, let's also NULL out the salary for hourly employees and null out the hourly rate for salaried employees. I provide the code here with no explanation; this is pretty straightforward JSF code at this point:
private void setEmpType(String type)
{
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
ValueBinding bind = app.createValueBinding("#{bindings.Emptype.inputValue}");
bind.setValue(ctx, type);
if ("S".equals(type))
{
bind = app.createValueBinding("#{bindings.Hourlyrate.inputValue}");
}
else
{
bind = app.createValueBinding("#{bindings.Salary.inputValue}");
}
bind.setValue(ctx, null);
}
Now, it's simply a matter of fixing up the disclosure listeners to look like this:
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
setEmpType("H");
}
}
public void salaried_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
setEmpType("S");
}
}
There we are.... there are lots of little things that can be cleaned up and made more robust, but that's the technique.
As we left before the commercial break, we had just set up the navigation links between our emplist and empedit pages. Let's first fix up the "Edit" and "New Employee" buttons on the emplist page so that clicking them will take us to the edit page. To do this is really quite simple. For the edit button, select the button using either the visual editor or the structure window; then, use the property inspector to set the Action property to "edit," which is the navigation case you created. There's even a drop-down list in the property inspector - JDeveloper knows about the navigation cases, and thus can give you a drop-down list. Now, just do the same thing for the "New Employee" button; in this case, at run-time, the action listener (which creates the new employee record) will fire first, and then the action property causes the navigation case "edit" to fire, taking you to the empedit page.
Now, let's create the skeleton of the empedit page. First, ensure empedit.jspx is shown in the visual editor. Then, in the data control palette, drag MyEmpView1 to the empedit.jspx page and drop it. In the pop-up menu, select "Forms" and then "ADF Form" from the sub-menu. Ensure the "Include Submit Button" checkbox is selected and click "OK."
Let's next add a commit button to the page so that the changes can be saved to the database. In the data control palette, expand the AppModuleDataControl and then expand the "operations" folder from the data control - be sure it's the AppModuleDataControl's operations folder, and not the MyEmpView1's. If you have the correct one, you'll see Commit and Rollback operations. Drag the commit operation and drop it on to the empedit.jspx page next to the submit button. In the pop-up menu, choose "ADF Command Button." Finally, select the "Commit" button and use the property inspector to set the Action property to "returntolist." This will make clicking the commit button take us back to the list page as well as committing the data to the database.
Now, we've got a basic working application. Let's test it; right-click the emplist.jspx page in the applications navigator and choose "run." You should see an (empty) list of employees. Click the "New Employee" button, fill in some values, and click commit. You can also test editing an employee you create (use the "submit" button to submit changes and make ADF enable the commit button). For now, create at least two employees, one with emptype of "H" and one with emptype of "S." Here's what my emplist.jspx looks like after I did that:
There's a lot more we should to to make this a real application (adding a "Cancel" button, for example), but I'll leave that to you. What we really want to show now is how to make the Salary field hidden (and set to null in the database) when the employee type is "hourly" and make the Hourly Rate field hidden (and set to null in the database) when the employee type is "salaried." There are a number of ADF Faces controls we could use to implement this (they all start with "ShowOne"), but for this example, let's use a ShowOneRadio.
In the Component Palette, ensure the ADF Faces Core components are showing and locate the ShowOneRadio. Drag it to the empedit page and drop it between the Emptype and Salary fields (it's easiest if you use the Structure window). Use the property editor to change the label to "Employee Type." You should now have something that looks like this:
The "ShowOne" components work by having "ShowDetail" components as their children. So, locate the ShowDetail component in the Component Palette and drag one to the af:showOneRadio you just created; again, it's easiest if you use the Structure window to ensure you are dropping it on the right component. Use the property inspector to change the Text property to "Hourly." Then, repeat the same process to create another ShowDetail component with its text set to "Salaried." When you are done, the Structure should look something like this:
The next step is to put the Salary and HourlyRate fields into the appropriate ShowDetail component. To do this, just use the structure window to drag the Salary's af:inputText component to the "Salaried" showDetailItem and the Hourly Rate's af:inputText component to the "Hourly" showDetailItem. Your structure now should look like this:
If you run the application now, you'll see that clicking the Hourly or Salaried radio buttons automatically hide/show the appropriate fields; however, the value of the EMPTYPE field doesn't have anything to do with the radio buttons at this point. We'll need to write some code to make that part work.
The code that you will write needs to be in a java class known as a "managed bean." We'll let JDeveloper create the managed bean for us. If you click one of the af:showDetailItem components and look in the Property Inspector, you'll see a property called the "Disclosure Listener." This is where we will write our Java code (for you experts out there, yes, the af:showOneRadio has an attribute change listener that is a better place for the code, but for some reason, it does not fire correctly in JDev 10.1.3.1). To create the managed bean, select the Hourly showDetailItem in the Structure window and then click in the blank field next to "DisclosureListener" in the Property Inspector. You should see a button appear with an elipsis (...) in the label - click this button. You'll get a dialog that looks like this:
Click the "New..." button to create a new managed bean. Use "empedit_bean" for both the name and class and leave the scope set at request:
After clicking "OK", click the "New..." button next to the Method drop-down list. Provide a method name of "hourly_disclosed" and click "OK." The dialog now looks like this:
Click "OK" in the managed bean window. You should see a new tab at the top of the editor for the empedit_bean.java file that was just created. The code looks like this:
import oracle.adf.view.faces.event.DisclosureEvent;
public class empedit_bean
{
public empedit_bean()
{
}
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
// Add event code here...
}
}
Let's add some simple code to the disclosure listener so that we can see how it works. Change the hourly_disclosed method so that it looks like this:
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
System.out.println("The hourly type was selected");
}
else
{
System.out.println("The hourly type was not selected");
}
}
Now, let's create a disclosure listener for the Salary radio button. Just type this code into the editor:
public void salaried_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
System.out.println("The salaried type was selected");
}
else
{
System.out.println("The salaried type was not selected");
}
}
Finally, go back to the empedit.jspx page and select the af:showDetailItem for Salaried. In the property inspector, click the elipsis-button next to the DisclosureListener property and pick the empedit_bean managed bean and salaried_disclosed method:
Now, when you run the application and click the Hourly and Salaried radio buttons, you should see a pair of messages in the log window for each click. This shows us that our code is running correctly. We now just have two steps remaining. The first is to make the value in the database field EMPTYPE determine which radio button is selected. This is really quite simple. If you go back to the empedit.jspx page and select the "Hourly" af:showDetailItem, you'll notice a property in the property inspector called "Disclosed," which is set to false. What we will do is to use an Expression Language (EL) expression to set the item to be disclosed if the value of the EMPTYPE field in the database is "H." To do so, click the Disclosed property in the inspector. You should see the "Bind to data" button become available in the property inspector toolbar - it looks like this:
Click the Bind to data button; this displays JDeveloper's EL editor. In the editor, expand the ADF Bindings folder, then the bindings container. You should see an attribute binding for "Emptype." Finally, expand that binding and double-click on the InputValue property. The Expression builder should now look like this:
Complete the expression by typing so that it reads:
#{bindings.Emptype.inputValue == "H"}
Remember before when we set the default value of the field EMPTYPE to "H?" This is so we didn't have to code for the special NULL case here, although it's not too difficult. Now, repeat the same process for the Salaried af:showDetailItem, except the "disclosed" property should be:
#{bindings.Emptype.inputValue == "S"}
At this point, if you run your application and edit the two employees you created earlier (one hourly and one salaried), you should see the correct radio button selected and the correct field shown.
We now just have some cosmetic issues to clean up (we still have the EMPTYPE field on the screen) and one remaining problem: clicking the Hourly and Salaried radio buttons do not change the value of the EMPTYPE field - we haven't written the code to make this happen yet. Let's start by getting rid of the EMPTYPE field. If you just click on the EMPTYPE af:inputText and delete it, it will also delete the binding in the underlying page definition, which will make our page break, because we use that binding. Here's a little trick that I use to avoid this behavior. Before you delete the af:inputText item, open the page definition for empedit.jspx by right-clicking in an empty area of the empedit.jspx page and choosing Go to Page Definition. Now, you can go back to the empedit.jspx page and delete the EMPTYPE field. Now, just switch back to the page definition and close it, answering "no" when prompted to save changes.
The last item remaining is to set the value of the EMPTYPE field as we click the radio buttons for Hourly and Salaried employees. This code will go into the disclosure listeners. Let's code a simple utility method into our backing bean that will allow us to set the employee type, and we can call that utility method from the disclosure listeners. For good measure, let's also NULL out the salary for hourly employees and null out the hourly rate for salaried employees. I provide the code here with no explanation; this is pretty straightforward JSF code at this point:
private void setEmpType(String type)
{
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
ValueBinding bind = app.createValueBinding("#{bindings.Emptype.inputValue}");
bind.setValue(ctx, type);
if ("S".equals(type))
{
bind = app.createValueBinding("#{bindings.Hourlyrate.inputValue}");
}
else
{
bind = app.createValueBinding("#{bindings.Salary.inputValue}");
}
bind.setValue(ctx, null);
}
Now, it's simply a matter of fixing up the disclosure listeners to look like this:
public void hourly_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
setEmpType("H");
}
}
public void salaried_disclosed(DisclosureEvent disclosureEvent)
{
if (disclosureEvent.isExpanded())
{
setEmpType("S");
}
}
There we are.... there are lots of little things that can be cleaned up and made more robust, but that's the technique.
Conditionally showing fields based upon attribute value
A recent post on the OTN JDeveloper Forum asks how to hide/show fields on an ADF Faces page depending upon the value of another attribute. I've concocted a simple example to show the technique I used in a recent project to accomplish this.
The business case in the example is quite simple: we want to create a page to allow us to create and edit employee information. There are two types of employees: salaried employees and hourly employees. Salaried employees earn a yearly salary regardless of how many long hours they work (sounds familiar), whereas hourly employees earn an hourly rate for each hour they work. Our database table looks like this:
create table my_emp
(empno number not null primary key,
emptype varchar2(1) not null,
salary number,
hourlyrate number);
On our employee edit screen, we want to show the salary field if the employee type is "S" (for salaried) and show the hourlyrate field if the employee type is "H". In both cases, the field that does not apply to the particular employee should be hidden AND should be automatically set to null in the database. We'll also create a typical list screen that lets us browse through the employees and select one to edit, and also to create new employees.
I will walk quickly through the preliminary steps, and slow down later on to show the details. This example should work with any of the point releases of JDeveloper 10g R3 (10.1.3.x).
To get started, use your favorite tool (SQL*Plus, SQL Developer, JDeveloper, etc) to create the table as shown above. Then, in JDeveloper, create a database connection to the database/account that owns the table you created. Finally, create a new application, selecting the "Web Application [JSF, ADF BC]" template in the directory of your choice:
In your newly created application, you should have two projects - "Model" and "ViewController." The next step is to create some ADF Business Components for the my_emp table. In this example, we'll just create some basic stuff (a single Entity Object, a default editable View Object, and a default Application Module). To do this, right-click the Model project and choose "New..." In the dialog that appears, choose "ADF Business Components" in the categories pane and "Business Components from Tables" in the items pane:
You'll be prompted to initialize your project for business components. Pick the connection you created earlier (and the SQL flavor and type map if you are not using an Oracle database) and click "OK." Now, you'll quickly walk through the wizard to create the default business components. Click "Next" to dismiss the welcome screen, if it is shown. On the next screen, type "my_emp" in the name filter and press "Query" to display the table you created earlier; use the shuttle controls to add the MY_EMP table to the selected list:
Click "Next" to display the "Updatable View Objects" page of the wizard; use the shuttle controls to add the MyEmp Entity Object to the selected list:
From here on out, we will just be taking the defaults for the wizard, so you can click "Finish." If you'd like to see the steps one-by-one, you can click "Next" on each page to see them. Once you are done, you will have a single Entity Object called "MyEmp," an updatable View Object called "MyEmpView," and an Application Module called "AppModule," which has MyEmpView in its data model. You can see these objects by expanding the folders under the Model project in the Applications Navigator. To make things a bit easier down the road, let's set a default for the employee type to "H" for hourly. To do this, double-click on the MyEmp entity object. In the dialog that appears, expand the Attributes tree on the left side and click the "EmpType" attribute. Now, in the right pane, enter "H" into the default value field and press "OK" when done:
That's it for the data model; in real life, you'd of course give some nice attribute names, display hints, etc, etc, but I'll leave that to you. The next step for this exercise is to create the JSF pages. We will first create a simple list-type page that lists the employees and allows us to select an employee to edit or to create a new employee. To do this, right-click the "ViewController" project and select "New..." In the dialog that appears, select "JSF" from the categories pane and JSF JSP from the items pane. Click "Next" to dismiss the welcome page, if it is shown; this will display the "JSP File" step of the wizard. Let's call our page "emplist.jspx" Make sure the "JSP Document" radio button is selected for the document type:
Click "Next" to display the component binding page. As we do not need component bindings, click "Next" to display the tag libraries page. Ensure that you have the 4 libraries selected as shown here:
Now, you can click "Finish" to complete the wizard. While we are at it, follow the same steps to create an "empedit.jspx" page. Now, let's finish the emplist page - it's the simpler of the two. To create an ADF Faces table, go to the Data Control Palette window in JDeveloper. You should see a single data control called "AppModuleDataControl." Expand the data control, and you'll find your single view object, "MyEmpView1." Ensure that you have the emplist.jspx page open in the visual editor and drag the "MyEmpView1" view object on to the emplist.jspx page. In the pop-up menu that appears, select the "Tables" menu and then the "ADF Read-only" table from the sub-menu. Ensure that you click the "Enable Selection" checkbox and click "OK." You'll now see the af:table added to your page. If you run the page now, you'll see an empty table because there are no rows in the database.
Next, let's add "Edit" and "New Employee" buttons to the page. First, get rid of the "Submit" button that JDeveloper created for you automatically by selecting it and hitting the Delete key. The "Edit" button that we are going to add must be inside of the af:tableSelectOne object that exists inside of the "selection" facet of the table. My preferred way to drag-and-drop components is to use the structure window in JDeveloper, because it gives me the most precision. So, expand the items in the structure window until you get to the af:tableSelectOne object (you can also click on the radio buttons in the "Select" column of the table to do this automatically):
Now, find the Control Palette window in JDeveloper. Select "ADF Faces Core" from the drop-down at the top of the palette and find the "CommandButton" component. Drag this component and drop it into the af:tableSelectOne on your page. If you've done it correctly, you'll se an af:commandButton inside of the af:tableSelectOne in the structure window, and your page will look like this:
Use the Property Inspector window of JDeveloper to change the text of the button to "Edit." Now, let's add the "New Employee" button. Because the "New Employee" button does not require an employee to be selected first, it doesn't belong in the selection facet of the table, but the "actions" facet. First, make sure that you can see the actions facet in JDeveloper's structure window; secondly, in the Data Control Palette, expand the AppModuleDataControl, the EmpView1, and the Operations folder. Find the "Create" operation and drag it into the actions facet, using the structure window. In the pop-up window that appears when you release the mouse, select ADF Command Button. You can now use the property inspector to change the text of the command button to "New Employee."
Now, without going into a long explanation of why (read the docs if you must), we need to change the binding on the "New Employee" button from the "Create" action to "CreateInsert." To do this, right-click in a blank area of the emplist.jspx page and choose "Go To Page Definition." Using the structure window, expand the bindings folder and double-click on the "Create" binding. In the window that appears, change the action from "Create" to "CreateInsert:"
Now, save and close the page binding. The final piece of work we need to do on this page is to set up some navigation cases so that we can navigate back and forth between the list and edit pages. I'm not going to walk through all of the steps here (a quick read of the docs should set you in the right direction). Create two navigation cases, one going from emplist.jspx to empedit.jspx called "edit" and one going from empedit.jspx to emplist.jspx called "returntolist." Here's what my faces-config.xml navigation diagram looked like after this step:
Wow - this is more steps than I thought.... continued in part deux.
The business case in the example is quite simple: we want to create a page to allow us to create and edit employee information. There are two types of employees: salaried employees and hourly employees. Salaried employees earn a yearly salary regardless of how many long hours they work (sounds familiar), whereas hourly employees earn an hourly rate for each hour they work. Our database table looks like this:
create table my_emp
(empno number not null primary key,
emptype varchar2(1) not null,
salary number,
hourlyrate number);
On our employee edit screen, we want to show the salary field if the employee type is "S" (for salaried) and show the hourlyrate field if the employee type is "H". In both cases, the field that does not apply to the particular employee should be hidden AND should be automatically set to null in the database. We'll also create a typical list screen that lets us browse through the employees and select one to edit, and also to create new employees.
I will walk quickly through the preliminary steps, and slow down later on to show the details. This example should work with any of the point releases of JDeveloper 10g R3 (10.1.3.x).
To get started, use your favorite tool (SQL*Plus, SQL Developer, JDeveloper, etc) to create the table as shown above. Then, in JDeveloper, create a database connection to the database/account that owns the table you created. Finally, create a new application, selecting the "Web Application [JSF, ADF BC]" template in the directory of your choice:
In your newly created application, you should have two projects - "Model" and "ViewController." The next step is to create some ADF Business Components for the my_emp table. In this example, we'll just create some basic stuff (a single Entity Object, a default editable View Object, and a default Application Module). To do this, right-click the Model project and choose "New..." In the dialog that appears, choose "ADF Business Components" in the categories pane and "Business Components from Tables" in the items pane:
You'll be prompted to initialize your project for business components. Pick the connection you created earlier (and the SQL flavor and type map if you are not using an Oracle database) and click "OK." Now, you'll quickly walk through the wizard to create the default business components. Click "Next" to dismiss the welcome screen, if it is shown. On the next screen, type "my_emp" in the name filter and press "Query" to display the table you created earlier; use the shuttle controls to add the MY_EMP table to the selected list:
Click "Next" to display the "Updatable View Objects" page of the wizard; use the shuttle controls to add the MyEmp Entity Object to the selected list:
From here on out, we will just be taking the defaults for the wizard, so you can click "Finish." If you'd like to see the steps one-by-one, you can click "Next" on each page to see them. Once you are done, you will have a single Entity Object called "MyEmp," an updatable View Object called "MyEmpView," and an Application Module called "AppModule," which has MyEmpView in its data model. You can see these objects by expanding the folders under the Model project in the Applications Navigator. To make things a bit easier down the road, let's set a default for the employee type to "H" for hourly. To do this, double-click on the MyEmp entity object. In the dialog that appears, expand the Attributes tree on the left side and click the "EmpType" attribute. Now, in the right pane, enter "H" into the default value field and press "OK" when done:
That's it for the data model; in real life, you'd of course give some nice attribute names, display hints, etc, etc, but I'll leave that to you. The next step for this exercise is to create the JSF pages. We will first create a simple list-type page that lists the employees and allows us to select an employee to edit or to create a new employee. To do this, right-click the "ViewController" project and select "New..." In the dialog that appears, select "JSF" from the categories pane and JSF JSP from the items pane. Click "Next" to dismiss the welcome page, if it is shown; this will display the "JSP File" step of the wizard. Let's call our page "emplist.jspx" Make sure the "JSP Document" radio button is selected for the document type:
Click "Next" to display the component binding page. As we do not need component bindings, click "Next" to display the tag libraries page. Ensure that you have the 4 libraries selected as shown here:
Now, you can click "Finish" to complete the wizard. While we are at it, follow the same steps to create an "empedit.jspx" page. Now, let's finish the emplist page - it's the simpler of the two. To create an ADF Faces table, go to the Data Control Palette window in JDeveloper. You should see a single data control called "AppModuleDataControl." Expand the data control, and you'll find your single view object, "MyEmpView1." Ensure that you have the emplist.jspx page open in the visual editor and drag the "MyEmpView1" view object on to the emplist.jspx page. In the pop-up menu that appears, select the "Tables" menu and then the "ADF Read-only" table from the sub-menu. Ensure that you click the "Enable Selection" checkbox and click "OK." You'll now see the af:table added to your page. If you run the page now, you'll see an empty table because there are no rows in the database.
Next, let's add "Edit" and "New Employee" buttons to the page. First, get rid of the "Submit" button that JDeveloper created for you automatically by selecting it and hitting the Delete key. The "Edit" button that we are going to add must be inside of the af:tableSelectOne object that exists inside of the "selection" facet of the table. My preferred way to drag-and-drop components is to use the structure window in JDeveloper, because it gives me the most precision. So, expand the items in the structure window until you get to the af:tableSelectOne object (you can also click on the radio buttons in the "Select" column of the table to do this automatically):
Now, find the Control Palette window in JDeveloper. Select "ADF Faces Core" from the drop-down at the top of the palette and find the "CommandButton" component. Drag this component and drop it into the af:tableSelectOne on your page. If you've done it correctly, you'll se an af:commandButton inside of the af:tableSelectOne in the structure window, and your page will look like this:
Use the Property Inspector window of JDeveloper to change the text of the button to "Edit." Now, let's add the "New Employee" button. Because the "New Employee" button does not require an employee to be selected first, it doesn't belong in the selection facet of the table, but the "actions" facet. First, make sure that you can see the actions facet in JDeveloper's structure window; secondly, in the Data Control Palette, expand the AppModuleDataControl, the EmpView1, and the Operations folder. Find the "Create" operation and drag it into the actions facet, using the structure window. In the pop-up window that appears when you release the mouse, select ADF Command Button. You can now use the property inspector to change the text of the command button to "New Employee."
Now, without going into a long explanation of why (read the docs if you must), we need to change the binding on the "New Employee" button from the "Create" action to "CreateInsert." To do this, right-click in a blank area of the emplist.jspx page and choose "Go To Page Definition." Using the structure window, expand the bindings folder and double-click on the "Create" binding. In the window that appears, change the action from "Create" to "CreateInsert:"
Now, save and close the page binding. The final piece of work we need to do on this page is to set up some navigation cases so that we can navigate back and forth between the list and edit pages. I'm not going to walk through all of the steps here (a quick read of the docs should set you in the right direction). Create two navigation cases, one going from emplist.jspx to empedit.jspx called "edit" and one going from empedit.jspx to emplist.jspx called "returntolist." Here's what my faces-config.xml navigation diagram looked like after this step:
Wow - this is more steps than I thought.... continued in part deux.
Wednesday, May 23, 2007
Don't mix glue and SQL
This post isn't really related to ADF in particular, but it is of benefit. I've seen a number of posts (well, OK 2 of them) on the Oracle JDeveloper forum in the past week where someone "glues" literals into their SQL statements like this:
String sqlStmt = "select x from y where username='" + userName + "'";
stmt = new PreparedStatement(sqlStmt, 0);
//etc
Now, anyone who reads Ask Tom is already falling out of their chair. The real problem is in the first line of code; first of all, imagine what happens if someone puts this string into userName: x' or '1' = '1
Can you say "SQL Injection?" The second problem with this approach is that for each value of userName, this generates a unique SQL statement, which Oracle has never seen before, and must hard parse. Hard parsing in Oracle, well in most any database, really, is an operation that takes lots of CPU and inherently limits scalability. If you run this query a lot with different values of userName, you'll bring the system to it's knees. What the query should do is use binds, like this:
String sqlStmt = "select x from y where username= :1";
stmt = new PreparedStatement(sqlStmt, 0);
stmt.setString(1, userName);
//etc
/
Now, no matter what that pesky user puts in userName, this code does not expose the security risks as the first one. Additionally, the SQL is the same from call to call (it never changes) - therefore you don't have the hard parsing problem, either. Now to make the code even better, we could cache the prepared statement and bind/execute on subsequent calls, but I'll leave that one to you.
String sqlStmt = "select x from y where username='" + userName + "'";
stmt = new PreparedStatement(sqlStmt, 0);
//etc
Now, anyone who reads Ask Tom is already falling out of their chair. The real problem is in the first line of code; first of all, imagine what happens if someone puts this string into userName: x' or '1' = '1
Can you say "SQL Injection?" The second problem with this approach is that for each value of userName, this generates a unique SQL statement, which Oracle has never seen before, and must hard parse. Hard parsing in Oracle, well in most any database, really, is an operation that takes lots of CPU and inherently limits scalability. If you run this query a lot with different values of userName, you'll bring the system to it's knees. What the query should do is use binds, like this:
String sqlStmt = "select x from y where username= :1";
stmt = new PreparedStatement(sqlStmt, 0);
stmt.setString(1, userName);
//etc
/
Now, no matter what that pesky user puts in userName, this code does not expose the security risks as the first one. Additionally, the SQL is the same from call to call (it never changes) - therefore you don't have the hard parsing problem, either. Now to make the code even better, we could cache the prepared statement and bind/execute on subsequent calls, but I'll leave that one to you.
Friday, May 11, 2007
I just don't get Ruby on Rails
In addition to all of the cool toys (robots and helicopters) shown at the Java Toy Show (general session of JavaOne 2007 on Friday morning), a NetBeans guy from Sun got up and did a demo of Netbeans 6.0 and JRuby on Rails (a scripting-languaged based web application framework). He created a Ruby on Rails application, created persistence classes from a database using a wizard, created a simple web page showing the database information, and ran it all from within the IDE. Judging by the audience reaction, people were impressed. My reaction, on the other hand, was, as we used to say as kids, "big whoop." Haven't we been doing this in JDeveloper for, I dunno, 8 years or something?
Thursday, May 10, 2007
The fun side of JavaOne 2007
There's more to JavaOne than listening to presentations. You could...
View a 3D world:
Watch (and buy for around $300 US) a fully Java-programmable robot with MP3 and MPEG video playback:
Use the Java real-time API's to write a control program for a race car and try to have it be the fastest around the track (without falling off):
I have some video clips of the robot dancing to some music and the race car doing fine, until it falls off the banked turn, but I need to figure out how to post them. More to come...
View a 3D world:
Watch (and buy for around $300 US) a fully Java-programmable robot with MP3 and MPEG video playback:
Use the Java real-time API's to write a control program for a race car and try to have it be the fastest around the track (without falling off):
I have some video clips of the robot dancing to some music and the race car doing fine, until it falls off the banked turn, but I need to figure out how to post them. More to come...
JavaOne 2007: Shay Shmeltzer on "What's new in JDeveloper"
Shay Shmeltzer of Oracle (note the fast hands)
delivered a session today (Thursday) at JavaOne detailing what's new in JDeveloper release 11, which was just released the other day as a technology preview. The session was attended by (my estimate) 150 people:
After talking about the overall purpose of JDeveloper (keep people in the Java fold by providing a productive alternative to .Net), Shay gave a brief overview of version 10.1.3.2 of JDev, and built a nice demo, which of course, did not run. Stupid oranls18.jar!
Then came the exciting stuff. Any omissions or errors in this section are my own... The focus areas for JDeveloper 11 include:
In the demo, one of the things Shay did was to create a simple task flow composed of two JSF page fragments. Just like the simple tutorial we've all done, he created two fragments (instead of pages) - one to list (in an af:table) some items, and another to edit a newly created item. Then, he simply dragged the page flow into one of the declared facets on the JSF page template that he was using. Now, whenever he ran his demo, the list -> edit record -> return to list was rendered in the area of the template, independently of the rest of the page content. This looked to me like it was using PPR, so it was quite responsive. I'm going to have to play with this myself...
Shay covered more detail (obviously) than I've included here, but this looks like a serious new release of JDev. As Lucas Jellema writes, the Rich Client Framework components are being donated to Apache - with such an amazing, high quality set of JSF components available for free, it's going to put a lot of pressure on JSF component vendors.
delivered a session today (Thursday) at JavaOne detailing what's new in JDeveloper release 11, which was just released the other day as a technology preview. The session was attended by (my estimate) 150 people:
After talking about the overall purpose of JDeveloper (keep people in the Java fold by providing a productive alternative to .Net), Shay gave a brief overview of version 10.1.3.2 of JDev, and built a nice demo, which of course, did not run. Stupid oranls18.jar!
Then came the exciting stuff. Any omissions or errors in this section are my own... The focus areas for JDeveloper 11 include:
- Improved IDE
- J2EE 5 support
- Taking JSF to the next level
- Further ADF improvements
- Metadata Management
- Javascript editor/debugger
- SQL Developer integration (try opening a .sql file in JDev 11 - you'll get the SQL Developer window)
- New profilers - it looks like the dependency on Oracle's JVM (ojvm) is removed, and you can profile with a standard JVM.
- JUnit 4 support
- EJB 3 diagramming, dialogs for managing persistence.xml and orm.xml
- JSF 1.2 support
- Web services improvements (JAX-WS, WSDL editor, WS tester, JSF 181 property inspector).
- The new AJAX/Rich Client Framework components (100+ of them)
- Reusability (page templates, page fragments, task flows, declarative components)
- Security
- Graphs (rendered in flash!)
- Dialog/pop-up framework. In my view, much improved over the 10g release - pop-ups are now rendered in the page itself, not in a new browser window - solves a lot of problems.
- Navigation menus. I see JDev 11 has a wizard for creating trees of managed beans instead of forcing us to edit XML by hand - quite nice.
- (not in the technology preview) an "active data framework," described as a push technology for JSF.
- Advanced data streaming - if you have 3 tables on the JSF page, they can populate in parallel - the page render can happen before the data is fully loaded.
In the demo, one of the things Shay did was to create a simple task flow composed of two JSF page fragments. Just like the simple tutorial we've all done, he created two fragments (instead of pages) - one to list (in an af:table) some items, and another to edit a newly created item. Then, he simply dragged the page flow into one of the declared facets on the JSF page template that he was using. Now, whenever he ran his demo, the list -> edit record -> return to list was rendered in the area of the template, independently of the rest of the page content. This looked to me like it was using PPR, so it was quite responsive. I'm going to have to play with this myself...
Shay covered more detail (obviously) than I've included here, but this looks like a serious new release of JDev. As Lucas Jellema writes, the Rich Client Framework components are being donated to Apache - with such an amazing, high quality set of JSF components available for free, it's going to put a lot of pressure on JSF component vendors.
Wednesday, May 09, 2007
And now, for something completely different
By far, my favorite musician is Pepe Kalle He passed away a few years back from heart problems.
He sings in a mixture of language, but mostly a language from Congo (fka Zaire) called "Lingala." I like lingala music in general for it's good harmonic singing and the styles of dancing that go along with it. There are a variety of different music/dance styles, including ndombolo, soukouss, kwassa-kwassa, etc. For a non-African like me (read "dance and rhythm-challenged white guy"), it's still fun. Just don't expect to see me dancing like this at JavaOne, unless his band, or perhaps Kanda Bongo Man shows up.
YouTube is great...
He sings in a mixture of language, but mostly a language from Congo (fka Zaire) called "Lingala." I like lingala music in general for it's good harmonic singing and the styles of dancing that go along with it. There are a variety of different music/dance styles, including ndombolo, soukouss, kwassa-kwassa, etc. For a non-African like me (read "dance and rhythm-challenged white guy"), it's still fun. Just don't expect to see me dancing like this at JavaOne, unless his band, or perhaps Kanda Bongo Man shows up.
YouTube is great...
Thomas Kurian Keynote at JavaOne
Thomas Kurian
did the morning keynote today at JavaOne. He pretty much went over the entire Oracle Middleware stack (Java/BPEL/ESB/WebCenter/Identity Management). There were some really cool demos. Duncan Mills (gotta get his picture) did a demo of the new rich client framework JSF components that come with JDev 11. Let's just say, "you gotta see it for yourself."
It's pretty amazing to see a very responsive, AJAX application with not a lot of coding needed - certainly no hand-written Javascript. I was expecially amazed by the drag-and-drop (drag an item from a list of products and drop it in the shopping cart). Was that really just a browser?
did the morning keynote today at JavaOne. He pretty much went over the entire Oracle Middleware stack (Java/BPEL/ESB/WebCenter/Identity Management). There were some really cool demos. Duncan Mills (gotta get his picture) did a demo of the new rich client framework JSF components that come with JDev 11. Let's just say, "you gotta see it for yourself."
It's pretty amazing to see a very responsive, AJAX application with not a lot of coding needed - certainly no hand-written Javascript. I was expecially amazed by the drag-and-drop (drag an item from a list of products and drop it in the shopping cart). Was that really just a browser?
Tables, Templates, and Task Flows; oh my!
As I mentioned yesterday, I've been "wowed" by some of the new stuff floating around in the JDeveloper 11 preview release that came out the other day. The ADF Faces components (both the new and the old) have some great stuff. I'm also excited to see a true templating capability, which looks to be much better than the old af:region; I haven't had a chance to dive into this yet, so templates is going to have to be a topic for another day.
Another interesting new addition is the concept of an ADF Task Flow. Again, I haven't had the time yet to do a "deep dive," but task flows look to me like the JSF faces-config.xml on steroids - instead of one large faces-config, we can have multiple re-usable adf task flows that can then be pieced together. There's even a new memory scope, the task flow scope, that is longer than request but shorter than session to facilitate this. I'm going to have to spend a bit of time understanding this one before I post the details.
The instant "wow" factor in JDev 11 is the ADF Faces components. In addition to some really cool visualization components (Flash-y graphs, bar charts, gannt charts, etc), the old venerable ADF Faces components have gotten a great face lift. The applications created using JDev 11 have a much more responsive, AJAX-y, Web 2.0 feel. Today, I thought I'd take one of the components I use most often, af:table, and give a preview of how it has changed in this release.
The first thing I noticed is that there is no more selection or actions facet in the table; hmmm, how am I going to perform the typical "select a row and edit it" or "create a new row" buttons? After some poking around the docs, I discovered a new component (find it in the layout section of the control pallete) called "af:panelCollection:"
The af:panelCollection provides a container for af:table that allows for toolbars and menus (!) that allow you to act on the table. After putting one of these on my page, I dragged-and-dropped a view object from the data control pallete as an af:table. The resulting dialog, although similar to the one in 10.1.3.2, has an interesting new checkbox, "Filtering." Wonder what this does.....
Hiding and showing columns is pretty easy too:
Re-ordering columns by dragging and dropping them is supposed to work (I got the nice drag-and-drop effect), but got stuck:
It is a preview release, after all. The next thing I went looking for was the range scrolling. Where is that "next 10, previous 10?" It turns out, you just move the scroll bar; rows are fetched on demand:
That alone is worth the price of admission. The final thing I wanted to show was how to add a CreateInsert item to the menu to support creating a new row in the table. First, I simply dragged and dropped the Create operation from the data control pallete inside of an af:menu in the menus facet of the af:panelCollection:
Next, I needed to change the binding from Create to CreateInsert. Now where is that pageDef? Oh, there it is, hiding in the "bindings" tab of the JSF editor window:
Another interesting new addition is the concept of an ADF Task Flow. Again, I haven't had the time yet to do a "deep dive," but task flows look to me like the JSF faces-config.xml on steroids - instead of one large faces-config, we can have multiple re-usable adf task flows that can then be pieced together. There's even a new memory scope, the task flow scope, that is longer than request but shorter than session to facilitate this. I'm going to have to spend a bit of time understanding this one before I post the details.
The instant "wow" factor in JDev 11 is the ADF Faces components. In addition to some really cool visualization components (Flash-y graphs, bar charts, gannt charts, etc), the old venerable ADF Faces components have gotten a great face lift. The applications created using JDev 11 have a much more responsive, AJAX-y, Web 2.0 feel. Today, I thought I'd take one of the components I use most often, af:table, and give a preview of how it has changed in this release.
The first thing I noticed is that there is no more selection or actions facet in the table; hmmm, how am I going to perform the typical "select a row and edit it" or "create a new row" buttons? After some poking around the docs, I discovered a new component (find it in the layout section of the control pallete) called "af:panelCollection:"
The af:panelCollection provides a container for af:table that allows for toolbars and menus (!) that allow you to act on the table. After putting one of these on my page, I dragged-and-dropped a view object from the data control pallete as an af:table. The resulting dialog, although similar to the one in 10.1.3.2, has an interesting new checkbox, "Filtering." Wonder what this does.....
After ok-ing the dialog, it's time to run and see it. There are so many new things to look at just on this simple page... First of all, selecting an item is just as simple as clicking in some of the blank space in the row. The selected row is automatically highlighted:
This "highlight the selected row" is something that I've seen asked over and over again on the OTN JDeveloper forum, so it's a nice thing. It's not all good, in my opinion; if you look at the screen shot, there's precious little "blank space" to click - it was pretty hard to select the row in this case. It's also a bit less obvious that in 10.1.3 how to select the row; there is no "Select and..." text floating up there on the top.Next up is sorting; just hover the mouse over the column label and:
Nice up-and-down sorting indicators. Right above the column labels is the filtering. Just type a letter in the filter area, press enter, and:Hiding and showing columns is pretty easy too:
Re-ordering columns by dragging and dropping them is supposed to work (I got the nice drag-and-drop effect), but got stuck:
It is a preview release, after all. The next thing I went looking for was the range scrolling. Where is that "next 10, previous 10?" It turns out, you just move the scroll bar; rows are fetched on demand:
That alone is worth the price of admission. The final thing I wanted to show was how to add a CreateInsert item to the menu to support creating a new row in the table. First, I simply dragged and dropped the Create operation from the data control pallete inside of an af:menu in the menus facet of the af:panelCollection:
Next, I needed to change the binding from Create to CreateInsert. Now where is that pageDef? Oh, there it is, hiding in the "bindings" tab of the JSF editor window:
I really like the visual representation showing the relationship among the bindings, executables, and data controls. After double-clicking the Create binding and changing the action to CreateInsert, I set up the partial triggers (so that the table refreshed after I selected the "Create" menu item), and it was time to test. Here's the menu in action:
In summary, I showed some of the great new capabilities of just one (!) of the who-knows-how-many ADF Faces components that are in JDev 11. Over the next days and weeks, I'm going to continue digging in to the new features (the eye candy and the meat) and posting my views here.
Tuesday, May 08, 2007
JavaOne first look
It's mid-afternoon on the first day of JavaOne. Most of the buzz in the keynotes today is around a newly announced JavaFX platform. It's not completely clear yet what it is, but it does have a component called JavaFX Script which looks like it will be pretty cool for creating rich-client type applications.
Oracle, as promised, has released a preview version of JDeveloper 11 on OTN. I've had a chance to look at it, and there's some great stuff to be had, including a bunch of new ADF Faces components that made me sit up and say WOW. Watch this space tomorrow (Wednesday) for some screen shots.
I attended the Ruby-on-Rails session this morning. Ruby-on-rails is a web application framework written completely in the Ruby scripting language. After using Oracle ADF for the past year, I was pretty un-impressed by Ruby. Yes, ADF is Oracle proprietary, but for the ability to create database-centric, good-looking web applications quickly, ADF wins this battle hands-down.
more to come...
Oracle, as promised, has released a preview version of JDeveloper 11 on OTN. I've had a chance to look at it, and there's some great stuff to be had, including a bunch of new ADF Faces components that made me sit up and say WOW. Watch this space tomorrow (Wednesday) for some screen shots.
I attended the Ruby-on-Rails session this morning. Ruby-on-rails is a web application framework written completely in the Ruby scripting language. After using Oracle ADF for the past year, I was pretty un-impressed by Ruby. Yes, ADF is Oracle proprietary, but for the ability to create database-centric, good-looking web applications quickly, ADF wins this battle hands-down.
more to come...
Saturday, May 05, 2007
JavaOne and other musings
After a long hiatus (projects take a lot of time, don't they...), I'm back in the blogging world again. I'll be attending JavaOne next week, and am looking forward to posting lots of information about the new JDeveloper version 11 preview release. It looks to be a tiring conference (who ever heard of conference sessions going until 11:30 pm), but should be lots of good information.
It's been a week of travel for me. Last week, I was in Kenya for the week, then back to London on an overnight flight, off to work for the day, then off to Chicago the next day. On Monday, I'll be leaving for San Francisco, then back to London after the conference. I think I'll need a lot of real world "Java" (aka coffee) to keep me going.
Check back here often next week (during the JavaOne conference) - I hope to be posting once or twice per day.
It's been a week of travel for me. Last week, I was in Kenya for the week, then back to London on an overnight flight, off to work for the day, then off to Chicago the next day. On Monday, I'll be leaving for San Francisco, then back to London after the conference. I think I'll need a lot of real world "Java" (aka coffee) to keep me going.
Check back here often next week (during the JavaOne conference) - I hope to be posting once or twice per day.
Subscribe to:
Posts (Atom)