2012-09-10 44 views
0

我在Primefaces新的,我嘗試使用現在的Primefaces樹了好幾天。 基本上,我有一棵樹。我附加到這棵樹的上下文菜單。當我點擊上下文菜單時,會打開一個對話窗口並顯示有關樹的選定節點的更多詳細信息。我嘗試重現基於Tree和TreeTable示例的primefaces展示。Primefaces 3.4:樹selectedNode是空

當我跑我的項目,我嘗試打開對話窗口,我有這樣的錯誤在調試器:

WARNING: /protected/treeonly.xhtml @34,91 value="#{folderManagedBean.selectedNode.data.name}": Target Unreachable, 'null' returned null 
javax.el.PropertyNotFoundException: /protected/treeonly.xhtml @34,91 value="#{folderManagedBean.selectedNode.data.name}": Target Unreachable, 'null' returned null 

請看以下JSF頁面

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:p="http://primefaces.org/ui"> 
    <h:head> 
     <title>Facelet Title</title> 
    </h:head> 
    <h:body> 

     <h:form id="form"> 

      <!--*********** Context Menu ***********--> 
      <p:contextMenu for="folderTree"> 
       <p:menuitem value="Rename Folder" update="folderPanel" oncomplete="folderDialog.show();" icon="ui-icon-plus"/> 
      </p:contextMenu> 

      <!--*********** Folder Tree ***********--> 
      <p:tree style="border:none;" id="folderTree" value="#{folderManagedBean.root}" var="folder" selectionMode="single" selection="#{folderManagedBean.selectedNode}"> 
       <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"> 
        <h:outputText value="#{folder.name}" /> 
       </p:treeNode> 
      </p:tree> 


      <!--*********** Dialog Box ***********--> 
      <p:dialog header="New Folder" widgetVar="folderDialog" modal="true" resizable="false" 
         showEffect="clip" hideEffect="fold"> 
       <p:outputPanel id="folderPanel"> 
        <h:panelGrid columns="2" cellpadding="4"> 
         <h:outputText value="Folder Name:" /> 
         <p:inputText value="#{folderManagedBean.selectedNode.data.name}"/> 
        </h:panelGrid> 
       </p:outputPanel> 
      </p:dialog> 


     </h:form> 


    </h:body> 
</html> 

這裏託管bean :

@ManagedBean 
@SessionScoped 
public class FolderManagedBean implements Serializable{ 

    @EJB 
    private FolderBean folderBean; 

    private Folder froot; 
    private TreeNode root; 

    private TreeNode selectedNode; 

    public FolderManagedBean() { 
    } 

    @PostConstruct 
    public void initialize(){ 
     root = buildTree(); 
    } 

    public TreeNode getRoot(){ 
     return root; 
    } 


    private TreeNode buildTree(){ 
     froot = folderBean.getRootFolder(); 

     root = new DefaultTreeNode("root", null);  
     TreeNode realRoot = new DefaultTreeNode(froot, root); 

     for (Folder child : froot.getChildFolders()){ 
      TreeNode tnChild = new DefaultTreeNode(child, realRoot); 
      tnChild.setParent(realRoot); 
      buildTreeRecursively(tnChild); 
     }   
     return root;  
    } 

    private void buildTreeRecursively(TreeNode currentNode){ 
     Folder folder = (Folder)(currentNode.getData()); 
     for(Folder child : folder.getChildFolders()){ 
      TreeNode tnChild = new DefaultTreeNode(child, currentNode); 
      tnChild.setParent(currentNode); 

      buildTreeRecursively(tnChild); 
     } 
    } 

    public TreeNode getSelectedNode() { 
     return selectedNode; 
    } 

    public void setSelectedNode(TreeNode selectedNode) { 
     this.selectedNode = selectedNode; 
    } 
} 

任何幫助將非常感激。

+0

請不要發佈**的**所有代碼。只發布相關部分,不相關部分影響可讀性,根本沒有幫助。 – siebz0r

+0

你當然是對的。但是我在尋找這麼多天的解決方案,以至於我不知道什麼是相關或不相關的。謝謝你的評論。 –

回答

1

我期待例外出現在頁面加載。該對話框有一個inputText,它指的是selectedNode。該值在頁面加載時爲空(因爲選擇尚未發生),因此NullPointerException。您的問題有多種解決方案。

最簡單的解決方案是設置<p:dialog dynamic="true"對話框然後訪問僅當訪問對話框的屬性。

更新:您還需要使用AJAX事件處理程序更新select對話框。

<p:tree style="border:none;" id="folderTree" value="#{folderManagedBean.root}" var="folder" selectionMode="single" selection="#{folderManagedBean.selectedNode}"> 
    <p:ajax event="select" update="folderPanel"/> 
    <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"> 
     <h:outputText value="#{folder.name}" /> 
    </p:treeNode> 
</p:tree> 

上下文菜單中的update屬性需要刪除。

+0

我嘗試添加dynamic =「true」。它的工作原理,但只是第一次顯示對話框。其他時間,它只保留以前的值。 –

+0

@CédricChristinaz你需要在選擇發生後更新對話框。查看PrimeFaces的更新屬性;-) – siebz0r

+0

不,頁面加載時不顯示異常。當點擊樹的一個節點時會顯示異常。 –

0

好吧,我終於解決了。 我添加屬性appendToBody="true"到對話框,它的工作原理。屬性dynamic="true"不是必需的。

更新:此解決方案的工作原理,但不是那麼清楚。我不明白屬性appendToBody="true"的目的是什麼。這就是爲什麼,在我看來,上面的解決方案更爲正確。

+0

我不會低估,因爲這看起來有點苛刻,但不要使用'appendToBody'。正如PrimeFaces手冊所述:'小心使用appendToBody作爲頁面定義和html dom會有所不同,對於 示例,如果dialog位於h:form組件內且appendToBody已啓用,則瀏覽器 對話框將位於form和可能會導致意外的結果在這種情況下,在 對話框中嵌套一個表格。相反,看到我的答案,誠實可能是你最好的解決方案。 – siebz0r