CellTable не отображается в TabLayoutPanel

У меня есть класс EntryPoint WebCrawlerOne.java, который содержит TabLayoutPanel, и на одной из вкладок я вызываю CrawlerOne.java, который содержит CellTable. Я много пробовал, но не могу найти никакой ошибки вообще. Я пытался найти соответствующие темы, но все же CellTable не отображается в TabLayoutPanel при запуске проекта.

  1. Я нахожусь в стандартном режиме (используя DOCTYPE html)
  2. с использованием GWT 2.2.4
  3. Укажите высоту TabLayoutPanel в css как .gwt-TabLayoutPanel { height: 100%; }

    CrawlerOne.ui.xml выглядит так: внутри тегов g:HTMLpanel

    Hello,
    <g:Button styleName="{style.important}" ui:field="button" />
    <table cellspacing='0' cellpadding='0' style='width:100%;'>
        <tr>
            <td valign='top'>
                <c:CellTable addStyleNames="{style.cellTable}" ui:field="table"/>
            </td>
        </tr>
    </table>    
    
    <g:TextBox ui:field="box"></g:TextBox>
    <g:Button ui:field="addSite"></g:Button>
    

CrawlerOne.java выглядит так:

public class CrawlerOne extends Composite implements HasText {

interface CrawlerOneUiBinder extends UiBinder<Widget, CrawlerOne> {
}

@UiField
CellTable<Contact> table;

@UiField
Button addSite;

@UiField
TextBox box;

public CrawlerOne() {
    Widget w = new Widget();
    w = onInitialize();
    initWidget(w);    
}

@UiField
Button button;

@UiHandler("button")
void onClick(ClickEvent e) {
    Window.alert("Hello!");
}

public void setText(String text) {
    button.setText(text);
}

public String getText() {
    return button.getText();
}

/**
   * A simple data type that represents a contact with a unique ID.
   */
  private static class Contact {
    private static int nextId = 0;
    private final int id;

    private String site;
    private String document;
    private String pending;

    public Contact(String site, String document, String pending) {
      nextId++;
      this.id = nextId;
      this.site = site;
      this.document = document;
      this.pending = pending;
    }

    public String getDocument() {
        return document;
    }

    public int getId() {
        return id;
    }

    public String getSite() {
        return site;
    }

    public void setSite(String site) {
        this.site = site;
    }

    public String getPending() {
        return pending;
    }
  }

  /**
   * The list of data to display.
   */
private static final List<Contact> CONTACTS = new LinkedList<Contact>(Arrays.asList(
        new Contact("www.google.com", "12", "123"),
        new Contact("www.yahoo.com", "23", "124"),
        new Contact("www.rediff.com", "24", "124"),
        new Contact("www.gmail.com", "23", "124"),
        new Contact("www.facebook.com", "23", "124"),
        new Contact("www.flickr.com", "23", "124"),
        new Contact("www.youtube.com", "45", "125")));

private static final ProvidesKey<Contact> KEY_PROVIDER =
      new ProvidesKey<Contact>() {
        @Override
        public Object getKey(Contact object) {
          return object.getId();
        }
      };

  /**
   * Initialize.
   */
      public Widget onInitialize() {
        table = new CellTable<Contact>(KEY_PROVIDER);
        table.setWidth("100%", true);
        table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

        initTableColumns();

        // Push the data into the widget.
        table.setRowData(CONTACTS);

        // Set table width.
        table.setWidth("100%");

        box = new TextBox();
        box.setText("Enter New Site");

        addSite = new Button("Add Row");
        addSite.addClickHandler(new ClickHandler() {

            @UiHandler("addSite")
            public void onClick(ClickEvent event) {
                // TODO Auto-generated method stub
                try {
                    if(box.getValue()=="") {
                        Window.alert("Error: Invalid Site Value");
                        box.setText("Enter New Site");
                    }
                    else {
                        CONTACTS.add(new Contact(box.getValue(), "23", "127"));
                        table.setRowCount(CONTACTS.size(), true);
                        table.setRowData(CONTACTS);
                        table.redraw();
                    }
                }catch (Exception e) {
                    Window.alert("Exception Error: " + e);
                }   
            }
        });

     // Create the UiBinder.
        CrawlerOneUiBinder uiBinder = GWT.create(CrawlerOneUiBinder.class);
        Widget widget = uiBinder.createAndBindUi(this);

        return widget;
  }

private void initTableColumns() {

    //code to add columns
}}//end of file

и WebCrawlerOne.java выглядит так:

    public class WebCrawlerOne implements EntryPoint {
    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        TabLayoutPanel menu = new TabLayoutPanel(10, Unit.EM);

        menu.add(new CrawlerOne(), "Crawler");
        menu.add(new HTML("This is my page!"), "Page 2");
        menu.selectTab(0);
        RootLayoutPanel.get().add(menu);
    }
  }

Результат выглядит так: введите здесь описание изображения

CellTable отображается при запуске непосредственно из класса EntryPoint. Любая помощь приветствуется. Спасибо!


person Prince    schedule 16.02.2012    source источник


Ответы (1)


Я написал немного, прежде чем понял простой ответ, который, я думаю, вам действительно нужен, поэтому сначала простой ответ, а затем еще несколько вещей, которые нужно учитывать.

Вы создаете новый экземпляр CellTable в файле ui.xml. Это заменяет уже настроенный экземпляр CellTable в onInitialize, что означает, что он не имеет столбцов и поэтому не виден. Вызов uibinder.createAndBind будет выполнен и создаст все виджеты с аннотациями @UiField, если вы не пометите их как уже предоставленные. Два варианта:

  • Отметьте это как предоставленное:

    @UiField(provided = true)
    CellTable<Contact> table;
    
  • Не настраивайте таблицу до тех пор, пока не будет вызвана функция uibinder.createAndBind.

    //...
    Widget widget = uiBinder.createAndBindUi(this);
    table.setWidth("100%", true);
    table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
    
    initTableColumns();
    
    // Push the data into the widget.
    table.setRowData(CONTACTS);
    
    // Set table width.
    table.setWidth("100%");
    

Первый вариант, вероятно, лучше, так что вы можете полностью настроить его, прежде чем что-либо рисовать. Тем не менее, я тоже не тестировал (недостаточно кода для простого тестирования).


Различные LayoutPanels (как правило, вещи, которые реализуют ProvidesResize и RequiresResize) определяют размер своих дочерних элементов на основе любых конкретных правил, которые есть у каждого из них.

Они могут изменять размер только своих прямых дочерних элементов - если им предоставлен дочерний элемент, который не требует изменения размера (например, HTMLPanel), они не выполняют там никакой работы по макету, вместо этого ожидая, что этот контейнер изменит размер своих дочерних элементов так, как он считает нужным.

Таким образом, HtmlPanel и HTML-код, который вы нарисовали в файле ui.xml, скорее всего, помешали TabLayoutPanel правильно передать информацию о макете в CellTable. Если вы не хотите использовать материал макета, то это хорошо - вам нужно будет изменить размер CellTable каким-то другим способом.

И последняя мысль: используйте FireBug или что-то подобное, чтобы убедиться, что дом настроен так, как вы ожидаете. Там вы увидите, что таблица ячеек присутствует, но не имеет никакого содержимого.

person Colin Alworth    schedule 17.02.2012
comment
Большое спасибо! @UiField (при условии = true) отсутствовал. Я удалил его раньше из-за других ошибок, а потом забыл поставить обратно. Большое спасибо! :) - person Prince; 17.02.2012