Change-Id: I3adf9d0cc32f800a535a82ffe5d6ba503a36e746tags/7.5.0.beta1
@@ -165,6 +165,18 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
this.id = id; | |||
} | |||
/** | |||
* Sets a new renderer for this column object | |||
* | |||
* @param rendererConnector | |||
* a renderer connector object | |||
*/ | |||
public void setRenderer( | |||
AbstractRendererConnector<Object> rendererConnector) { | |||
setRenderer(rendererConnector.getRenderer()); | |||
this.rendererConnector = rendererConnector; | |||
} | |||
@Override | |||
public Object getValue(final JsonObject obj) { | |||
final JsonObject rowData = obj.getObject(GridState.JSONKEY_DATA); | |||
@@ -178,16 +190,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
return null; | |||
} | |||
/* | |||
* Only used to check that the renderer connector will not change during | |||
* the column lifetime. | |||
* | |||
* TODO remove once support for changing renderers is implemented | |||
*/ | |||
private AbstractRendererConnector<Object> getRendererConnector() { | |||
return rendererConnector; | |||
} | |||
private AbstractFieldConnector getEditorConnector() { | |||
return editorConnector; | |||
} | |||
@@ -730,13 +732,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
*/ | |||
private void updateColumnFromStateChangeEvent(GridColumnState columnState) { | |||
CustomGridColumn column = columnIdToColumn.get(columnState.id); | |||
updateColumnFromState(column, columnState); | |||
if (columnState.rendererConnector != column.getRendererConnector()) { | |||
throw new UnsupportedOperationException( | |||
"Changing column renderer after initialization is currently unsupported"); | |||
} | |||
} | |||
/** | |||
@@ -780,6 +776,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
* @param state | |||
* The state to get the data from | |||
*/ | |||
@SuppressWarnings("unchecked") | |||
private static void updateColumnFromState(CustomGridColumn column, | |||
GridColumnState state) { | |||
column.setWidth(state.width); | |||
@@ -787,6 +784,9 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
column.setMaximumWidth(state.maxWidth); | |||
column.setExpandRatio(state.expandRatio); | |||
assert state.rendererConnector instanceof AbstractRendererConnector : "GridColumnState.rendererConnector is invalid (not subclass of AbstractRendererConnector)"; | |||
column.setRenderer((AbstractRendererConnector<Object>) state.rendererConnector); | |||
column.setSortable(state.sortable); | |||
column.setEditable(state.editable); | |||
column.setEditorConnector((AbstractFieldConnector) state.editorConnector); |
@@ -3115,12 +3115,14 @@ public class Grid<T> extends ResizeComposite implements | |||
if (renderer == null) { | |||
throw new IllegalArgumentException("Renderer cannot be null."); | |||
} | |||
bodyRenderer = renderer; | |||
if (grid != null) { | |||
grid.refreshBody(); | |||
} | |||
if (renderer != bodyRenderer) { | |||
bodyRenderer = renderer; | |||
if (grid != null) { | |||
grid.refreshBody(); | |||
} | |||
} | |||
return this; | |||
} | |||
@@ -0,0 +1,103 @@ | |||
package com.vaadin.tests.components.grid; | |||
import java.util.List; | |||
import java.util.Random; | |||
import com.vaadin.annotations.Theme; | |||
import com.vaadin.data.Item; | |||
import com.vaadin.data.Property.ValueChangeEvent; | |||
import com.vaadin.data.Property.ValueChangeListener; | |||
import com.vaadin.data.util.IndexedContainer; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.CheckBox; | |||
import com.vaadin.ui.Grid; | |||
import com.vaadin.ui.Grid.Column; | |||
import com.vaadin.ui.Grid.SelectionMode; | |||
import com.vaadin.ui.renderers.HtmlRenderer; | |||
import com.vaadin.ui.renderers.TextRenderer; | |||
@SuppressWarnings("serial") | |||
@Theme("valo") | |||
public class GridSwitchRenderers extends AbstractTestUIWithLog { | |||
private static final int MANUALLY_FORMATTED_COLUMNS = 1; | |||
private static final int COLUMNS = 3; | |||
private static final int ROWS = 1000; | |||
private static final String EXPANSION_COLUMN_ID = "Column 0"; | |||
private IndexedContainer ds; | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
ds = new IndexedContainer() { | |||
@Override | |||
public List<Object> getItemIds(int startIndex, int numberOfIds) { | |||
log("Requested items " + startIndex + " - " | |||
+ (startIndex + numberOfIds)); | |||
return super.getItemIds(startIndex, numberOfIds); | |||
} | |||
}; | |||
{ | |||
ds.addContainerProperty(EXPANSION_COLUMN_ID, String.class, ""); | |||
int col = MANUALLY_FORMATTED_COLUMNS; | |||
for (; col < COLUMNS; col++) { | |||
ds.addContainerProperty(getColumnProperty(col), String.class, | |||
""); | |||
} | |||
} | |||
Random rand = new Random(); | |||
rand.setSeed(13334); | |||
for (int row = 0; row < ROWS; row++) { | |||
Item item = ds.addItem(Integer.valueOf(row)); | |||
fillRow("" + row, item); | |||
item.getItemProperty(getColumnProperty(1)).setReadOnly(true); | |||
} | |||
final Grid grid = new Grid(ds); | |||
grid.setWidth("100%"); | |||
grid.getColumn(EXPANSION_COLUMN_ID).setWidth(50); | |||
for (int col = MANUALLY_FORMATTED_COLUMNS; col < COLUMNS; col++) { | |||
grid.getColumn(getColumnProperty(col)).setWidth(300); | |||
grid.getColumn(getColumnProperty(col)).setRenderer( | |||
new TextRenderer()); | |||
} | |||
grid.setSelectionMode(SelectionMode.NONE); | |||
addComponent(grid); | |||
final CheckBox changeRenderer = new CheckBox( | |||
"SetHtmlRenderer for Column 2", false); | |||
changeRenderer.addValueChangeListener(new ValueChangeListener() { | |||
@Override | |||
public void valueChange(ValueChangeEvent event) { | |||
Column column = grid.getColumn(getColumnProperty(1)); | |||
if (changeRenderer.getValue()) { | |||
column.setRenderer(new HtmlRenderer()); | |||
} else { | |||
column.setRenderer(new TextRenderer()); | |||
} | |||
grid.markAsDirty(); | |||
} | |||
}); | |||
addComponent(changeRenderer); | |||
} | |||
@SuppressWarnings("unchecked") | |||
private void fillRow(String content, Item item) { | |||
int col = MANUALLY_FORMATTED_COLUMNS; | |||
for (; col < COLUMNS; col++) { | |||
item.getItemProperty(getColumnProperty(col)).setValue( | |||
"<b>(" + content + ", " + col + ")</b>"); | |||
} | |||
} | |||
private static String getColumnProperty(int c) { | |||
return "Column " + c; | |||
} | |||
} |
@@ -0,0 +1,84 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.grid; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.testbench.elements.CheckBoxElement; | |||
import com.vaadin.testbench.elements.GridElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class GridSwitchRenderersTest extends MultiBrowserTest { | |||
@Test | |||
public void testRendererSwitch() { | |||
// The UI should start with TEXT rendering in the second column | |||
// Clicking the checkbox will toggle rendering to HTML mode | |||
// Clicking it again should return TEXT rendering mode. | |||
openTestURL(); | |||
GridElement grid = $(GridElement.class).first(); | |||
Assert.assertTrue( | |||
"Initial rendering of column 1 is not unformatted text", | |||
cellTextIsUnformatted(grid.getCell(0, 1).getText())); | |||
// NOTE: must click at 5,5 because of Valo and rendering in Chrome | |||
// This is a TestBench bug that may be fixed sometime in the future | |||
CheckBoxElement cb = $(CheckBoxElement.class).first(); | |||
cb.click(5, 5); | |||
Assert.assertTrue( | |||
"Column 1 data has not been rendered with HTMLRenderer after renderer swap", | |||
cellTextIsHTMLFormatted(grid.getCell(0, 1).getText())); | |||
cb.click(5, 5); | |||
Assert.assertTrue( | |||
"Column 1 data has not been re-rendered as text after renderer swap", | |||
cellTextIsUnformatted(grid.getCell(0, 1).getText())); | |||
} | |||
/** | |||
* Attempts to match a string to a string like {@code <b>(4, 1)</b>}. | |||
* | |||
* @param cellText | |||
* input string | |||
* @return true if input string is formatted like a raw HTML string | |||
*/ | |||
private boolean cellTextIsUnformatted(String cellText) { | |||
String regex = "<b>\\(\\d+, \\d+\\)</b>"; | |||
return cellText.matches(regex); | |||
} | |||
/** | |||
* Attempts to match a string to a string like {@code (4, 1)}, i.e. the HTML | |||
* formatted version of the above (the bold tags should be consumed by the | |||
* renderer). | |||
* | |||
* @param cellText | |||
* input string | |||
* @return true if input string is formatted like plain text (i.e. HTML bits | |||
* have been consumed by renderer) | |||
*/ | |||
private boolean cellTextIsHTMLFormatted(String cellText) { | |||
String regex = "\\(\\d+, \\d+\\)"; | |||
return cellText.matches(regex); | |||
} | |||
} |