8

I am trying to override renderer for h:selectBooleanCheckbox (for the reasons explained here):

However, I find it impossible to register my renderer. I have tried declaring it in my faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.SelectBoolean</component-family>
        <renderer-type>javax.faces.Checkbox</renderer-type>
        <renderer-class>com.myapp.CustomCheckboxRenderer</renderer-class>
    </renderer>
</render-kit>

The values I grabbed from:

  • component-family: javax.faces.component.html.HtmlSelectBooleanCheckbox
  • renderer-type: javax.faces.component.html.SelectBooleanCheckboxTag

But it doesn't work.

I also tried verbosely declaring the RenderKit:

<description>Custom renderers</description>
<render-kit-id>???</render-kit-id>
<render-kit-class>com.sun.faces.renderkit.RenderKitImpl</render-kit-class>

But as you can see, I don't really know where to grab value for render-kit-id or if the render-kit-class is correct anyway.

Inside Mojarra package there is file jsf-ri-runtime.xml but it doesn't declare the renderers. It only declares a RenderKitFactory, under which I don't directly find anything of interest.

Pointers?

Tuukka Mustonen
  • 4,722
  • 9
  • 49
  • 79

2 Answers2

12

Your initial <renderer> declaration looks fine, so I tried it here.

package com.myapp;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import com.sun.faces.renderkit.html_basic.CheckboxRenderer;

public class CustomCheckboxRenderer extends CheckboxRenderer {

    public CustomCheckboxRenderer() {
        System.out.println("CustomCheckboxRenderer <init>");
    }

    @Override
    public void decode(FacesContext context, UIComponent component) {
        System.out.println("CustomCheckboxRenderer decode()");
        super.decode(context, component);
    }

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        System.out.println("CustomCheckboxRenderer encodeBegin()");
        super.encodeBegin(context, component);
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        System.out.println("CustomCheckboxRenderer encodeEnd()");
        super.encodeEnd(context, component);
    }

}

It works fine. All get printed to stdout. Your problem lies somewhere else. I was using Mojarra 2.0.3 on Tomcat 7.0.5.

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Unrelated to the problem, why would you ever use non-booleans as value of a `selectBooleanCheckbox`? How can a non-boolean object represent a boolean state? – BalusC Jan 05 '11 at 15:27
  • Hmm, you are right, it does work. I didn't test with the encodeXXX methods before, I just set breakpoint to my custom renderer's `getConvertedValue` method, which doesn't get called. The reason for that might be subject of a completely different question, however. Anyway, do you know if there is a listing for JSF components, their render-types and families somewhere, or do we have to always navigate to their classes and search for these variables? – Tuukka Mustonen Jan 05 '11 at 15:30
  • It's a combination of table 8.1 in JSF 2.0 spec and the [`COMPONENT_FAMILY`](http://download.oracle.com/javaee/5/api/constant-values.html#javax.faces.component.UISelectBoolean.COMPONENT_FAMILY) constant field value in JSF 2.0 API doc. Eventually, chapter 4.1.x of JSF 2.0 spec can be consulted for both. – BalusC Jan 05 '11 at 15:37
  • Excellent. Thank you once again! (although I fear this will not be the last time... :) – Tuukka Mustonen Jan 05 '11 at 16:46
2

I add renderers to my faces-config.xml like so:

<faces-config>
    <!--elided-->
<render-kit>
    <render-kit-id>HTML_BASIC</render-kit-id>
    <renderer>
        <display-name>MyRenderer</display-name>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>foo.MyRenderer</renderer-type>
        <renderer-class>foo.MyRenderer</renderer-class>
        <!-- TODO: attributes for tooling -->

You don't need to (and shouldn't) declare a new render kit class in this scenario.

McDowell
  • 107,573
  • 31
  • 204
  • 267
  • Does one need to declare the `render-kit-id` when overriding the default ones? Seems to work without it... does HTML_BASIC refer to "default" RenderKit? – Tuukka Mustonen Jan 05 '11 at 15:32
  • @Tuukka Mustonen - render-kit-id is optional for the default RenderKit (there is an example in the spec). HTML_BASIC is indeed the default id. – McDowell Jan 05 '11 at 17:29