I want a pair of radio buttons in Vaadin 7 to represent boolean values where each value has a textual display such as "Active" and "Inactive".
Vaadin 7
This Answer addresses Vaadin 7 as asked in the Question. Note that Vaadin 8 makes this much easier. See my other Answer.
OptionGroup
Widget
In Vaadin 7, radio buttons are handled as a single widget, an instance of OptionGroup. The widget contains multiple Items, and if set to single item selection mode, they display as a group of radio buttons.
Item Id versus Item
The tricky part for me was understanding that the commands such as addItem
are a bit of a misnomer. We do not pass full Item
instances. Rather, we pass an object that is to serve as the id of the item.
The addItem
command takes the item id, generates an Item
instance and returns it to you. This is clearly documented, but took a while for me to sink in. You might think you are obligated to track that returned Item. But, no, you can use the item id to later retrieve or compare Items within the OptionGroup.
Since we need not track the returned Items, we can call the addItems
(plural) command to use one line of code to create multiple items for multiple radio buttons.
Boolean As Item Id
In our case, we want to use boolean values as our core data. We need objects rather than boolean
primitives because we are passing around objects. So we use the Boolean
class. Notice that the Boolean class a couple of handy constants: Boolean.TRUE
& Boolean.FALSE
.
These Boolean objects can be used as the item ids.
Example Code
Some example code using Vaadin 7.3.2.
this.activeCustomerRadio = new OptionGroup( "Filter By:" ); // Pass a string used as caption (title) of the group of radio buttons.
this.activeCustomerRadio.addItems( Boolean.TRUE , Boolean.FALSE ); // Pass item ids to be used in constructing Item objects on our behalf.
this.activeCustomerRadio.setItemCaption( Boolean.TRUE , "Active" ); // Specify a textual label rather than default generated value "true" & "false".
this.activeCustomerRadio.setItemCaption( Boolean.FALSE , "Inactive" );
this.activeCustomerRadio.setValue( Boolean.FALSE ); // Specify which radio button is selected by default.
// Add a listener to react to user selection.
this.activeCustomerRadio.addValueChangeListener( new Property.ValueChangeListener()
{
@Override
public void valueChange ( Property.ValueChangeEvent event )
{
Notification.show( "Radio Button" ,
"You chose: " + event.getProperty().getValue().toString() ,
Notification.Type.HUMANIZED_MESSAGE );
}
} );
Lambda Syntax
By the way… In Java 8, you can use the new alternate Lambda syntax. NetBeans 8 will suggest and perform the conversion to lambda syntax if you wish.
this.activeSupplierRadio.addValueChangeListener(( Property.ValueChangeEvent event ) -> {
Notification.show( "Radio Button" ,
"You chose: " + event.getProperty().getValue().toString() ,
Notification.Type.HUMANIZED_MESSAGE );
});
Boolean.true == true
and that the compiler will auto box, can't you just pass true
? What happens if you do? –
Haeckel tl;dr
Much simpler in Vaadin 8.
radios.setItems( Boolean.TRUE , Boolean.FALSE );
…and…
radios.setItemCaptionGenerator( ( ItemCaptionGenerator < Boolean > ) item ->
{
return item ? "Active" : "Inactive"; // Alternate labels.
} );
Vaadin 8
So much easier and more intuitive in Vaadin 8!
Vaadin 8 brings a new simplified data model, leveraging modern features of the Java language to eliminate the Container
interface that wrapped your content in the old data model.
Support for Java Generics means the radio button widget knows the type of your content items. In the case of this Question, that type is the Boolean
class.
RadioButtonGroup < Boolean > radios = new RadioButtonGroup <>( "T/F:" );
Pass objects to be represented by radio buttons
Now we just throw our objects at a widget such as RadioButtonGroup
. In the case of this Question, we throw a pair of Boolean
objects, the predefined constants Boolean.TRUE
and Boolean.FALSE
. Reverse the order of the arguments to change the order of the radio buttons presented to user.
radios.setItems( Boolean.TRUE , Boolean.FALSE );
To pre-select one of the radio buttons, just refer to the desired item object. Here that would be either constant, Boolean.TRUE
or Boolean.FALSE
.
radios.setValue( Boolean.FALSE );
As to the labels we present to the user for each radio button, by default each item object has its toString
method invoked. For us here, that would mean true
and false
would be the text used for the radio button labels.
Generating labels
Our Question here calls for alternate labeling of our radio buttons, such as for localization. So we call setItemCaptionGenerator
and pass a little generator we write to generate a String for each radio button.
Our generator uses the ternary operator, handy for a conditional based on a boolean value. Remember that in the following code, a item
is a Boolean
object.
radios.setItemCaptionGenerator( new ItemCaptionGenerator < Boolean >( )
{
@Override
public String apply ( Boolean item )
{
return item ? "vrai" : "faux"; // French for "true"/"false".
}
} );
Or use lambda syntax.
radios.setItemCaptionGenerator( ( ItemCaptionGenerator < Boolean > ) item ->
{
return item ? "vrai" : "faux"; // French for "true"/"false".
} );
Here is a screen shot of the same Boolean
objects being presented with labels in French.
Specifically requested in the Question, "Active" & "Inactive".
radios.setItemCaptionGenerator( ( ItemCaptionGenerator < Boolean > ) item ->
{
return item ? "Active" : "Inactive"; // Alternate labels.
} );
Respond to user
You may want to respond when the user wants to click a radio button. Add a value change listener. Notice how we are informed as to the object behind the item selected by the user, not the text of the label we generated. The call to event.getValue( )
returns the type Boolean
without the need for casting because of Java Generics – The code here knows that the radio buttons represent Boolean
objects, not mere text.
radios.addValueChangeListener( new HasValue.ValueChangeListener < Boolean >( )
{
@Override
public void valueChange ( HasValue.ValueChangeEvent < Boolean > event )
{
Notification.show(
"User chose: " + event.getValue( ) ,
Notification.Type.TRAY_NOTIFICATION
);
}
} );
Or use lambda syntax.
radios.addValueChangeListener( ( HasValue.ValueChangeListener < Boolean > ) event -> Notification.show(
"User chose: " + event.getValue( ) ,
Notification.Type.TRAY_NOTIFICATION
) );
Entire example
Here is an entire working example, in a single class file.
package com.example.vaadin.radio;
import javax.servlet.annotation.WebServlet;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.HasValue;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.*;
/**
* This UI is the application entry point. A UI may either represent a browser window
* (or tab) or some part of a html page where a Vaadin application is embedded.
* <p>
* The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
* overridden to add component to the user interface and initialize non-component functionality.
*/
@Theme ( "mytheme" )
public class MyUI extends UI
{
@Override
protected void init ( VaadinRequest vaadinRequest )
{
final VerticalLayout layout = new VerticalLayout( );
RadioButtonGroup < Boolean > radios = new RadioButtonGroup <>( "T/F:" );
radios.setItems( Boolean.TRUE , Boolean.FALSE );
radios.setValue( Boolean.FALSE );
radios.setItemCaptionGenerator( ( ItemCaptionGenerator < Boolean > ) item ->
{
return item ? "vrai" : "faux"; // French for "true"/"false".
} );
radios.addValueChangeListener( new HasValue.ValueChangeListener < Boolean >( )
{
@Override
public void valueChange ( HasValue.ValueChangeEvent < Boolean > event )
{
Notification.show(
"User chose: " + event.getValue( ) ,
Notification.Type.TRAY_NOTIFICATION
);
}
} );
layout.addComponent( radios );
setContent( layout );
}
@WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
@VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
public static class MyUIServlet extends VaadinServlet
{
}
}
More info
See the manual for radio buttons.
See the radio button example in the Sampler.
See What's new in Vaadin.
© 2022 - 2024 — McMap. All rights reserved.