#java #wicket
#java #калитка
Вопрос:
Wicket ListView предоставляет removeLink для добавления с помощью ListItem. Реализация метода 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();
}
};
}
Теперь, если я добавлю ссылку на ListItem и переопределю метод 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?
Комментарии:
1. Вы пробовали это? Это скомпилировалось?
2. @Ravi Wallau нет, это не компилировалось.
Ответ №1:
Вы можете использовать Component.findParent(class)
:
ListView<?> listView = findParent(ListView.class);
listView.modelChanged();
listView.removeAll();
Или вы могли бы просто вызвать super.onClick()
свой onClick()
метод.
Комментарии:
1. Я попробовал это.getParent() в методе onClick (). Но это не удается. И ссылка extend AbstractLink, которая дополнительно расширяет WebMarkupContainer, в super (ах) нет метода onClick(). Хотя onClick() ссылки является абстрактным. Не так ли? Как я могу вызвать super.onClick()? Как насчет вызова метода анонимного внешнего класса (хотя он и внутренний) из анонимного внутреннего класса этого внешнего класса в целом? Возможно ли это в Java?
2. @Tapas а) что означает «сбой»? Это стандартный метод, и он всегда работает б) насчет super, моя ошибка, я думал, ты переопределяешь removeLink()
3. 1) извините за мою ошибку. Поскольку я попробовал this.getParent (), который возвращал ListItem, так что теперь я сделал (ListView) this.getParent().getParent() и это сработало. Также (ListView) this.findParent(ListView.class ) работал нормально. Итак, оба они сработали. Спасибо. 2) У меня есть вопрос относительно фрагмента кода, который я привел в своем первом сообщении. Зачем вызывать ListView.removeAll(). После добавления StateChange в Link мы вызвали ListItem.modelChanging(), затем удалили элемент и вызвали modelChanged(), какая польза от removeAll()? 3) Что привело к перезагрузке страницы? Спасибо.
4. @Tapas пожалуйста: в комментариях нет вопросов. задайте новый вопрос
Ответ №2:
Я верю, что приведенный ниже код сработает — объявленные переменные доступны из внутреннего класса, если они объявлены окончательными, поэтому вы можете объявить переменную, содержащую экземпляр ListView, и использовать ее из вашего внутреннего класса, как я сделал в примере ниже. Пожалуйста, обратите внимание, что я не компилировал этот код, но я не вижу причин, по которым он не будет работать. Просто помните, что переменная должна быть объявлена окончательной.
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();
}
});
}
});
Комментарии:
1. Спасибо. Предоставленное вами решение сработало отлично. Итак, я предполагаю, что таким образом в общем случае мы можем вызвать метод внешнего анонимного класса из внутреннего анонимного класса! Не так ли?
2. Если у вас есть возможность объявить переменную, как у меня, тогда да, это правильный способ сделать это.
Ответ №3:
Простой ответ: не используйте вложенные анонимные классы. В любом случае, читать и поддерживать их — абсолютный кошмар. Как правило, если ваш класс будет иметь более двух методов или более пяти строк кода в телах методов, лучше сделать его надлежащим именованным классом.
Комментарии:
1. Это разумный совет во многих случаях, но непрактичный с Wicket. Поведение простых компонентов (таких как текстовый заполнитель или компонент формы) часто определяется переопределяющими методами из родительских классов. Если бы вы создали соответствующий класс для каждого из них, у вас были бы десятки классов даже для простых страниц.
2. Я тоже использую анонимный внутренний класс в Swing. И я люблю это использовать.
3. Я согласен, что анонимные классы не должны использоваться чрезмерно, но фреймворк на основе слушателя, такой как wicket, становится кошмаром с сотнями тривиальных классов без них
4. @perilandmishap Обратите внимание, что я не говорил в каждом случае, и я не говорил, что вы должны использовать классы верхнего уровня. Действительно, у анонимного внутреннего класса есть некоторое преимущество перед именованным внутренним классом, но все это теряется в тот момент, когда вы пытаетесь делать нетривиальные вещи.