Requirement was a component like the existing t:spinner, with the possibilty to configure the steps value of in/decrementation, e.g. it should be possible to work with double values and add/subtract values with decimal places.
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>decspinner</name>
<tag-class>trimatrix.controls.DECSPINNERComponentTag</tag-class>
<attribute>
<name>id</name>
</attribute>
<attribute>
<name>objectbinding</name>
</attribute>
<attribute>
<name>enabled</name>
</attribute>
<attribute>
<name>width</name>
</attribute>
<attribute>
<name>rendered</name>
</attribute>
<attribute>
<name>align</name>
</attribute>
<attribute>
<name>bgpaint</name>
</attribute>
<attribute>
<name>userhint</name>
</attribute>
<attribute>
<name>tooltip</name>
</attribute>
<attribute>
<name>step</name>
</attribute>
</tag>
</taglib>
2., Creating Component and ComponentTag class files
Code:
package trimatrix.controls;
import org.eclnt.jsfserver.elements.BaseComponentTag;
public class DECSPINNERComponentTag extends BaseComponentTag {
public void setObjectbinding(String value) {
m_attributes.put("objectbinding", value);
}
public void setEnabled(String value) {
m_attributes.put("enabled", value);
}
public void setWidth(String value) {
m_attributes.put("width", value);
}
public void setRendered(String value) {
m_attributes.put("rendered", value);
}
public void setAlign(String value) {
m_attributes.put("align", value);
}
public void setUserhint(String value) {
m_attributes.put("userhint", value);
}
public void setTooltip(String value) {
m_attributes.put("tooltip", value);
}
public void setBgpaint(String value) {
m_attributes.put("bgpaint", value);
}
public void setStep(String value) {
m_attributes.put("step", value);
}
}
Code:
package trimatrix.controls;
import java.io.IOException;
import javax.faces.context.FacesContext;
import org.eclnt.jsfserver.elements.BaseActionComponent;
import org.eclnt.jsfserver.elements.BaseComponent;
import org.eclnt.jsfserver.elements.impl.BEANPROCESSINGComponentTag;
import org.eclnt.jsfserver.elements.impl.BEANPROPERTYSETTERComponentTag;
import org.eclnt.jsfserver.elements.impl.BUTTONComponentTag;
import org.eclnt.jsfserver.elements.impl.FORMATTEDFIELDComponentTag;
import trimatrix.utils.Helper;
public class DECSPINNERComponent extends BaseActionComponent {
transient BaseComponent field;
transient BaseComponent buttonPlus;
transient BaseComponent buttonMinus;
transient BaseComponent setter;
transient BaseComponent processor;
@Override
public void encodeBegin(FacesContext context) throws IOException {
if(getChildren().size() == 0) {
// pick component's own attributes
String objectbinding = getAttributeString("objectbinding");
String width = getAttributeString("width");
String enabled = getAttributeString("enabled");
String rendered = getAttributeString("rendered");
String align = getAttributeString("align");
String bgpaint = getAttributeString("bgpaint");
String userhint = getAttributeString("userhint");
String tooltip = getAttributeString("tooltip");
String step = getAttributeString("step");
if(!Helper.isEmpty(objectbinding)) objectbinding = objectbinding.replace('}', '.');
// create field component
FORMATTEDFIELDComponentTag fct = new FORMATTEDFIELDComponentTag();
fct.setId(createSubId());
if(!Helper.isEmpty(objectbinding)) fct.setValue(objectbinding + "value}");
fct.setWidth(width);
fct.setFormat("double");
fct.setEnabled(enabled);
fct.setRendered(rendered);
fct.setBgpaint(bgpaint);
fct.setAlign(align);
fct.setUserhint(userhint);
fct.setTooltip(tooltip);
field = fct.createBaseComponent();
getChildren().add(field);
// create property setter
BEANPROPERTYSETTERComponentTag bpsct = new BEANPROPERTYSETTERComponentTag();
bpsct.setId(createSubId());
bpsct.setProperty(objectbinding + "step}");
bpsct.setValue(step);
setter = bpsct.createBaseComponent();
// create bean processor
BEANPROCESSINGComponentTag bpct = new BEANPROCESSINGComponentTag();
bpct.setId(createSubId());
processor = bpct.createBaseComponent();
processor.getChildren().add(setter);
getChildren().add(processor);
// create max button
BUTTONComponentTag bct1 = new BUTTONComponentTag();
bct1.setId(createSubId());
bct1.setText("+");
bct1.setEnabled(enabled);
bct1.setRendered(rendered);
bct1.setContentareafilled("false");
bct1.setFont("size:16;weight:bold");
bct1.setFocusable("false");
if(!Helper.isEmpty(objectbinding)) bct1.setActionListener(objectbinding + "increment}");
buttonMinus = bct1.createBaseComponent();
getChildren().add(buttonMinus);
// create min button
BUTTONComponentTag bct2 = new BUTTONComponentTag();
bct2.setId(createSubId());
bct2.setText("-");
bct2.setEnabled(enabled);
bct2.setRendered(rendered);
bct2.setContentareafilled("false");
bct2.setFont("size:16;weight:bold");
bct2.setFocusable("false");
if(!Helper.isEmpty(objectbinding)) bct2.setActionListener(objectbinding + "decrement}");
buttonPlus = bct2.createBaseComponent();
getChildren().add(buttonPlus);
}
}
@Override
public void encodeChildren(FacesContext context) throws IOException {
field.encodeBegin(context);
field.encodeEnd(context);
buttonMinus.encodeBegin(context);
buttonMinus.encodeEnd(context);
buttonPlus.encodeBegin(context);
buttonPlus.encodeEnd(context);
setter.encodeBegin(context);
setter.encodeEnd(context);
processor.encodeBegin(context);
processor.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.DECSPINNERComponent</component-type>
<component-class>trimatrix.controls.DECSPINNERComponent</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:decspinner" />
</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 javax.faces.event.ActionEvent;
import org.apache.commons.lang.math.NumberUtils;
public class DecSpinner {
private double value;
public double getValue() {return value;}
public void setValue(double value) {
this.value = value;
}
private Double step;
public String getStep() {return step.toString();}
public void setStep(String step) {
if(NumberUtils.isNumber(step)) {
this.step = Double.valueOf(step);
} else {
this.step = new Double(0);
}
}
public void increment(ActionEvent event) {
if(step==null) return;
value += step;
}
public void decrement(ActionEvent event) {
if(step==null) return;
value -= step;
}
}
8., Implementation in beanUI
Code:
private DecSpinner weight = new DecSpinner();
public DecSpinner getWeight() {
return weight;
}
Then set the objectbinding property to this object
9., You're done ;-)