Как я могу использовать ComplexPanel с GWT ActivityManager
Я пытаюсь изменить пример кода GWT 2.1 HelloMVP, чтобы использовать более сложный интерфейс. (Я не могу предоставить ссылку из-за ограничения в две ссылки)
Моя проблема в том, что ActivityManager.setDisplay принимает только объекты, которые реализуют AcceptsOneWidget. LayoutPanel и другие ComplexPanel не поддерживают AcceptsOneWidget. В примере кода вместо этого используется SimplePanel. Но я не могу вкладывать сложные виджеты в SimplePanel (они не отображаются).
Я нашел несколько дискуссий по этой проблеме:
Люди предполагают, что решение состоит в том, чтобы создать подкласс ComplexPanel, который я хочу, который реализует интерфейс AcceptsOneWidget. Вот так:
public class PanelForView extends LayoutPanel implements AcceptsOneWidget {
IsWidget myWidget = null;
@Override
public void setWidget(IsWidget w) {
if (myWidget != w) {
if (myWidget != null) {
remove(myWidget);
}
if (w != null) {
add(w);
}
myWidget = w;
}
}
}
Это звучит замечательно, но, похоже, не работает для меня. Возможно, потому что я использую GWT 2.3 вместо 2.1 или 2.2. В моей EntryPoint я ожидаю просто заменить SimplePanel моим новым классом PanelForView и запустить приложение, как раньше. Вот так:
public class HelloMVP implements EntryPoint {
private Place defaultPlace = new HelloPlace("World!");
// private SimplePanel appWidget = new SimplePanel(); // Replace this with PanelForView
private PanelForView appWidget = new PanelForView(); // This compiles but doesn't work.
// private SimpleLayoutPanel appWidget = new SimpleLayoutPanel(); // This doesn't work either.
public void onModuleLoad() {
// Create ClientFactory using deferred binding so we can replace with different
// impls in gwt.xml
ClientFactory clientFactory = GWT.create(ClientFactory.class);
EventBus eventBus = clientFactory.getEventBus();
PlaceController placeController = clientFactory.getPlaceController();
// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);
// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper= GWT.create(AppPlaceHistoryMapper.class);
PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(placeController, eventBus, defaultPlace);
RootPanel.get().add(appWidget);
// Goes to place represented on URL or default place
historyHandler.handleCurrentHistory();
}
}
Это хорошо компилируется, но когда я запускаю его, я не вижу ничего, кроме пустого экрана. Что-то еще, что я должен сделать, чтобы инициализировать ComplexPanel? Я просто что-то недопонимаю? Я попытался добавить виджеты и вызвать setSize безрезультатно. Это мой первый проект GWT.
Спасибо за ваше время.
Corey
3 ответа
Вы должны иметь возможность легко использовать SimplePanel (или подкласс Composite для реализации AcceptsOneWidget). Лучший способ сделать это - подумать о содержащем виджет. Вы можете добавить: HTMLPanel, FlowPanel, VerticalPanel и т. Д. В одну область виджетов SimplePanel.
Однако, как только вы это сделаете, вы сгибаете предполагаемое использование ActivityMapper/AcceptsOneWidget/SimplePanel
Вы можете создать более сложный интерфейс:
Добавление другого ActivityMapper (с другим регионом пользовательского интерфейса - SimplePanel - который должен меняться с места на место) или Добавление области виджета (который не меняется с места на место)
или же*
Сделайте так, чтобы ваш элемент управления Activity представлял собой более сложное представление (оставьте виджет ActivityMapper.setDisplay в виде SimplePanel, но затем установите для Activity значение HTMLPanel, VerticalPanel и т. Д.)
Очень популярная реализация - сохранить SimplePanel в качестве области содержимого для ActivityMapper. Затем используйте UiBinder (с HTMLPanel в качестве элемента верхнего уровня)
Мы можем назвать UiBinder: "просмотр", и он может иметь много регионов
view.getTopArea() - SimplePanel, view.getLeft() - FlowPanel, view.getNameArea - Anchor/InlineHTML
Все эти различные элементы обернуты в поле зрения, которое может быть составным
а затем в вашем
activity.start(AcceptsOneWidget panel){
panel.setWidget(view);//insert your complex view into the SimplePanel view
...
}
Итак, когда у меня возникла эта проблема, я просто экспериментировал с очень простым пользовательским интерфейсом, который поставляется с примером приложения.
Я также попытался сохранить SimplePanel и заставить Activity возвращать HeaderPanel, состоящий из метки и изображения (второй метод, упомянутый в ответе Эштона). Я думал, что это не сработало. И я видел комментарии в блогах и форумах, которые, казалось, указывали, что это не работает. Но как только я начал создавать пользовательский интерфейс с помощью DockPanel, вложенной TabPanel и т. Д., Внезапно все стало отображаться правильно. Я не знаю почему. Наверное, это была ошибка в моем коде. Но я уже в пути. Я не хочу возвращаться и диагностировать точно, что пошло не так.:)
Спасибо за совет, ребята!
Corey