2011-04-17 32 views
2

Wicket ListView提供removeLink以添加ListItem。在ListView控件類的源removeLink方法的實現是:添加刪除鏈接到ListView - 如何從內部匿名類中引用外部匿名類

public final Link removeLink(final String id, final ListItem item) 
{ 
    return new Link(id) 
    { 
     private static final long serialVersionUID = 1L; 

     /** 
     * @see org.apache.wicket.markup.html.link.Link#onClick() 
     */ 
     public void onClick() 
     { 
      addStateChange(new Change() 
      { 
       private static final long serialVersionUID = 1L; 

       final int oldIndex = getList().indexOf(item.getModelObject()); 
       final Object removedObject = item.getModelObject(); 

       public void undo() 
       { 
        getList().add(oldIndex, removedObject); 
       } 

      }); 

      item.modelChanging(); 

      // Remove item and invalidate listView 
      getList().remove(item.getModelObject()); 

      ListView.this.modelChanged(); 
      ListView.this.removeAll(); 
     } 
    }; 
} 

現在,如果我一個鏈接添加到列表項和重寫的onClick()方法如上,並添加一些更多的功能吧,我怎麼能重新定義這個片段:

ListView.this.modelChanged(); 
ListView.this.removeAll(); 

作爲ListView的對象實例化是由ListView中的匿名類進行,相同的鏈接。

add(new ListView("listId", list) { 
    protected void populateItem(ListItem item) { 
     item.add(new Link("linkId") { 
      public void onClick() { 
       // how can I define 
       // ListView.this.modelChanged(); 
       // ListView.this.removeAll(); 
       // here? 
      } 
     }); 
    } 
}); 

這是如何從內部匿名類引用外部匿名類?從一般外部類的匿名內部類調用匿名外部類的方法(儘管它是內部的)?在Java中可能嗎?

+0

你試過嗎?它編譯了嗎? – 2011-04-17 17:45:37

+0

@Ravi Wallau不,它沒有編譯。 – 2011-04-17 17:51:45

回答

4

您可以使用Component.findParent(class)

ListView<?> listView = findParent(ListView.class); 
listView.modelChanged(); 
listView.removeAll(); 

或者您也可以撥打super.onClick()onClick()方法。

+0

我在onClick()方法中嘗試了this.getParent()。但它失敗了。並且鏈接擴展了進一步擴展WebMarkupContainer的AbstractLink,超級中沒有onClick()方法。儘管Link的onClick()是抽象的。不是嗎?我怎樣才能調用super.onClick()?怎麼樣從外部類的匿名內部類調用匿名外部類的方法(儘管它是內部的)呢?在Java中可能嗎? – 2011-04-17 18:14:16

+0

@Tapas a)「失敗」是什麼意思?這是一個標準的方法,它總是有效的b)關於超級,我的錯誤,我認爲你是在壓倒removeLink() – 2011-04-18 04:38:46

+0

1)對不起我的錯。因爲我嘗試了返回ListItem的this.getParent(),所以現在我做了(ListView)this.getParent()。getParent(),它工作。此外(ListView)this.findParent(ListView.class)工作正常。所以他們都工作。謝謝。 2)我有一個關於我在第一篇文章中給出的代碼片段的問題。有什麼需要調用listView.removeAll()。添加stateChange到Link之後,我們調用ListItem.modelChanging(),然後移除該項並調用modelChanged(),removeAll()有什麼用? 3)什麼使頁面重新加載?謝謝。 – 2011-04-18 05:32:35

0

簡單的答案是:不要使用嵌套的匿名類。無論如何,它們是閱讀和維護的絕對噩夢。作爲一個經驗法則,如果您的類將在方法體中使用兩個以上的方法或五行以上的代碼,最好將其設置爲適當的命名類。

+2

這在很多情況下都是聲音提示,但對Wicket不切實際。簡單組件的行爲(如文本佔位符或表單組件)通常由父類的重寫方法定義。如果你要爲每一個類創建一個合適的類,那麼即使是簡單的頁面也會有幾十個類。 – perilandmishap 2011-04-17 23:28:12

+0

我在Swing中也使用匿名內部類。我喜歡使用它。 – 2011-04-18 05:36:49

+0

我同意匿名類不應該被過度使用,但像wicket這樣的基於監聽器的框架會變成一個沒有它們的瑣碎類100s的噩夢 – 2011-04-18 08:54:59

2

我相信下面的代碼會工作 - 聲明的變量可以從內部類訪問,只要它們聲明爲final,因此您可以聲明一個變量,該變量包含ListView實例並在內部類中使用它,就像我一樣在下面的例子中。請注意,我沒有編譯這段代碼,但我沒有理由不工作。請記住,變量必須聲明爲final。

add(new ListView("listId", list) { 
    protected void populateItem(ListItem item) { 
     final ListView lv = this; 
     item.add(new Link("linkId") { 
      public void onClick() { 
       lv.modelChange(); 
       lv.removeAll(); 
      } 
     }); 
    } 
}); 
+0

謝謝。您提供的解決方案完美運行所以我想通過這種方式一般我們可以從內部匿名類調用外部匿名類的方法!不是嗎? – 2011-04-18 05:35:18

+0

如果你可以選擇像我那樣聲明變量,那麼是的,這是一個有效的方法。 – 2011-04-18 18:57:51