【问题标题】:How to override h:selectOneRadio renderer? Where is the renderer class in jsf-impl?如何覆盖 h:selectOneRadio 渲染器? jsf-impl 中的渲染器类在哪里?
【发布时间】:2013-08-22 19:35:49
【问题描述】:

是否可以覆盖<h:selectOneRadio> 使用的渲染器?我试图从 JSF 2.2 的 jsf-impl 包中找到该类,但没有找到。我想这样做的原因是摆脱它生成的表。

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    是否可以覆盖 h:selectOneRadio 使用的渲染器?

    是的,确实如此。否则,像 PrimeFaces 这样的 UI 组件库就无法存在。


    我试图从 jsf-impl 包中找到该类,但没有找到。

    确切的类取决于您使用的 JSF 实现。如果是 Mojarra,那么它就是 com.sun.faces.renderkit.html_basic.RadioRenderer 类。如果是 MyFaces,那么它就是 org.apache.myfaces.renderkit.html.HtmlRadioRenderer 类。

    为了正确覆盖它,只需扩展类并在必要时覆盖方法,并在您的faces-config.xml 中注册如下:

    <render-kit>
        <renderer>
            <component-family>javax.faces.SelectOne</component-family>
            <renderer-type>javax.faces.Radio</renderer-type>
            <renderer-class>com.example.MyRadioRenderer</renderer-class>
        </renderer>
    </render-kit>
    

    请记住,您通过这种方式将渲染器与特定的 JSF impl/version 紧密耦合。这样的扩展渲染器与不同的 JSF 实现不兼容(即,当您将 Mojarra 替换为 MyFaces 时,您的应用程序将不会部署),并且可能会在当前 JSF 实现更新到较新版本时中断。如果您担心这一点,请考虑完全从头开始编写渲染器,例如 PrimeFaces 等。做。


    我想这样做是为了摆脱它生成的表。

    考虑查看TomahawkPrimeFaces 而不是重新发明轮子。它们分别有一个&lt;t:selectOneRadio layout="spread"&gt;&lt;t:radio&gt;&lt;p:selectOneRadio layout="custom"&gt;&lt;p:radioButton&gt;,可以让你将这些东西放在你想要的任何地方。

    另见:

    【讨论】:

      【解决方案2】:

      我加了

        <render-kit>
              <renderer>
                  <component-family>javax.faces.SelectOne</component-family>
                  <renderer-type>javax.faces.Radio</renderer-type>
                  <renderer-class>com.sial.ecommerce.configurator.ui.model.RadioRendererWithoutDataTable</renderer-class>
              </renderer>
          </render-kit>
      

      faces-config.xml

      并创建了一个扩展 com.sun.faces.renderkit.html_basic.RadioRenderer 的类,我确实重写了 encodeEnd 方法,然后注释掉了添加 table 元素的代码。

      public class RadioRendererWithoutDataTable extends com.sun.faces.renderkit.html_basic.RadioRenderer {
          @Override
          public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
      
              rendererParamsNotNull(context, component);
      
              if (!shouldEncode(component)) {
                  return;
              }
      
              ResponseWriter writer = context.getResponseWriter();
              assert (writer != null);
      
              String alignStr;
              Object borderObj;
              boolean alignVertical = false;
              int border = 0;
      
              if (null != (alignStr = (String) component.getAttributes().get("layout"))) {
                  alignVertical = alignStr.equalsIgnoreCase("pageDirection");
              }
              if (null != (borderObj = component.getAttributes().get("border"))) {
                  border = (Integer) borderObj;
              }
      
              Converter converter = null;
              if (component instanceof ValueHolder) {
                  converter = ((ValueHolder) component).getConverter();
              }
      
      //      renderBeginText(component, border, alignVertical, context, true);
      
              Iterator<SelectItem> items = RenderKitUtils.getSelectItems(context, component);
      
              Object currentSelections = getCurrentSelectedValues(component);
              Object[] submittedValues = getSubmittedSelectedValues(component);
              Map<String, Object> attributes = component.getAttributes();
              OptionComponentInfo optionInfo = new OptionComponentInfo((String) attributes.get("disabledClass"),
                      (String) attributes.get("enabledClass"), (String) attributes.get("unselectedClass"),
                      (String) attributes.get("selectedClass"), Util.componentIsDisabled(component), isHideNoSelection(component));
              int idx = -1;
              while (items.hasNext()) {
                  SelectItem curItem = items.next();
                  idx++;
                  // If we come across a group of options, render them as a nested
                  // table.
                  if (curItem instanceof SelectItemGroup) {
                      // write out the label for the group.
                      if (curItem.getLabel() != null) {
      //                  if (alignVertical) {
      //                      writer.startElement("tr", component);
      //                  }
                          //writer.startElement("td", component);
                          writer.writeText(curItem.getLabel(), component, "label");
      //                  writer.endElement("td");
      //                  if (alignVertical) {
      //                      writer.endElement("tr");
      //                  }
      
                      }
      //              if (alignVertical) {
      //                  writer.startElement("tr", component);
      //              }
      //              writer.startElement("td", component);
      //              writer.writeText("\n", component, null);
      //              renderBeginText(component, 0, alignVertical, context, false);
                      // render options of this group.
                      SelectItem[] itemsArray = ((SelectItemGroup) curItem).getSelectItems();
                      for (int i = 0; i < itemsArray.length; ++i) {
                          renderOption(context, component, converter, itemsArray[i], currentSelections, submittedValues, alignVertical, i,
                                  optionInfo);
                      }
      //              renderEndText(component, alignVertical, context);
      //              writer.endElement("td");
      //              if (alignVertical) {
      //                  writer.endElement("tr");
      //                  writer.writeText("\n", component, null);
      //              }
                  } else {
                      renderOption(context, component, converter, curItem, currentSelections, submittedValues, alignVertical, idx, optionInfo);
                  }
              }
      
              //renderEndText(component, alignVertical, context);
          }
      

      然后它对我有用。

      当我给了

      <h:selectOneRadio >
      <f:selectItem itemValue="1" itemLabel="Item 1" />
      <f:selectItem itemValue="2" itemLabel="Item 2" />
      </h:selectOneRadio>
      

      在我的 jsf 页面中。

      转换成

      <input type="radio" name="bulkForm:j_idt224" id="bulkForm:j_idt224:0" value="1"><label for="bulkForm:j_idt224:0"> Item 1</label>
      
      <input type="radio" name="bulkForm:j_idt224" id="bulkForm:j_idt224:1" value="2"><label for="bulkForm:j_idt224:1"> Item 2</label>
      

      这正是我需要的。

      【讨论】:

        猜你喜欢
        • 2012-01-01
        • 2023-03-25
        • 2014-01-31
        • 2017-08-28
        • 2017-06-28
        • 1970-01-01
        • 2018-06-29
        • 2016-05-13
        • 1970-01-01
        相关资源
        最近更新 更多