org.primefaces.model.menu.DefaultSubMenu 无法转换为 javax.faces.component.UIComponent
org.primefaces.model.menu.DefaultSubMenu cannot be cast to javax.faces.component.UIComponent
我正在尝试从 PrimeFaces 3.5 升级到 PrimeFaces 4.0,在 3.5 版本上运行良好的代码行是:
private MenuModel modelPrincipal;
private Menubar menuBar;
menuBar.getChildren().addAll(modelPrincipal.getContents());
但是当我升级到4.0版本时,我必须改变它如下:
private org.primefaces.model.menu.DefaultMenuModel modelPrincipal;
private Menubar menuBar;
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
它抛出标题异常,你们知道解决方法吗?我在迁移文档中找不到任何内容 https://github.com/primefaces/primefaces/wiki/Migration-Guide
我也试过:
menuBar.getElements().addAll(modelPrincipal.getElements());
但给了我同样的例外
感谢任何帮助
编辑(最小(这是我可以使代码出现错误的最小值)可重现示例):
这是 PrimeFaces 4.0:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import javax.faces.component.UIComponent;
import org.primefaces.component.menubar.Menubar;
import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultSubMenu;
public class MenuExampleMB {
private org.primefaces.model.menu.DefaultMenuModel modelPrincipal;
private Menubar menuBar;
private HashMap<String, SubMenuItemObject> menuUrlCodigos;
public static void main(String[] args) {
MenuExampleMB menuExampleMB = new MenuExampleMB();
// MenuList
List<MenuObject> menuList = new ArrayList<>();
// SubMenuItemList
List<SubMenuItemObject> subMenuList = new ArrayList<>();
// Add 1 item to the SubMenuItemList
subMenuList.add(new SubMenuItemObject("1", "SubMenu", "an url"));
// MenuObject
MenuObject menu1 = new MenuObject("Menu 1");
// Set the SubMenu list for this MenuObject
menu1.setlSubmenus(subMenuList);
menuList.add(menu1);
// Call method that brings the Exception
menuExampleMB.loadMenu(menuList);
}
public void loadMenu(List<MenuObject> lMenus) {
menuUrlCodigos = new HashMap<String, SubMenuItemObject>();
modelPrincipal = new org.primefaces.model.menu.DefaultMenuModel();
menuBar = new Menubar();
// Go through the list of MenuObject and create each SubMenu and add them to
// DefaultMenuModel
for (MenuObject menu : lMenus) {
DefaultSubMenu subMenu = new DefaultSubMenu();
subMenu = agregarSubmenu(menu.getlSubmenus());
subMenu.setLabel(menu.getTitulo());
modelPrincipal.addElement(subMenu);
}
// This is the one that brings the exception.
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
}
private DefaultSubMenu agregarSubmenu(List<SubMenuItemObject> lSubMenuUsuario) {
DefaultMenuItem menuItem = null;
DefaultSubMenu subMenuPadre = new DefaultSubMenu();
for (SubMenuItemObject subMenuItem : lSubMenuUsuario) {
// Ask if this submenu has sons
if (subMenuItem.getlSubmenus().size() > 0) {
DefaultSubMenu subMenuHijo = new DefaultSubMenu();
subMenuHijo.setLabel(subMenuItem.getTitulo());
/*
* Invoke this method with recursivity to get all the sons of this menu
*
*/
subMenuHijo.getElements().addAll(agregarSubmenu(subMenuItem.getlSubmenus()).getElements());
// Add sons to the father submenu.
subMenuPadre.getElements().add(subMenuHijo);
} else {
// This submenu doesn't have sons so its created as an unique son of the
// father submenu.
menuItem = agregarItem(subMenuItem);
subMenuPadre.getElements().add(menuItem);
subMenuPadre.setLabel(subMenuItem.getTitulo());
}
}
return subMenuPadre;
}
private DefaultMenuItem agregarItem(SubMenuItemObject pSubMenuItem) {
DefaultMenuItem menuItem = new DefaultMenuItem();
menuItem.setValue(pSubMenuItem.getTitulo());
menuItem.setUrl(pSubMenuItem.getUrl());
menuUrlCodigos.put(pSubMenuItem.getUrl(), pSubMenuItem);
return menuItem;
}
}
class MenuObject {
private String titulo;
private List<SubMenuItemObject> lSubmenus = new ArrayList<SubMenuItemObject>();
public MenuObject(String pTitulo) {
titulo = pTitulo;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public List<SubMenuItemObject> getlSubmenus() {
return lSubmenus;
}
public void setlSubmenus(List<SubMenuItemObject> lSubmenus) {
this.lSubmenus = lSubmenus;
}
}
class SubMenuItemObject {
private String codigo;
private String titulo;
private String url;
private List<String[]> lJerarquia;
private List<String> lTabs;
private List<SubMenuItemObject> lSubmenus = new ArrayList<SubMenuItemObject>();
public SubMenuItemObject(String pCodigo, String pTitulo, String pUrl) {
codigo = pCodigo;
titulo = pTitulo;
url = pUrl;
lJerarquia = new ArrayList<String[]>();
}
public SubMenuItemObject() {
}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<SubMenuItemObject> getlSubmenus() {
return lSubmenus;
}
public void setlSubmenus(List<SubMenuItemObject> lSubmenus) {
this.lSubmenus = lSubmenus;
}
public List<String[]> getlJerarquia() {
return lJerarquia;
}
public void setlJerarquia(List<String[]> lJerarquia) {
this.lJerarquia.clear();
this.lJerarquia.addAll(lJerarquia);
}
public List<String> getlTabs() {
return lTabs;
}
public void setlTabs(List<String> lTabs) {
this.lTabs = lTabs;
}
}
class演员
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
是合乎逻辑的,因为模型中的 org.primefaces.model.menu.DefaultMenuItem
元素在任何方面都不是 UIComponent(您可以通过跟踪源代码直到基础 class/interface 来看到这一点)。即使你没有明确地转换它,它也会因同样的错误而失败,但在另一个 class.
的另一行
做
menuBar.getElements().addAll(modelPrincipal.getElements());
同样的原因失败了。如果您检查了 menuBar
中 getElements()
方法中的代码,您会看到
public List getElements() {
MenuModel model = getModel();
if (model != null) {
return model.getElements();
}
else {
return getChildren();
}
}
您甚至可以调试它并看到模型为空,然后 getChildren()
将被返回,实际上以与您第一次尝试相同的调用结束。但是...
您还会在其中看到 getModel()
,这可能是在何处寻找解决方案的提示。 menuBar 有一个 setModel(...)
,您可以在其中设置以编程方式创建的模型。所以解决方案是
menuBar.setModel(modelPrincipal);
如果您以编程方式创建菜单栏。
但大多数情况下它是通过
添加到 xhtml 中的
<p:menu model="#{menuBean.model}" />
一些额外的提示:
- 搜索 "primefaces menu model 4.0 3.5" 得到的结果会给你 help/hints(至少 G00gle 当时向我展示)
- 在 PrimeFaces 7 文档中键入 'menumodel' 会给通用菜单组件中的动态菜单部分一个完整的完整示例提示。 https://primefaces.github.io/primefaces/7_0/#/components/menu
- 在 java 代码或 xhtml 中使用代码完成的 IDE 并检查 api 会显示
setModel
方法或 model
属性。
但我同意,在迁移文档中多一点解释会有所帮助,但当时(至少我从 3.5 迁移到 4 时)论坛等中提到了这一点......所以它是 'actual' 当时
我正在尝试从 PrimeFaces 3.5 升级到 PrimeFaces 4.0,在 3.5 版本上运行良好的代码行是:
private MenuModel modelPrincipal;
private Menubar menuBar;
menuBar.getChildren().addAll(modelPrincipal.getContents());
但是当我升级到4.0版本时,我必须改变它如下:
private org.primefaces.model.menu.DefaultMenuModel modelPrincipal;
private Menubar menuBar;
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
它抛出标题异常,你们知道解决方法吗?我在迁移文档中找不到任何内容 https://github.com/primefaces/primefaces/wiki/Migration-Guide
我也试过:
menuBar.getElements().addAll(modelPrincipal.getElements());
但给了我同样的例外
感谢任何帮助
编辑(最小(这是我可以使代码出现错误的最小值)可重现示例):
这是 PrimeFaces 4.0:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import javax.faces.component.UIComponent;
import org.primefaces.component.menubar.Menubar;
import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultSubMenu;
public class MenuExampleMB {
private org.primefaces.model.menu.DefaultMenuModel modelPrincipal;
private Menubar menuBar;
private HashMap<String, SubMenuItemObject> menuUrlCodigos;
public static void main(String[] args) {
MenuExampleMB menuExampleMB = new MenuExampleMB();
// MenuList
List<MenuObject> menuList = new ArrayList<>();
// SubMenuItemList
List<SubMenuItemObject> subMenuList = new ArrayList<>();
// Add 1 item to the SubMenuItemList
subMenuList.add(new SubMenuItemObject("1", "SubMenu", "an url"));
// MenuObject
MenuObject menu1 = new MenuObject("Menu 1");
// Set the SubMenu list for this MenuObject
menu1.setlSubmenus(subMenuList);
menuList.add(menu1);
// Call method that brings the Exception
menuExampleMB.loadMenu(menuList);
}
public void loadMenu(List<MenuObject> lMenus) {
menuUrlCodigos = new HashMap<String, SubMenuItemObject>();
modelPrincipal = new org.primefaces.model.menu.DefaultMenuModel();
menuBar = new Menubar();
// Go through the list of MenuObject and create each SubMenu and add them to
// DefaultMenuModel
for (MenuObject menu : lMenus) {
DefaultSubMenu subMenu = new DefaultSubMenu();
subMenu = agregarSubmenu(menu.getlSubmenus());
subMenu.setLabel(menu.getTitulo());
modelPrincipal.addElement(subMenu);
}
// This is the one that brings the exception.
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
}
private DefaultSubMenu agregarSubmenu(List<SubMenuItemObject> lSubMenuUsuario) {
DefaultMenuItem menuItem = null;
DefaultSubMenu subMenuPadre = new DefaultSubMenu();
for (SubMenuItemObject subMenuItem : lSubMenuUsuario) {
// Ask if this submenu has sons
if (subMenuItem.getlSubmenus().size() > 0) {
DefaultSubMenu subMenuHijo = new DefaultSubMenu();
subMenuHijo.setLabel(subMenuItem.getTitulo());
/*
* Invoke this method with recursivity to get all the sons of this menu
*
*/
subMenuHijo.getElements().addAll(agregarSubmenu(subMenuItem.getlSubmenus()).getElements());
// Add sons to the father submenu.
subMenuPadre.getElements().add(subMenuHijo);
} else {
// This submenu doesn't have sons so its created as an unique son of the
// father submenu.
menuItem = agregarItem(subMenuItem);
subMenuPadre.getElements().add(menuItem);
subMenuPadre.setLabel(subMenuItem.getTitulo());
}
}
return subMenuPadre;
}
private DefaultMenuItem agregarItem(SubMenuItemObject pSubMenuItem) {
DefaultMenuItem menuItem = new DefaultMenuItem();
menuItem.setValue(pSubMenuItem.getTitulo());
menuItem.setUrl(pSubMenuItem.getUrl());
menuUrlCodigos.put(pSubMenuItem.getUrl(), pSubMenuItem);
return menuItem;
}
}
class MenuObject {
private String titulo;
private List<SubMenuItemObject> lSubmenus = new ArrayList<SubMenuItemObject>();
public MenuObject(String pTitulo) {
titulo = pTitulo;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public List<SubMenuItemObject> getlSubmenus() {
return lSubmenus;
}
public void setlSubmenus(List<SubMenuItemObject> lSubmenus) {
this.lSubmenus = lSubmenus;
}
}
class SubMenuItemObject {
private String codigo;
private String titulo;
private String url;
private List<String[]> lJerarquia;
private List<String> lTabs;
private List<SubMenuItemObject> lSubmenus = new ArrayList<SubMenuItemObject>();
public SubMenuItemObject(String pCodigo, String pTitulo, String pUrl) {
codigo = pCodigo;
titulo = pTitulo;
url = pUrl;
lJerarquia = new ArrayList<String[]>();
}
public SubMenuItemObject() {
}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<SubMenuItemObject> getlSubmenus() {
return lSubmenus;
}
public void setlSubmenus(List<SubMenuItemObject> lSubmenus) {
this.lSubmenus = lSubmenus;
}
public List<String[]> getlJerarquia() {
return lJerarquia;
}
public void setlJerarquia(List<String[]> lJerarquia) {
this.lJerarquia.clear();
this.lJerarquia.addAll(lJerarquia);
}
public List<String> getlTabs() {
return lTabs;
}
public void setlTabs(List<String> lTabs) {
this.lTabs = lTabs;
}
}
class演员
menuBar.getChildren().addAll((Collection<? extends UIComponent>) modelPrincipal.getElements());
是合乎逻辑的,因为模型中的 org.primefaces.model.menu.DefaultMenuItem
元素在任何方面都不是 UIComponent(您可以通过跟踪源代码直到基础 class/interface 来看到这一点)。即使你没有明确地转换它,它也会因同样的错误而失败,但在另一个 class.
做
menuBar.getElements().addAll(modelPrincipal.getElements());
同样的原因失败了。如果您检查了 menuBar
中 getElements()
方法中的代码,您会看到
public List getElements() {
MenuModel model = getModel();
if (model != null) {
return model.getElements();
}
else {
return getChildren();
}
}
您甚至可以调试它并看到模型为空,然后 getChildren()
将被返回,实际上以与您第一次尝试相同的调用结束。但是...
您还会在其中看到 getModel()
,这可能是在何处寻找解决方案的提示。 menuBar 有一个 setModel(...)
,您可以在其中设置以编程方式创建的模型。所以解决方案是
menuBar.setModel(modelPrincipal);
如果您以编程方式创建菜单栏。
但大多数情况下它是通过
添加到 xhtml 中的<p:menu model="#{menuBean.model}" />
一些额外的提示:
- 搜索 "primefaces menu model 4.0 3.5" 得到的结果会给你 help/hints(至少 G00gle 当时向我展示)
- 在 PrimeFaces 7 文档中键入 'menumodel' 会给通用菜单组件中的动态菜单部分一个完整的完整示例提示。 https://primefaces.github.io/primefaces/7_0/#/components/menu
- 在 java 代码或 xhtml 中使用代码完成的 IDE 并检查 api 会显示
setModel
方法或model
属性。
但我同意,在迁移文档中多一点解释会有所帮助,但当时(至少我从 3.5 迁移到 4 时)论坛等中提到了这一点......所以它是 'actual' 当时