Browse Source

Make initially disabled grid work when enabled (#20240)

Adds API to allow grid to ask its data source if it is waiting for data.
The previous tracking inside grid was not always correct as it relied
on dataAvailable being called.

Change-Id: I0bdb448d9b720155940b0834e118f0eca27a3bfc
tags/7.7.2
Artur Signell 7 years ago
parent
commit
6033e13c20

+ 5
- 0
client/src/main/java/com/vaadin/client/connectors/RpcDataSourceConnector.java View File

droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row)); droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row));
} }
} }

@Override
protected boolean canFetchData() {
return isEnabled();
}
} }


private final RpcDataSource dataSource = new RpcDataSource(); private final RpcDataSource dataSource = new RpcDataSource();

+ 15
- 1
client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java View File

* @return <code>true</code> if waiting for data; otherwise * @return <code>true</code> if waiting for data; otherwise
* <code>false</code> * <code>false</code>
*/ */
@Override
public boolean isWaitingForData() { public boolean isWaitingForData() {
return currentRequestCallback != null; return currentRequestCallback != null;
} }
} }


private void handleMissingRows(Range range) { private void handleMissingRows(Range range) {
if (range.isEmpty()) {
if (range.isEmpty() || !canFetchData()) {
return; return;
} }
currentRequestCallback = new RequestRowsCallback<T>(this, range); currentRequestCallback = new RequestRowsCallback<T>(this, range);
protected boolean isPinned(T row) { protected boolean isPinned(T row) {
return pinnedRows.containsKey(getRowKey(row)); return pinnedRows.containsKey(getRowKey(row));
} }

/**
* Checks if it is possible to currently fetch data from the remote data
* source.
*
* @return <code>true</code> if it is ok to try to fetch data,
* <code>false</code> if it is known that fetching data will fail
* and should not be tried right now.
* @since 7.7.2
*/
protected boolean canFetchData() {
return true;
}
} }

+ 10
- 0
client/src/main/java/com/vaadin/client/data/DataSource.java View File

* means that the row is not currently in this data source's cache. * means that the row is not currently in this data source's cache.
*/ */
public RowHandle<T> getHandle(T row); public RowHandle<T> getHandle(T row);

/**
* Checks whether this data source is currently waiting for more rows to
* become available.
*
* @return <code>true</code> if waiting for data; otherwise
* <code>false</code>
* @since 7.7.2
*/
public boolean isWaitingForData();
} }

+ 5
- 0
client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java View File

} }
}; };
} }

@Override
public boolean isWaitingForData() {
return false;
}
} }

+ 5
- 15
client/src/main/java/com/vaadin/client/widgets/Grid.java View File

Scheduler.get().scheduleDeferred(this); Scheduler.get().scheduleDeferred(this);
} }
} else if (currentDataAvailable.isEmpty() } else if (currentDataAvailable.isEmpty()
&& dataIsBeingFetched) {
&& dataSource.isWaitingForData()) {
// No data available yet but something is incoming soon // No data available yet but something is incoming soon
Scheduler.get().scheduleDeferred(this); Scheduler.get().scheduleDeferred(this);
} else { } else {
private void calculate() { private void calculate() {
isScheduled = false; isScheduled = false;
rescheduleCount = 0; rescheduleCount = 0;
assert !(currentDataAvailable.isEmpty()
&& dataIsBeingFetched) : "Trying to calculate column widths without data while data is still being fetched.";
assert !(currentDataAvailable.isEmpty() && dataSource
.isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched.";


if (columnsAreGuaranteedToBeWiderThanGrid()) { if (columnsAreGuaranteedToBeWiderThanGrid()) {
applyColumnWidths(); applyColumnWidths();


private final Editor<T> editor = GWT.create(Editor.class); private final Editor<T> editor = GWT.create(Editor.class);


private boolean dataIsBeingFetched = false;

/** /**
* The cell a click event originated from * The cell a click event originated from
* <p> * <p>
public void onRowVisibilityChange( public void onRowVisibilityChange(
RowVisibilityChangeEvent event) { RowVisibilityChangeEvent event) {
if (dataSource != null && dataSource.size() != 0) { if (dataSource != null && dataSource.size() != 0) {
dataIsBeingFetched = true;
dataSource.ensureAvailability( dataSource.ensureAvailability(
event.getFirstVisibleRow(), event.getFirstVisibleRow(),
event.getVisibleRowCount()); event.getVisibleRowCount());
} }
}); });


addDataAvailableHandler(new DataAvailableHandler() {
@Override
public void onDataAvailable(DataAvailableEvent event) {
dataIsBeingFetched = false;
}
});
} }


@Override @Override
} }


if (newSize > 0) { if (newSize > 0) {
dataIsBeingFetched = true;
Range visibleRowRange = escalator.getVisibleRowRange(); Range visibleRowRange = escalator.getVisibleRowRange();
dataSource.ensureAvailability(visibleRowRange.getStart(), dataSource.ensureAvailability(visibleRowRange.getStart(),
visibleRowRange.length()); visibleRowRange.length());
Scheduler.get().scheduleFinally(new ScheduledCommand() { Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override @Override
public void execute() { public void execute() {
if (!dataIsBeingFetched) {
if (!dataSource.isWaitingForData()) {
handler.onDataAvailable( handler.onDataAvailable(
new DataAvailableEvent(currentDataAvailable)); new DataAvailableEvent(currentDataAvailable));
} }


@Override @Override
public boolean isWorkPending() { public boolean isWorkPending() {
return escalator.isWorkPending() || dataIsBeingFetched
return escalator.isWorkPending() || dataSource.isWaitingForData()
|| autoColumnWidthsRecalculator.isScheduled() || autoColumnWidthsRecalculator.isScheduled()
|| editor.isWorkPending(); || editor.isWorkPending();
} }

+ 20
- 38
uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java View File



import com.vaadin.data.util.BeanItemContainer; import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.data.bean.Person;
import com.vaadin.ui.Button; import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Grid; import com.vaadin.ui.Grid;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.VerticalLayout;


public class InitiallyDisabledGrid extends UI { public class InitiallyDisabledGrid extends UI {


public static class NotAPersonJustStringAndInt {
private String name;

public NotAPersonJustStringAndInt() {
}

public NotAPersonJustStringAndInt(String string, int i) {
name = string;
age = i;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

private int age;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

@Override @Override
protected void init(VaadinRequest request) { protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout(); VerticalLayout layout = new VerticalLayout();
layout.setSizeFull(); layout.setSizeFull();
layout.setWidth("600px"); layout.setWidth("600px");
layout.setHeight("600px"); layout.setHeight("600px");
final Grid g = createGrid();
Button button = new Button("Sample button");
final Grid grid = createGrid();
Button button = new Button("Enable/Disable", new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
grid.setEnabled(!grid.isEnabled());
}
});


layout.addComponent(button); layout.addComponent(button);
VerticalLayout l = new VerticalLayout(); VerticalLayout l = new VerticalLayout();
l.setSizeFull(); l.setSizeFull();
l.addComponent(g);
l.addComponent(grid);


layout.addComponent(l); layout.addComponent(l);
layout.setExpandRatio(l, 1.0f); layout.setExpandRatio(l, 1.0f);


private Grid createGrid() { private Grid createGrid() {
// Have some data // Have some data
Collection<NotAPersonJustStringAndInt> people = new ArrayList<NotAPersonJustStringAndInt>();
Collection<Person> people = new ArrayList<Person>();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
people.add(new NotAPersonJustStringAndInt("A " + i, i));
Person person = new Person();
person.setFirstName("First " + i);
person.setLastName("Last " + i);
people.add(person);

} }
// Have a container of some type to contain the data // Have a container of some type to contain the data
BeanItemContainer<NotAPersonJustStringAndInt> container = new BeanItemContainer<NotAPersonJustStringAndInt>(
NotAPersonJustStringAndInt.class, people);
BeanItemContainer<Person> container = new BeanItemContainer<Person>(
Person.class, people);


// Create a grid bound to the container // Create a grid bound to the container
Grid grid = new Grid(container); Grid grid = new Grid(container);
grid.setSizeFull(); grid.setSizeFull();
grid.setColumnOrder("name", "age");
grid.setColumns("firstName", "lastName");


grid.setEnabled(false); grid.setEnabled(false);



+ 5
- 0
uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/GridCellFocusOnResetSizeWidget.java View File

} }
handler.resetDataAndSize(size); handler.resetDataAndSize(size);
} }

@Override
public boolean isWaitingForData() {
return false;
}
} }


private class Col extends Grid.Column<String, String[]> { private class Col extends Grid.Column<String, String[]> {

+ 10
- 2
uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java View File

private int numberOfRows; private int numberOfRows;
private DataChangeHandler dataChangeHandler; private DataChangeHandler dataChangeHandler;
private int latency; private int latency;
private Timer timer;


public DelayedDataSource(DataSource<String> ds, int latency) { public DelayedDataSource(DataSource<String> ds, int latency) {
this.ds = ds; this.ds = ds;
@Override @Override
public void ensureAvailability(final int firstRowIndex, public void ensureAvailability(final int firstRowIndex,
final int numberOfRows) { final int numberOfRows) {
new Timer() {
timer = new Timer() {


@Override @Override
public void run() { public void run() {
dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows); dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows);
dataChangeHandler.dataAvailable(firstRowIndex, dataChangeHandler.dataAvailable(firstRowIndex,
numberOfRows); numberOfRows);
timer = null;
} }
}.schedule(latency);
};
timer.schedule(latency);
} }


@Override @Override
// TODO Auto-generated method stub (henrik paul: 17.6.) // TODO Auto-generated method stub (henrik paul: 17.6.)
return null; return null;
} }

@Override
public boolean isWaitingForData() {
return timer != null;
}
} }


@Override @Override

+ 13
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java View File

import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;


import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement;
import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.GridElement.GridCellElement;
import com.vaadin.tests.tb3.SingleBrowserTest; import com.vaadin.tests.tb3.SingleBrowserTest;
Assert.assertTrue(col0.getSize().getWidth() > 250); Assert.assertTrue(col0.getSize().getWidth() > 250);
Assert.assertTrue(col1.getSize().getWidth() > 250); Assert.assertTrue(col1.getSize().getWidth() > 250);
} }

@Test
public void worksWhenEnabled() {
openTestURL();
$(ButtonElement.class).first().click();

GridElement grid = $(GridElement.class).first();
grid.scrollToRow(80);
GridCellElement col0 = grid.getCell(80, 0);
Assert.assertEquals("First 80", col0.getText());
}

} }

Loading…
Cancel
Save