Requirement was a component to make a rating by stars (0 - 5 stars)
I followed the example of MyField in the Developer Guide and had to add some special functions.
1., Creating TLD File (\WEB-INF\trimatrixcontrols.tld)
Code:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlnssi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee webjsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>trimatrixcontrols</short-name>
<uri>/WEB-INF/trimatrixcontrols</uri>
<tag>
<name>star</name>
<tag-class>trimatrix.controls.STARComponentTag</tag-class>
<attribute>
<name>id</name>
</attribute>
<attribute>
<name>objectbinding</name>
</attribute>
<attribute>
<name>enabled</name>
</attribute>
<attribute>
<name>rendered</name>
</attribute>
</tag>
</taglib>
2., Creating Component and ComponentTag class files
Code:
package trimatrix.controls;
import org.eclnt.jsfserver.elements.BaseComponentTag;
public class STARComponentTag extends BaseComponentTag {
public void setObjectbinding(String value) {
m_attributes.put("objectbinding", value);
}
public void setEnabled(String value) {
m_attributes.put("enabled", value);
}
public void setRendered(String value) {
m_attributes.put("rendered", value);
}
}
Code:
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.eclnt.jsfserver.elements.BaseActionComponent;
import org.eclnt.jsfserver.elements.BaseComponent;
import org.eclnt.jsfserver.elements.impl.BUTTONComponentTag;
import trimatrix.utils.Helper;
public class STARComponent extends BaseActionComponent {
private static String WIDTH = "20";
private static int COUNT = 5;
@Override
public void encodeBegin(FacesContext context) throws IOException {
if(getChildren().size() == 0) {
// pick component's own attributes
String objectbinding = getAttributeString("objectbinding");
String enabled = getAttributeString("enabled");
String rendered = getAttributeString("rendered");
if(!Helper.isEmpty(objectbinding)) objectbinding = objectbinding.replace('}', '.');
// create star buttons
for(int i=1;i<=COUNT;i++) {
BUTTONComponentTag bct = new BUTTONComponentTag();
bct.setId(createSubId());
bct.setEnabled(enabled);
bct.setRendered(rendered);
bct.setContentareafilled("false");
bct.setFocusable("false");
bct.setImage(objectbinding + "star" + String.valueOf(i) + "}");
bct.setWidth(WIDTH);
bct.setImagewidth(WIDTH);
if(!Helper.isEmpty(objectbinding)) bct.setActionListener(objectbinding + "onStar" + String.valueOf(i) + "}");
BaseComponent button = bct.createBaseComponent();
getChildren().add(button);
}
}
}
@Override
public void encodeChildren(FacesContext context) throws IOException {
for(UIComponent uc : getChildren()) {
BaseComponent bc = (BaseComponent)uc;
bc.encodeBegin(context);
bc.encodeEnd(context);
}
}
@Override
public void encodeEnd(FacesContext context) throws IOException {}
@Override
public boolean getRendersChildren() {
return true;
}
}
3., Creating \webcontent\eclntserver\config\controllibraries.xml
Code:
<controllibraries>
<controllibrary prefix="tx"
tldfilename="trimatrixcontrols.tld"
packagename="trimatrix.controls"
uri="/WEB-INF/trimatrixcontrols"/>
</controllibraries>
4., Configure \WEB-INF\faces-config.xml added <component> tag
Code:
<component>
<component-type>trimatrix.controls.STARComponent</component-type>
<component-class>trimatrix.controls.STARComponent</component-class>
</component>
5., Create subpackage resources in package where the component classes are (trimatrix.controls.resources) in this package create controlsarrangement.xml
Code:
<controlsarrangement>
<tag name="t:row" below="tx:star" />
</controlsarrangement>
6., Added <controllibraryusage> tag to project.xml like described in the Developer's Guide "Adding own component" page 174 ff.
7., Create class to bundle logic for in-/decrementation
Code:
package trimatrix.controls;
import java.util.BitSet;
import javax.faces.event.ActionEvent;
public class Star {
public Star(int value) {
bitSet = new BitSet();
setValue(value);
}
private BitSet bitSet;
public int getValue() {
return bitSet.length();
}
public void setValue(int value) {
if(getValue()==value) {
bitSet.clear();
} else {
bitSet.clear();
bitSet.set(0, value);
}
}
private String imageOn = "/images/icons/star_full.png";
private String imageOff = "/images/icons/star_none.png";
public String getStar1() { return bitSet.get(0) ? imageOn : imageOff; }
public String getStar2() { return bitSet.get(1) ? imageOn : imageOff; }
public String getStar3() { return bitSet.get(2) ? imageOn : imageOff; }
public String getStar4() { return bitSet.get(3) ? imageOn : imageOff; }
public String getStar5() { return bitSet.get(4) ? imageOn : imageOff; }
public void onStar1(ActionEvent event) {setValue(1);}
public void onStar2(ActionEvent event) {setValue(2);}
public void onStar3(ActionEvent event) {setValue(3);}
public void onStar4(ActionEvent event) {setValue(4);}
public void onStar5(ActionEvent event) {setValue(5);}
}
8., Implementation in beanUI
Code:
private Star fitness = new Star(1);
public Star getFitness() {
return fitness;
}
Then set the objectbinding property to this object
9., You're done ;-)