/** @overrides ISupportMomento.loadState() */ @Override public void loadState(Object memento) { assert (memento instanceof PageState) : "ISupportMemento contract violated in Page"; if (memento instanceof PageState) { PageState state = (PageState) memento; // load basic page information this.setPageName(state.name); this.setPageId(state.id); this.setPageColor(state.color); this.setPixelWidth(state.width); // Load block information Map<Long, Object> renderableBlockStates = state.renderableBlocks; List<Long> unloadedRenderableBlockStates = new LinkedList<Long>(); List<Long> loadedBlocks = new LinkedList<Long>(); for (Long id : renderableBlockStates.keySet()) { unloadedRenderableBlockStates.add(id); } // First, load all the blocks that are in the state to be loaded // against all the blocks that already exist. for (RenderableBlock existingBlock : getBlocks()) { Long existingBlockID = existingBlock.getBlockID(); if (renderableBlockStates.containsKey(existingBlockID)) { existingBlock.loadState(renderableBlockStates.get(existingBlockID)); unloadedRenderableBlockStates.remove(existingBlockID); loadedBlocks.add(existingBlockID); } } ArrayList<RenderableBlock> blocksToRemove = new ArrayList<RenderableBlock>(); // Now, find all the blocks that don't exist in the save state and flag them to be removed. for (RenderableBlock existingBlock : this.getBlocks()) { Long existingBlockID = existingBlock.getBlockID(); if (!loadedBlocks.contains(existingBlockID)) { blocksToRemove.add(existingBlock); } } // This loop is necessary to avoid a concurrent modification error that occurs // if the loop above removes the block while iterating over an unmodifiable // iterator. for (RenderableBlock toBeRemovedBlock : blocksToRemove) { this.removeBlock(toBeRemovedBlock); } // Finally, add all the remaining blocks that weren't there before ArrayList<RenderableBlock> blocksToAdd = new ArrayList<RenderableBlock>(); for (Long newBlockID : unloadedRenderableBlockStates) { RenderableBlock newBlock = new RenderableBlock(workspace, this, newBlockID); newBlock.loadState(renderableBlockStates.get(newBlockID)); blocksToAdd.add(newBlock); } this.addBlocks(blocksToAdd); this.pageJComponent.repaint(); } }