2011-04-17 81 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