my dog learned polymorphism*
The moose likes JSF and the fly likes JSF 2.0 - Using Listboxes and Menus Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "JSF 2.0 - Using Listboxes and Menus" Watch "JSF 2.0 - Using Listboxes and Menus" New topic
Author

JSF 2.0 - Using Listboxes and Menus

Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
In my applications I got some listboxes and menus to work with maps correctly, but for some situations this is not sufficient. as with maps you cannot disabled some components, so I'm trying to use List<SelectItem> in my bean, but it will not instantiate.

Here is the xhtml code:

and here is the bean:

The code will read data from a file, as it does already when using maps, so just to save file handling here and keep this test as simple as possible, I'm just simulating a file read by putting data in a couple of string arrays, then copying them to array lists. The string arrays will be removed once this problem is solved.

Basically, when I try and run the applications, I just get the following message on the console:

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.csharp.MyMenuBean.
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)

etc. etc.

Caused by: java.lang.NullPointerException
at com.csharp.MyMenuBean.<init>(MyMenuBean.java:32)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

etc. etc.

Line 32 has the statement: options.add(option);

which is in the second for-loop in the constructor.

Does anybody have any idea what is going wrong here? I've spent quite a lot of time on this and I'm stuck, so help would be most appreciated.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello!

It is right question to me!
NullPointerException indicates that variabe is used after it is assigned to null or only declared without being instantiating before you use it!


True person is moral, false is right!
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
But the point is, why is it doing that? The progam fails on load. I can't see whu there is a NullPointerException.
Ankit Dan
Ranch Hand

Joined: Aug 31, 2012
Posts: 47

options is only a reference not an object that is you are getting
NullPointerException
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

I agree with Ankit Dan!
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
OK, that is helpful, but in any case, when I get stuck I strip down the code. This is what I have now for the xhtml file:

and this is what I have for the bean:

where I have used ArrayList getters only.

Now when I fire up a browser I do indeed get a menu, but on each line is listed all the labels. If I look at the source the JSF has generated, I get this:

so although the individual values are generated, which I want (they all start in lower case), all the labels are listed for each entry (they start with upper case).

How do I now get the code only to display a single label for each line?

Many thanks for any help.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello!

I had almost identical task. And I did everything very easily using SelectItem[] items array for 'value' attribute in f:selectItems:

I need only getter of forumsMenu:

I don't have even variable 'forumsMenu' but only getter 'getForumsMenu'. Next in my JsfUtil I have simple method generated by netbeans itself:

SelectItem constructor takes first parameter as value returned when item is selected and second is label displayed on menu item.
I think it is better approach!!!
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

Synopsis:

1. When using selectOneMenu, you need one or more SelectItems and/or SelectItem lists (or arrays) to hold the definitions for the selectable items. You can define this set of SelectItems either by brute force using View Template Language or by supplying a SelectItem list/array as a property in a backing bean. You can also mix and match. For example, I usually have my "-- Select One --" default selectItem defined in the VTL and the detail items as a backing bean so that I don't have to stuff a dummy element into the backing bean's property list.

2. SelectItem has 2 parts of interest: a label and a value. For the single-element constructor, the argument is set to be both label and value. For the 2-argument constructor, argument 1 is the value, argument 2 is the label. Argument 1 must be convertible to/from a String. Argument 2 must BE a string. The SelectItem is rendered as an HTML <OPTION> element where the value is rendered as the option VALUE= attribute and the label is what displays when the list becomes visible (drops down).

3. A SelectItem or SelectItem list/array property does not need a "set" method, since it's read-only. You do have to initialize this property yourself. JSF will not do it for you, since only you are going to know what items you'll be needing.


Customer surveys are for companies who didn't pay proper attention to begin with.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
Hello,

I have the book "Core JavaServer Faces" 3rd Ed., and I've spent quite a bit of time on this, but I still have problems understanding how to do this, but your description looks very useful.

In the book an example is given in the xhtml code for the following:

where obviously "w" is a JavaScript variable that iterates over itemLabel and itemValue. However, the code in the bean seems to be unnecessarily complicated, as it is in a public static class inside a bean, and there is a private static method that initialized the class. The code seems to be rather converluted and difficult to understand, but does not use the SelectItem[] class.

In my application I will have several menus where I can use maps, these seem to work OK and I have no problems. But I will also have menus where I will want to interact with the items in the menu and change them. One will be a list of 92 chemical elements from hydrogen through to uranium, where you will be able to change abundances of values you are interested in, and as far as I can see, this cannot be done with maps. There are some elements, such as technecium and francium, which I still want listed, but disabled, and again this can't be done with maps.

Anyway, could you kindly give me an example of the bean you mentioned in your posting, and explain what JsfUtil is, which I have never seen before.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
Hi Tim,

I have just seen your posting. Could you kindly give me a specific and simple example to help me get started. i.e. a sample from an xhtml file and the relevant lines in a bean, as I am still confused about this.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19



Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

I use netbeans 7.2 and development on JSF is simplified for me.
I create database and using my database NetBeans itself creates entities, facades(to query database using entities), managed beans (to provide useful technique
of laying out tables with many rows and other stuff). In short NetBeans itself generates everything to provide create,read,update,delete operation for each table inside your own database. Then you can add your own features.
If you are using free Eclipse then I recommend you to move to free NetBeans because it is very good for beginners because of many useful documentation which you can't find in eclipse. I didn't write JsfUtil because it is also generated by NetBeans. OK, I give you this class with superb technique to find jsf component programmatically which I myself found on the Internet:

USE SelectItem[] array as in example given by Tim Holloway. If you provide 'valueChangeListener' on <f:selectItems> you can access every selected item
whenever user selects new one by method getNewValue() and getOldValue of ValueChangeEvent. Also you can disable, enable any item by method setDisable
of SelectItem object
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
OK, many thanks to Tim and Volodymyr, and I will spend the evening going through these code samples, which look very helpful.

I've just come back from a nice break in a park in Lyon, as I needed the break before the sun sets and it gets cold and dark again.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
Hi Tim,

I'm still having a lot of trouble getting my head wrapped around all this, and I have problems understanding what "List<Type> list = this.typeService.findAllTypes();" means amongst other things, and I can't get part of that statement resolved, so I tried something much simpler, but it still does not work.

Here is the part of my xhtml file:

and here is the bean:

As far as I can see, it looks OK, but when I try and run it I get these messages:

java.lang.IllegalArgumentException
at com.sun.faces.renderkit.SelectItemsIterator.initializeItems(SelectItemsIterator.java:216)
at com.sun.faces.renderkit.SelectItemsIterator.hasNext(SelectItemsIterator.java:135)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:762)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderSelect(MenuRenderer.java:844)
etc. etc.

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalArgumentException
at com.sun.faces.renderkit.SelectItemsIterator.initializeItems(SelectItemsIterator.java:216)
at com.sun.faces.renderkit.SelectItemsIterator.hasNext(SelectItemsIterator.java:135)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:762)
etc. etc.

on the server's log without any obvious reason what the problem is, other than there is one.

So far I have not looked much at Volodymyr's code.

Basically I want to get something very simple to work without all the bells and whistles, which can come later.

Incidentally, I'm using Eclipse Indigo, and have never used NetBeans so far.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

You left out the "#" in the EL value expression for your selectItems element. Oops.

With all respect to Volodymir, we don't encourage people to learn how to do things by having an IDE do the work for them. IDE-generated code tends to be unnatural, you probably won't understand what it does or why, and if you take a job in a shop whose IDE standard is different, you're going to be seriously crippled.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
Hi Tim,

I was getting tired and frustrated last night, and it was getting cold with thick fog coming down, so I didn't notice that simple error, and decided to put it on hold until this afternoon.

Many thanks for pointing out the error, which I fixed, and also found a misplaced double quote, which for some reason Eclipse didn't complain about. The application ran straight away and produced the HTML source code:

So now I think I'm nearly 99% of the way there.

The next step is to avoid having anything like "Solar_System" in the case here displayed at the top of the form, the form defaults to 9 entries being displayed, the title and the 8 planets, and need to change that. In the case of the 92 chemical elements I only want 5 or 6 displayed in a window at any one time. I think these changes are quite easy to do.

A bit more of a challenge is to make the form so that you can change any of the values displayed. For example, in my original form I might have something for carbon displayed as:

06 C 8.55

where the number before "C" is the atomic number, and the number afterwards is the relative log10 abundance by number of atoms per cc. In my original JSF 1.2 application I used JavaScript to change the abundance in a regular HTML menu, with the changed values being sent to the server via hidden fields. Obviously I want to avoid using JavaScript with plain HTML and hidden fields, and work directly with JSF menus etc.

As to Volodymir's suggestion of using output generated by an IDE, yes, I will often have trouble understanding the output of an IDE, as it is more general code that covers every situation, and one is likely to get bogged down in some of details without understanding them. Exactly this situation happened a number of years ago when I was asked to look through some Visual C++ code written by some Russians. Quite apart from the comments being written in Russian, which I got solved by asking a Bulgarian friend to translate them, I was not at that time familiar with Visual C++, and a lot of the code I looked through was generated by the IDE.

Anyway, getting back to the subject here, the first method "public static SelectItem[]" looks as if I can use it. However, I had to go to Google to find out what "List<?>" means, which I had never seen before in Java.

My understanding is that SelectItem[] uses (Object, String) pairs as entries, but I will always use either (String, String), or (Integer, String) pairs, so want to avoid the complication of dealing with general objects.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

String and Integer are both subclasses of class Object. You do have to use the same object type for the value part of the SelectItem as you do for the selection value property itself. And that property does have to be something that can be translated to/from a String without the need for an explicit converter. Which is possible for Integer and String.

The way you alter the selection list is to modify the part of the page that contains that list. Although you could do that with JavaScript, you risk running afoul of the selectOneMenu validator. A better/safer solution is to modify the selectItem (model) list itself and re-render all (general form submit) or part (AJAX) of the page.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
I have indeed just managed to alter the list without using JavaScript at all, and also so far without Ajax, although I may use Ajax at some stage. It is completely logical to index the chemical elements with their atomic numbers, using either a string to represent the atomic number, or Integer.

I have been distracted by a party with lots of champagne this afternoon (well this is France!), so will use the weekend to catch up on this project.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
A few days ago I managed to get my application with Listboxes to work in exactly the way I wanted.

The server hosting my original code with JSF 1.2 was down for several days, but is now up and running. If you go to http://phoenix.ens-lyon.fr/simulator/ then click "MODEL SPECTRA", then click the "Continue" button on the lower left of the login page, this will take you to a page where a listbox is displayed, and you can alter the contents. That was all done with JavaScript with the contents of the menu being hard coded.

In my new version, which is not yet online, the contents of the listbox are read in from a file using the methods advised to me, and everthing is now done on the server without using any JavaScript. However, a couple of minor issues have turned up and would appreciate a bit of advice. They are as follows:

1) I cannot find an easy way to align the text in the menu by inserting spaces, so that for example all the numbers are formatted correctly. In my Java bean I tried adding spaces using
String space = " " as well as the two way of representling non-breaking spaces with HTML codes. Although the plain space does indeed line up neatly the characters, when rendered as HTML any additional spaces more than one are ignored, as is normal for HTML. The non-breaking codes do not produce non-breaking spaces, but display in the menu the literals between the quotes. How do I generate non-breaking spaces?

2) In <h:selectOneListbox> I added enabledClass="itemEnabled" then in the CSS I put in .itemEnabled {font-family:monospace;}, which indeed makes the characters monospaced. I tried the same by adding disabledClass="itemDisabled" then in my CSS putting in .itemDisabled {font-family:monospace;}, which is the same. The disabled characters are by default displayed weaker, which is what I want, but how do I change the color, font weight, etc. of these characters? That would be a useful thing to know.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

JSF's View Definition Language (.xhtml) is an XML notation, but it does not pre-define the extra entities that HTML does. So to be able to use the &nbsp; entity, you need to add the following to the top of your View definition:


I'm actually not sure about the "project" part of that, but it seems to be working, since I stole this from an existing webpage definition.

One thing that can be aggravating about formatting dropdown lists is that the ultimate limitations on display formatting are not JSF, but HTML, and the HTML specs appear to indicate style options that aren't actually available on any HTML OPTION element of any browser I know of.

To further frustrate, the SelectItems are implemented via the "f" tagset, which is informational, not display-oriented, so there's no place to hang style information on them in any event.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
Hello Tim,

I tried <!DOCTYPE html [<!ENTITY nbsp "html_code_for_non-breaking_space">]> at the top of my .xhtml page, but it doesn't work when setting space to the non-breaking code, and the literal text is displayed.

This is different from something like <h:outputText value="... text including non-breaking spaces..."/> which is correctly rendered.

Incidentally, I don't know how to make the HTML codes appear here, they are removed in preview and submit mode.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

In JSF2 you can set an "escape" option on SelectItems to keep the nbsp entity from displaying in its raw form.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 152
I've just tried in the SelectItem[] constructor to set the escape flag to true, and that didn't work. I also tried it in the <f:selectItems> tag, and that also didn't work, I always get the raw non-breaking space displayed.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: JSF 2.0 - Using Listboxes and Menus
 
Similar Threads
Argument Error: One or more parameters are null.
f:ajax not working within h:selectOneMenu. Please explain why this super simple example is not work
Instantiating SelectItems from Spring bean
Strange behavior: action method not called when button submitted
problem with SelectOneListbox