gpt4 book ai didi

jsf - p :selectOneMenu doesn't render custom content via p:column on List

转载 作者:行者123 更新时间:2023-12-04 13:48:10 36 4
gpt4 key购买 nike

我正在尝试使用 Primefaces 5.2 selectOneMenu 来显示图像及其文件名。这是我的 xhtml 目前的样子:

<h:form>
<h:panelGrid id="createPanelGrid" columns="2">
<p:outputLabel value="Service Logo:" />
<p:selectOneMenu value="#{imageBean.selectedImage}" var="l">
<f:selectItem itemLabel="Select a logo" itemValue="" />
<f:selectItems value="#{imageBean.imageList}" var="logo" itemLabel="#{logo}" itemValue="#{logo}" />
<p:column>
<p:graphicImage value="#{imageBean.imageFolder}/#{l}" style="max-width:50px;max-height:50px;" />
</p:column>
<p:column>#{l}</p:column>
</p:selectOneMenu>
</h:panelGrid>

ManagedBean (imageBean) 具有
public List<String> getImageList () {
List<String> imageList = new ArrayList<String>();
File[] files = absoluteImageFolder.listFiles();
for (File file : files) {
imageList.add(file.getName());
}
return imageList;
}


private String selectedImage;

public String getSelectedImage() {
return selectedImage;
}

public void setSelectedImage(String selectedImage) {
this.selectedImage = selectedImage;
}

但是,图像不会呈现在网页上,只是文件名(我会发布屏幕截图,但我没有足够的声誉)。我没有得到两列(首先是图像,然后是文件名),我只是得到了文件名本身。

当我将文件名字符串包装到 POJO 并使用转换器时,它可以工作 - 但仅使用字符串就不行。

我怎样才能让它只与字符串一起工作?

最佳答案

SelectOneMenuRenderer source code证实了这种尴尬的行为(行号匹配 5.2):

260            if(itemValue instanceof String) {
261 writer.startElement("td", null);
262 writer.writeAttribute("colspan", columns.size(), null);
263 writer.writeText(selectItem.getLabel(), null);
264 writer.endElement("td");
265 }
266 else {
267 for(Column column : columns) {
268 writer.startElement("td", null);
269 renderChildren(context, column);
270 writer.endElement("td");
271 }
272 }

因此,如果项目值是 String 的一个实例, 通过 <p:column> 自定义内容完全被忽略。这确实没有任何意义。直观的期望是自定义内容会因 var 的存在而切换。属性和/或 <p:column> children 。您最好向 PrimeFaces 人员报告问题以解释/改进这一点。

解决方法,除了提供非 String -typed 项值,是覆盖 SelectOneMenuRenderer使用自定义渲染器包装 String在另一个对象中,它恰好在其 toString() 中返回了完全相同的值,例如 StringBuilder .这样渲染器就会被愚弄,认为这些值不是 String 的实例。 .很高兴他们没有检查 instanceof CharSequence .
public class YourSelectOneMenuRenderer extends SelectOneMenuRenderer {

@Override
protected void encodeOptionsAsTable(FacesContext context, SelectOneMenu menu, List<SelectItem> selectItems) throws IOException {
List<SelectItem> wrappedSelectItems = new ArrayList<>();

for (SelectItem selectItem : selectItems) {
Object value = selectItem.getValue();

if (value instanceof String) {
value = new StringBuilder((String) value);
}

wrappedSelectItems.add(new SelectItem(value, selectItem.getLabel()));
}

super.encodeOptionsAsTable(context, menu, wrappedSelectItems);
}

}

为了让它运行,在 faces-config.xml 中注册它如下:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.SelectOneMenuRenderer</renderer-type>
<renderer-class>com.example.YourSelectOneMenuRenderer</renderer-class>
</renderer>
</render-kit>

关于jsf - p :selectOneMenu doesn't render custom content via p:column on List<String>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32735770/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com