Hi, I'm trying to hack my way through creating a widget that allows a user to enter labels (like they do on Google Code). I really think I'm going down the wrong track and was just wondering if I could some community input. I know the code sucks... I was just trying to get something working.

I tried using TextFields and Buttons but had trouble because I couldn't capture any of the events so I tried using straight HTML but then I realized that it would look different. Can anyone maybe give me some pointers? This is what I have so far...

Code:
public class LabelsWidget extends BoxComponent {

    private Button addButton;
    private List<String> values;
    private static final int MAX_ROWS = 3;
    private static final int ITEMS_PER_ROWS = 3;

    public LabelsWidget() {
        StringBuffer sb = new StringBuffer();
        sb.append("<table cellpadding='2' cellspacing='2'><tbody>");
        // max MAX_ROWS rows of 3
        for (int i=0; i<MAX_ROWS; i++)
            appendRow(sb, (i!=0));
        sb.append("</tbody></table>");
        setElement(XDOM.create(sb.toString()));
        sinkEvents(Event.ONCHANGE | Event.MOUSEEVENTS);
    }
    
    public void setValues (List<String> values) {
        this.values = values;
        if (isAttached())
            refresh();
    }

    private void refresh() {
        if (null == values) values = new ArrayList<String>(0);
        Element[] rows = el().select("tr");
        int i = 0;
        for (; i<values.size(); i++) {
            String value = values.get(i);
            int rowNum = (i==0)?0:i/ITEMS_PER_ROWS;
            int rowIndex = (i<3)?i:i%(rowNum*ITEMS_PER_ROWS);
            new El(rows[rowNum]).getChild(rowIndex).getChild(0).setValue(value);
            if (i == 0 || i % ITEMS_PER_ROWS == 0) {
                // new row
                El row = new El(rows[rowNum]);
                row.setStyleAttribute("display", "");
            }
        }
    }

    private void revealNewRow() {
        // TODO need to show a row
    }

    private void appendRow(StringBuffer sb, boolean hidden) {
        sb.append("<tr");
        if (hidden)
            sb.append(" style='display: none'");
        sb.append(">");
        appendColumn(sb);
        appendColumn(sb);
        appendColumn(sb);
        sb.append("<td class='action-container'></td>");
        sb.append("</tr>");
    }

    private void appendColumn(StringBuffer sb) {
        sb.append("<td><input type='text' style='width: 75px' maxLength='40'/></td>");
    }

    @Override
    protected void onAttach() {
        super.onAttach();
        addButton = new Button("Add another row");
        addButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
            public void componentSelected(ButtonEvent ce) {
                // I never get here
                revealNewRow();
            };
        });

        // add the button
        int rowIndex = 0;
        El row = new El(el().select("tr")[rowIndex]);
        El buttonCell = row.getChild(ITEMS_PER_ROWS);
        addButton.render(buttonCell.dom);
        refresh();
    }

      @Override
      protected void doAttachChildren() {
        ComponentHelper.doAttach(addButton);
      }

      @Override
      protected void doDetachChildren() {
        ComponentHelper.doDetach(addButton);
      }
}