123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- package com.vaadin.tests.components.table;
-
- import java.io.IOException;
- import java.io.ObjectOutputStream;
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.util.HashMap;
- import java.util.Map;
-
- import com.vaadin.shared.ui.ContentMode;
- import com.vaadin.tests.components.TestBase;
- import com.vaadin.tests.util.TestUtils;
- import com.vaadin.ui.Button;
- import com.vaadin.ui.CheckBox;
- import com.vaadin.ui.Component;
- import com.vaadin.ui.Label;
- import com.vaadin.v7.data.Container;
- import com.vaadin.v7.ui.DefaultFieldFactory;
- import com.vaadin.v7.ui.Field;
- import com.vaadin.v7.ui.Table;
-
- public class EditableTableLeak extends TestBase {
- private final Table table = new Table("ISO-3166 Country Codes and flags");
- private final CheckBox useFieldFactory = new CheckBox(
- "Use a caching TableFieldFactory");
- private final Label sizeLabel = new Label("", ContentMode.HTML);
-
- private long size = 0;
-
- static class DebugUtils {
- private static class ByteCountNullOutputStream extends OutputStream
- implements Serializable {
- private static final long serialVersionUID = 4220043426041762877L;
- private long bytes;
-
- @Override
- public void write(int b) {
- bytes++;
- }
-
- public long getBytes() {
- return bytes;
- }
- }
-
- public static long getSize(Object object) {
- try (ByteCountNullOutputStream os = new ByteCountNullOutputStream()) {
- ObjectOutputStream oos = new ObjectOutputStream(os);
- oos.writeObject(object);
- return os.getBytes();
- } catch (IOException e) {
- e.printStackTrace();
- return 0;
- }
- }
- }
-
- private static class CachingFieldFactory extends DefaultFieldFactory {
- private final Map<Object, Map<Object, Field<?>>> cache = new HashMap<>();
-
- @Override
- public Field<?> createField(Container container, Object itemId,
- Object propertyId, Component uiContext) {
- if (cache.containsKey(itemId)) {
- if (cache.get(itemId) != null
- && cache.get(itemId).containsKey(propertyId)) {
- return cache.get(itemId).get(propertyId);
- }
- }
- Field<?> f = super.createField(container, itemId, propertyId,
- uiContext);
- if (!cache.containsKey(itemId)) {
- cache.put(itemId, new HashMap<Object, Field<?>>());
- }
- cache.get(itemId).put(propertyId, f);
- return f;
- }
-
- }
-
- @Override
- protected void setup() {
- addComponent(useFieldFactory);
- useFieldFactory.addValueChangeListener(event -> {
- if (useFieldFactory.getValue()) {
- table.setTableFieldFactory(new CachingFieldFactory());
- } else {
- table.setTableFieldFactory(DefaultFieldFactory.get());
- }
- });
- addComponent(table);
- table.setEditable(true);
- table.setWidth("100%");
- table.setHeight("170px");
- table.setSelectable(true);
- table.setContainerDataSource(TestUtils.getISO3166Container());
- table.setColumnHeaders("Country", "Code");
- table.setColumnAlignment(TestUtils.iso3166_PROPERTY_SHORT,
- Table.ALIGN_CENTER);
- table.setColumnExpandRatio(TestUtils.iso3166_PROPERTY_NAME, 1);
- table.setColumnWidth(TestUtils.iso3166_PROPERTY_SHORT, 70);
-
- addComponent(sizeLabel);
-
- addComponent(new Button("Show size of the table", event -> {
- table.markAsDirtyRecursive();
- updateSize();
- }));
-
- addComponent(new Button("Select the second row", event -> {
- table.select("AL");
- updateSize();
- }));
- }
-
- private void updateSize() {
- System.gc();
- long newSize = DebugUtils.getSize(table);
- sizeLabel.setValue("Size of the table: " + newSize
- + " bytes<br/>Delta: " + (newSize - size));
- size = newSize;
- }
-
- @Override
- protected String getDescription() {
- return "Table leaks memory while scrolling/selecting when in editable mode";
- }
-
- @Override
- protected Integer getTicketNumber() {
- return 6071;
- }
-
- }
|