Insert row at top of table

I have a table with the following columns: time (String.class), HTML text (Label.class) and a double. The table needs to be in reverse-chronological order so that the newest rows are at the top.

My workaround was to sort the table after every insert. This is fine but it won’t work on a midnight-crossing, like this:

23:59:59
23:59:58
23:59:57
00:00:05 << this should be at the top of the table because it’s newest

What is a better way – such as simply inserting a row at the top of the table without having to do a sort each time?

Here is the code I have:

public String now() {
    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
    Calendar today = Calendar.getInstance();
    return dateFormat.format(today.getTime());
}

public class TestTable extends Table {
    public TestTable() {
        setImmediate(true);

        this.addContainerProperty("time", String.class, "default id");
        this.addContainerProperty("name", Label.class, "default value");
        this.addContainerProperty("price", java.lang.Double.class, -1, null, null, Align.RIGHT);

        Label tf = new Label("Com<b>pu</b>ter<br>The second line wraps", ContentMode.HTML);
        addItem(new Object {now(), tf, 599.90 }, null);

        tf = new Label("Tablet", ContentMode.HTML);
        addItem(new Object {now(), tf, 99.90 }, null);

        tf = new Label("Ph<b>on</b>e", ContentMode.HTML);
        addItem(new Object {now(), tf, 14.5 }, null);

        tf = new Label("Mouse", ContentMode.HTML);
        addItem(new Object {now(), tf, .99 }, null);

        sort(new Object { "time" }, new boolean { false });
    }
}

@Override
protected void init(VaadinRequest request) {
    final VerticalLayout layout = new VerticalLayout();
    setContent(layout);

    final TestTable table = new TestTable();
    layout.addComponent(table);

    Button button = new Button("Insert");
    button.addClickListener(new Button.ClickListener() {
        public void buttonClick(ClickEvent event) {
            Label tf = new Label("Test<b>Value</b>is here", ContentMode.HTML);
            table.addItem(new Object{ now(), tf, 123.45 }, null);
            table.sort(new Object { "time" }, new boolean { false });
        }
    });
    layout.addComponent(button);
}

Thanks in advance.

Curtis

17225.java (2.95 KB)

You can use IndexedContainer’s
addItemAt
.

How about using Date as the type for the time column? You are now trying to sort time based on string value, so your problem is rather inevitable. When using Dates, you can use a Converter or a GeneratedColumn to format the time column.

You could also sort by index by adding a hidden index column with integer type and sorting by it.

That’s an interesting idea – I’ll have to learn more about Converter and GeneratedColumn.

Curtis

Thanks, that does what I need. I had to find a way to access the table’s IndexedContainer. This seems to have worked:

IndexedContainer container = (IndexedContainer)getContainerDataSource(); Then for each of the Label and addItem() lines in the original code, I replaced it with:

Label tf = new Label("Com<b>pu</b>ter<br>The second line wraps", ContentMode.HTML); Object itemID = container.addItemAt(0); Item newRow = container.getItem(itemID); newRow.getItemProperty("time").setValue(now()); newRow.getItemProperty("name").setValue(tf); newRow.getItemProperty("price").setValue(599.90); Of course, this block of code is better when it’s refactored as a function. But it seems to work correctly in my test project.

The sort() call is no longer needed so it was removed.

Thanks for the nudge in the right direction, Joacim.

Curtis