You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ExpandingContainer.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. package com.vaadin.tests.components.table;
  2. import java.util.AbstractList;
  3. import java.util.Arrays;
  4. import java.util.Collection;
  5. import java.util.List;
  6. import java.util.logging.Logger;
  7. import com.vaadin.server.VaadinSession;
  8. import com.vaadin.ui.Component;
  9. import com.vaadin.ui.Label;
  10. import com.vaadin.v7.data.Container;
  11. import com.vaadin.v7.data.Item;
  12. import com.vaadin.v7.data.Property;
  13. import com.vaadin.v7.data.util.AbstractContainer;
  14. import com.vaadin.v7.data.util.BeanItem;
  15. @SuppressWarnings("serial")
  16. public class ExpandingContainer extends AbstractContainer
  17. implements Container.Indexed, Container.ItemSetChangeNotifier {
  18. public static final List<String> PROPERTY_IDS = Arrays.asList("id",
  19. "column1", "column2");
  20. private final Label sizeLabel;
  21. private final Logger log = Logger.getLogger(this.getClass().getName());
  22. private int currentSize = 300;
  23. private boolean loggingEnabled;
  24. public ExpandingContainer(Label sizeLabel) {
  25. this.sizeLabel = sizeLabel;
  26. updateLabel();
  27. }
  28. private void log(String message) {
  29. if (loggingEnabled) {
  30. log.info(message);
  31. }
  32. }
  33. // Expand container if we scroll past 85%
  34. public int checkExpand(int index) {
  35. log("checkExpand(" + index + ")");
  36. if (index >= currentSize * 0.85) {
  37. final int oldsize = currentSize;
  38. currentSize = (int) (oldsize * 1.3333);
  39. log("*** getSizeWithHint(" + index + "): went past 85% of size="
  40. + oldsize + ", new size=" + currentSize);
  41. updateLabel();
  42. }
  43. return currentSize;
  44. }
  45. @Override
  46. public void fireItemSetChange() {
  47. super.fireItemSetChange();
  48. }
  49. private void updateLabel() {
  50. sizeLabel.setValue("Container size: " + currentSize);
  51. }
  52. public void triggerItemSetChange() {
  53. log("*** triggerItemSetChange(): scheduling item set change event");
  54. final VaadinSession session = VaadinSession.getCurrent();
  55. new Thread() {
  56. @Override
  57. public void run() {
  58. ExpandingContainer.this.invoke(session, () -> {
  59. log("*** Firing item set change event");
  60. ExpandingContainer.this.fireItemSetChange();
  61. });
  62. }
  63. }.start();
  64. }
  65. private void invoke(VaadinSession session, Runnable action) {
  66. session.lock();
  67. VaadinSession previousSession = VaadinSession.getCurrent();
  68. VaadinSession.setCurrent(session);
  69. try {
  70. action.run();
  71. } finally {
  72. session.unlock();
  73. VaadinSession.setCurrent(previousSession);
  74. }
  75. }
  76. // Container
  77. @Override
  78. public BeanItem<MyBean> getItem(Object itemId) {
  79. if (!(itemId instanceof Integer)) {
  80. return null;
  81. }
  82. final int index = ((Integer) itemId).intValue();
  83. return new BeanItem<>(new MyBean(index));
  84. }
  85. @Override
  86. public Collection<Integer> getItemIds() {
  87. return new IntList(size());
  88. }
  89. @Override
  90. public List<String> getContainerPropertyIds() {
  91. return PROPERTY_IDS;
  92. }
  93. @Override
  94. @SuppressWarnings("rawtypes")
  95. public Property/* <?> */ getContainerProperty(Object itemId,
  96. Object propertyId) {
  97. BeanItem<MyBean> item = getItem(itemId);
  98. return item != null ? item.getItemProperty(propertyId) : null;
  99. }
  100. @Override
  101. public Class<?> getType(Object propertyId) {
  102. return Component.class;
  103. }
  104. @Override
  105. public int size() {
  106. return currentSize;
  107. }
  108. @Override
  109. public boolean containsId(Object itemId) {
  110. if (!(itemId instanceof Integer)) {
  111. return false;
  112. }
  113. int index = ((Integer) itemId).intValue();
  114. checkExpand(index);
  115. return index >= 0 && index < currentSize;
  116. }
  117. /**
  118. * @throws UnsupportedOperationException
  119. * always
  120. */
  121. @Override
  122. public Item addItem(Object itemId) {
  123. throw new UnsupportedOperationException();
  124. }
  125. /**
  126. * @throws UnsupportedOperationException
  127. * always
  128. */
  129. @Override
  130. public Item addItem() {
  131. throw new UnsupportedOperationException();
  132. }
  133. /**
  134. * @throws UnsupportedOperationException
  135. * always
  136. */
  137. @Override
  138. public boolean removeItem(Object itemId) {
  139. throw new UnsupportedOperationException();
  140. }
  141. /**
  142. * @throws UnsupportedOperationException
  143. * always
  144. */
  145. @Override
  146. public boolean addContainerProperty(Object propertyId, Class<?> type,
  147. Object defaultValue) {
  148. throw new UnsupportedOperationException();
  149. }
  150. /**
  151. * @throws UnsupportedOperationException
  152. * always
  153. */
  154. @Override
  155. public boolean removeContainerProperty(Object propertyId) {
  156. throw new UnsupportedOperationException();
  157. }
  158. /**
  159. * @throws UnsupportedOperationException
  160. * always
  161. */
  162. @Override
  163. public boolean removeAllItems() {
  164. throw new UnsupportedOperationException();
  165. }
  166. // Container.Indexed
  167. /**
  168. * @throws UnsupportedOperationException
  169. * always
  170. */
  171. @Override
  172. public Object addItemAt(int index) {
  173. throw new UnsupportedOperationException();
  174. }
  175. /**
  176. * @throws UnsupportedOperationException
  177. * always
  178. */
  179. @Override
  180. public Item addItemAt(int index, Object newItemId) {
  181. throw new UnsupportedOperationException();
  182. }
  183. @Override
  184. public Integer getIdByIndex(int index) {
  185. if (index < 0) {
  186. throw new IndexOutOfBoundsException("index < " + index);
  187. }
  188. final int size = currentSize;
  189. if (index >= size) {
  190. throw new IndexOutOfBoundsException(
  191. "index=" + index + " but size=" + size);
  192. }
  193. checkExpand(index);
  194. return index;
  195. }
  196. @Override
  197. public List<Integer> getItemIds(int startIndex, int numberOfItems) {
  198. if (numberOfItems < 0) {
  199. throw new IllegalArgumentException("numberOfItems < 0");
  200. }
  201. final int size = currentSize;
  202. checkExpand(startIndex);
  203. if (startIndex < 0 || startIndex > size) {
  204. throw new IndexOutOfBoundsException(
  205. "startIndex=" + startIndex + " but size=" + size);
  206. }
  207. if (startIndex + numberOfItems > size) {
  208. numberOfItems = size - startIndex;
  209. }
  210. return new IntList(startIndex, numberOfItems);
  211. }
  212. @Override
  213. public int indexOfId(Object itemId) {
  214. if (!(itemId instanceof Integer)) {
  215. return -1;
  216. }
  217. final int index = ((Integer) itemId).intValue();
  218. checkExpand(index);
  219. if (index < 0 || index >= currentSize) {
  220. return -1;
  221. }
  222. return index;
  223. }
  224. // Container.Ordered
  225. @Override
  226. public Integer nextItemId(Object itemId) {
  227. if (!(itemId instanceof Integer)) {
  228. return null;
  229. }
  230. int index = ((Integer) itemId).intValue();
  231. checkExpand(index);
  232. if (index < 0 || index + 1 >= currentSize) {
  233. return null;
  234. }
  235. return index + 1;
  236. }
  237. @Override
  238. public Integer prevItemId(Object itemId) {
  239. if (!(itemId instanceof Integer)) {
  240. return null;
  241. }
  242. int index = ((Integer) itemId).intValue();
  243. checkExpand(index);
  244. if (index - 1 < 0 || index >= currentSize) {
  245. return null;
  246. }
  247. return index - 1;
  248. }
  249. @Override
  250. public Integer firstItemId() {
  251. return currentSize == 0 ? null : 0;
  252. }
  253. @Override
  254. public Integer lastItemId() {
  255. final int size = currentSize;
  256. return size == 0 ? null : size - 1;
  257. }
  258. @Override
  259. public boolean isFirstId(Object itemId) {
  260. if (!(itemId instanceof Integer)) {
  261. return false;
  262. }
  263. final int index = ((Integer) itemId).intValue();
  264. checkExpand(index);
  265. final int size = currentSize;
  266. return size > 0 && index == 0;
  267. }
  268. @Override
  269. public boolean isLastId(Object itemId) {
  270. if (!(itemId instanceof Integer)) {
  271. return false;
  272. }
  273. int index = ((Integer) itemId).intValue();
  274. checkExpand(index);
  275. int size = currentSize;
  276. return size > 0 && index == size - 1;
  277. }
  278. /**
  279. * @throws UnsupportedOperationException
  280. * always
  281. */
  282. @Override
  283. public Item addItemAfter(Object previousItemId) {
  284. throw new UnsupportedOperationException();
  285. }
  286. /**
  287. * @throws UnsupportedOperationException
  288. * always
  289. */
  290. @Override
  291. public Item addItemAfter(Object previousItemId, Object newItemId) {
  292. throw new UnsupportedOperationException();
  293. }
  294. // Container.ItemSetChangeNotifier
  295. @Override
  296. @SuppressWarnings("deprecation")
  297. public void addListener(Container.ItemSetChangeListener listener) {
  298. super.addListener(listener);
  299. }
  300. @Override
  301. public void addItemSetChangeListener(
  302. Container.ItemSetChangeListener listener) {
  303. super.addItemSetChangeListener(listener);
  304. }
  305. @Override
  306. @SuppressWarnings("deprecation")
  307. public void removeListener(Container.ItemSetChangeListener listener) {
  308. super.removeListener(listener);
  309. }
  310. @Override
  311. public void removeItemSetChangeListener(
  312. Container.ItemSetChangeListener listener) {
  313. super.removeItemSetChangeListener(listener);
  314. }
  315. // IntList
  316. private static class IntList extends AbstractList<Integer> {
  317. private final int min;
  318. private final int size;
  319. public IntList(int size) {
  320. this(0, size);
  321. }
  322. public IntList(int min, int size) {
  323. if (size < 0) {
  324. throw new IllegalArgumentException("size < 0");
  325. }
  326. this.min = min;
  327. this.size = size;
  328. }
  329. @Override
  330. public int size() {
  331. return size;
  332. }
  333. @Override
  334. public Integer get(int index) {
  335. if (index < 0 || index >= size) {
  336. throw new IndexOutOfBoundsException();
  337. }
  338. return min + index;
  339. }
  340. }
  341. // MyBean
  342. public class MyBean {
  343. private final int index;
  344. public MyBean(int index) {
  345. this.index = index;
  346. }
  347. public String getId() {
  348. return "ROW #" + index;
  349. }
  350. public String getColumn1() {
  351. return genText();
  352. }
  353. public String getColumn2() {
  354. return genText();
  355. }
  356. private String genText() {
  357. return "this is a line of text in row #" + index;
  358. }
  359. }
  360. public void logDetails(boolean enabled) {
  361. loggingEnabled = enabled;
  362. }
  363. }