private boolean animationsEnabled;
private boolean clearFocusedRowPending;
+ /**
+ * If the container does not send item set change events, always do a full
+ * repaint instead of a partial update when expanding/collapsing nodes.
+ */
+ private boolean containerSupportsPartialUpdates;
+
private ContainerStrategy getContainerStrategy() {
if (cStrategy == null) {
if (getContainerDataSource() instanceof Collapsible) {
@Override
protected boolean isPartialRowUpdate() {
- return toggledItemId != null;
+ return toggledItemId != null && containerSupportsPartialUpdates;
}
@Override
// ensure that page still has first item in page, DON'T clear the
// caches.
setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);
- requestRepaint();
if (isCollapsed(itemId)) {
fireCollapseEvent(itemId);
} else {
fireExpandEvent(itemId);
}
+
+ if (containerSupportsPartialUpdates) {
+ requestRepaint();
+ } else {
+ // For containers that do not send item set change events, always do
+ // full repaint instead of partial row update.
+ refreshRowCache();
+ }
}
@Override
@Override
public void setContainerDataSource(Container newDataSource) {
cStrategy = null;
+
+ containerSupportsPartialUpdates = (newDataSource instanceof ItemSetChangeNotifier);
+
if (!(newDataSource instanceof Hierarchical)) {
newDataSource = new ContainerHierarchicalWrapper(newDataSource);
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>FileSystemContainerInTreeTable</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">FileSystemContainerInTreeTable</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.containers.filesystemcontainer.FileSystemContainerInTreeTable?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>initial</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VHorizontalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>added_not_yet_visible</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>30,8</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>added_dir2_expanded</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VHorizontalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>32,6</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>deleted_dir2_collapsed</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>32,4</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>deleted_dir2_expanded</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VHorizontalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>31,8</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>added_dir2_collapsed</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>29,5</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>added_dir1_expanded</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VHorizontalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>32,8</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>deleted_dir1_collapsed</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscontainersfilesystemcontainerFileSystemContainerInTreeTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VHorizontalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
--- /dev/null
+package com.vaadin.tests.containers.filesystemcontainer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+\r
+import com.vaadin.data.Container;\r
+import com.vaadin.data.Container.Ordered;\r
+import com.vaadin.data.util.FilesystemContainer;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.tests.util.Log;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.HorizontalLayout;\r
+import com.vaadin.ui.Table;\r
+import com.vaadin.ui.Tree.CollapseEvent;\r
+import com.vaadin.ui.Tree.CollapseListener;\r
+import com.vaadin.ui.Tree.ExpandEvent;\r
+import com.vaadin.ui.Tree.ExpandListener;\r
+import com.vaadin.ui.TreeTable;\r
+\r
+public class FileSystemContainerInTreeTable extends TestBase {\r
+\r
+ private Log log = new Log(5);\r
+ private TreeTable treeTable;\r
+\r
+ @Override\r
+ protected void setup() {\r
+ setTheme("reindeer-tests");\r
+\r
+ final File folder;\r
+ try {\r
+ File tempFile = File.createTempFile("fsc-tt", "");\r
+ tempFile.delete();\r
+ folder = new File(tempFile.getParent(), tempFile.getName());\r
+ folder.mkdir();\r
+ System.out.println(folder.getPath());\r
+ folder.deleteOnExit();\r
+\r
+ populate(folder, 3, 10);\r
+\r
+ FilesystemContainer fsc = new FilesystemContainer(folder);\r
+\r
+ treeTable = new TreeTable();\r
+ treeTable.addStyleName("table-equal-rowheight");\r
+ treeTable.setWidth("450px");\r
+ treeTable.setHeight("550px");\r
+ treeTable.setContainerDataSource(fsc);\r
+ treeTable.setItemIconPropertyId(FilesystemContainer.PROPERTY_ICON);\r
+ treeTable.setVisibleColumns(new String[] { "Name" });\r
+ treeTable.setColumnWidth("Name", 400);\r
+ treeTable.addListener(new ExpandListener() {\r
+\r
+ public void nodeExpand(ExpandEvent event) {\r
+ logExpandCollapse(event.getItemId(), "expanded");\r
+\r
+ }\r
+ });\r
+ treeTable.addListener(new CollapseListener() {\r
+\r
+ public void nodeCollapse(CollapseEvent event) {\r
+ logExpandCollapse(event.getItemId(), "collapsed");\r
+\r
+ }\r
+ });\r
+\r
+ addComponent(log);\r
+ addComponent(treeTable);\r
+\r
+ HorizontalLayout buttonLayout = new HorizontalLayout();\r
+ buttonLayout.setSpacing(true);\r
+ buttonLayout.addComponent(new Button("Create dir11",\r
+ new Button.ClickListener() {\r
+ public void buttonClick(ClickEvent event) {\r
+ new File(folder, "dir11").mkdir();\r
+ log.log("Row dir11 created");\r
+ }\r
+ }));\r
+ buttonLayout.addComponent(new Button("Delete dir11",\r
+ new Button.ClickListener() {\r
+ public void buttonClick(ClickEvent event) {\r
+ new File(folder, "dir11").delete();\r
+ log.log("Row dir11 deleted");\r
+ }\r
+ }));\r
+ // to clean up explicitly before ending an automated test\r
+ buttonLayout.addComponent(new Button("Clean all files",\r
+ new Button.ClickListener() {\r
+ public void buttonClick(ClickEvent event) {\r
+ folder.delete();\r
+ }\r
+ }));\r
+ addComponent(buttonLayout);\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ private void populate(File folder, int subDirectories, int files)\r
+ throws IOException {\r
+ for (int i = 1; i <= files; i++) {\r
+ File f = new File(folder, "file" + i + ".txt");\r
+ f.createNewFile();\r
+ }\r
+\r
+ for (int i = 1; i <= subDirectories; i++) {\r
+ File f = new File(folder, "dir" + i);\r
+ f.mkdir();\r
+ populate(f, 0, 2);\r
+ }\r
+ }\r
+\r
+ protected int indexOfId(Table source, Object itemId) {\r
+ Container.Ordered c = (Ordered) source.getContainerDataSource();\r
+ if (c instanceof Container.Indexed) {\r
+ return ((Container.Indexed) source).indexOfId(itemId);\r
+ } else {\r
+ ArrayList<Object> list = new ArrayList<Object>(source.getItemIds());\r
+ return list.indexOf(itemId);\r
+ }\r
+ }\r
+\r
+ protected void logExpandCollapse(Object itemId, String operation) {\r
+ File file = (File) itemId;\r
+ // do not use the variable part (path) of file name\r
+ log.log("Row " + file.getName() + " " + operation + ". Row index: "\r
+ + indexOfId(treeTable, itemId));\r
+\r
+ }\r
+\r
+ @Override\r
+ protected String getDescription() {\r
+ return "TreeTable partial updates can only be used with a container that notifies the TreeTable of item set changes";\r
+ }\r
+\r
+ @Override\r
+ protected Integer getTicketNumber() {\r
+ return 7837;\r
+ }\r
+\r
+}
\ No newline at end of file