Java tutorial
package com.vaadin.addon.spreadsheet; /* * #%L * Vaadin Spreadsheet * %% * Copyright (C) 2013 - 2015 Vaadin Ltd * %% * This program is available under Commercial Vaadin Add-On License 3.0 * (CVALv3). * * See the file license.html distributed with this software for more * information about licensing. * * You should have received a copy of the CVALv3 along with this program. * If not, see <http://vaadin.com/license/cval-3>. * #L% */ import com.vaadin.addon.spreadsheet.Spreadsheet.CellValueChangeEvent; import com.vaadin.addon.spreadsheet.Spreadsheet.ProtectedEditEvent; import com.vaadin.addon.spreadsheet.client.SpreadsheetServerRpc; import com.vaadin.addon.spreadsheet.command.CellValueCommand; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; /** * Implementation of the Spreadsheet Server RPC interface. */ @SuppressWarnings("serial") public class SpreadsheetHandlerImpl implements SpreadsheetServerRpc { private Spreadsheet spreadsheet; public SpreadsheetHandlerImpl(Spreadsheet spreadsheet) { this.spreadsheet = spreadsheet; } @Override public void onSheetScroll(int firstRow, int firstColumn, int lastRow, int lastColumn) { spreadsheet.onSheetScroll(firstRow, firstColumn, lastRow, lastColumn); } @Override public void cellSelected(int row, int column, boolean discardOldRangeSelection) { spreadsheet.getCellSelectionManager().onCellSelected(row, column, discardOldRangeSelection); } @Override public void sheetAddressChanged(String value) { spreadsheet.getCellSelectionManager().onSheetAddressChanged(value, false); } @Override public void cellRangeSelected(int row1, int col1, int row2, int col2) { spreadsheet.getCellSelectionManager().onCellRangeSelected(row1, col1, row2, col2); } /* */ @Override public void cellRangePainted(int selectedCellRow, int selectedCellColumn, int row1, int col1, int row2, int col2) { spreadsheet.getCellSelectionManager().onCellRangePainted(selectedCellRow, selectedCellColumn, row1, col1, row2, col2); } @Override public void cellAddedToSelectionAndSelected(int row, int column) { spreadsheet.getCellSelectionManager().onCellAddToSelectionAndSelected(row, column); } @Override public void cellsAddedToRangeSelection(int row1, int col1, int row2, int col2) { spreadsheet.getCellSelectionManager().onCellsAddedToRangeSelection(row1, col1, row2, col2); } @Override public void rowSelected(int row, int firstColumnIndex) { spreadsheet.getCellSelectionManager().onRowSelected(row, firstColumnIndex); } @Override public void rowAddedToRangeSelection(int row, int firstColumnIndex) { spreadsheet.getCellSelectionManager().onRowAddedToRangeSelection(row, firstColumnIndex); } @Override public void columnSelected(int col, int firstRowIndex) { spreadsheet.getCellSelectionManager().onColumnSelected(firstRowIndex, col); } @Override public void columnAddedToSelection(int firstRowIndex, int column) { spreadsheet.getCellSelectionManager().onColumnAddedToSelection(firstRowIndex, column); } /* the actual selected cell hasn't changed */ @Override public void selectionIncreasePainted(int r1, int c1, int r2, int c2) { spreadsheet.getCellShifter().onSelectionIncreasePainted(r1, c1, r2, c2); } /* the actual selected cell hasn't changed */ @Override public void selectionDecreasePainted(int r, int c) { spreadsheet.getCellShifter().onSelectionDecreasePainted(r, c); } @Override public void cellValueEdited(int row, int col, String value) { spreadsheet.getCellValueManager().onCellValueChange(col, row, value); } @Override public void sheetSelected(int tabIndex, int scrollLeft, int scrollTop) { spreadsheet.onSheetSelected(tabIndex, scrollLeft, scrollTop); } @Override public void sheetRenamed(int sheetIndex, String sheetName) { spreadsheet.onSheetRename(sheetIndex, sheetName); } @Override public void sheetCreated(int scrollLeft, int scrollTop) { spreadsheet.onNewSheetCreated(scrollLeft, scrollTop); } @Override public void deleteSelectedCells() { spreadsheet.getCellValueManager().onDeleteSelectedCells(); } @Override public void linkCellClicked(int row, int column) { spreadsheet.onLinkCellClick(row, column); } @Override public void contextMenuOpenOnSelection(int row, int column) { spreadsheet.getContextMenuManager().onContextMenuOpenOnSelection(row, column); } @Override public void rowHeaderContextMenuOpen(int rowIndex) { spreadsheet.getContextMenuManager().onRowHeaderContextMenuOpen(rowIndex); } @Override public void columnHeaderContextMenuOpen(int columnIndex) { spreadsheet.getContextMenuManager().onColumnHeaderContextMenuOpen(columnIndex); } @Override public void actionOnCurrentSelection(String actionKey) { spreadsheet.getContextMenuManager().onActionOnCurrentSelection(actionKey); } @Override public void actionOnRowHeader(String actionKey) { spreadsheet.getContextMenuManager().onActionOnRowHeader(actionKey); } @Override public void actionOnColumnHeader(String actionKey) { spreadsheet.getContextMenuManager().onActionOnColumnHeader(actionKey); } @Override public void rowsResized(Map<Integer, Float> newRowSizes, int row1, int col1, int row2, int col2) { spreadsheet.onRowResized(newRowSizes, row1, col1, row2, col2); } @Override public void columnResized(Map<Integer, Integer> newColumnSizes, int row1, int col1, int row2, int col2) { spreadsheet.onColumnResized(newColumnSizes, row1, col1, row2, col2); } @Override public void onColumnAutofit(int columnIndex) { spreadsheet.onColumnAutofit(columnIndex - 1); } @Override public void onUndo() { spreadsheet.getSpreadsheetHistoryManager().undo(); } @Override public void onRedo() { spreadsheet.getSpreadsheetHistoryManager().redo(); } @Override public void setCellStyleWidthRatios(HashMap<Integer, Float> cellStyleWidthRatioMap) { spreadsheet.getCellValueManager().onCellStyleWidthRatioUpdate(cellStyleWidthRatioMap); } @Override public void onConnectorInit() { spreadsheet.onConnectorInit(); } @Override public void protectedCellWriteAttempted() { spreadsheet.fireEvent(new ProtectedEditEvent(spreadsheet)); } @Override public void onPaste(String text) { Workbook workbook = spreadsheet.getWorkbook(); Sheet activesheet = workbook.getSheetAt(workbook.getActiveSheetIndex()); CellReference selectedCellReference = spreadsheet.getSelectedCellReference(); String[] lines; if (text.indexOf("\r\n") > -1) { lines = text.split("\r\n"); } else if (text.indexOf("\n") > -1) { lines = text.split("\n"); } else { lines = text.split("\r"); } int pasteHeight = lines.length; int pasteWidth = 1; for (String line : lines) { String[] tokens = splitOnTab(line); pasteWidth = Math.max(pasteWidth, tokens.length); } int rowIndex = selectedCellReference.getRow(); int colIndex = selectedCellReference.getCol(); // Check for protected cells at target for (int i = 0; i < pasteHeight; i++) { Row row = activesheet.getRow(rowIndex + i); if (row != null) { for (int j = 0; j < pasteWidth; j++) { Cell cell = row.getCell(colIndex + j); if (spreadsheet.isCellLocked(cell)) { protectedCellWriteAttempted(); return; } } } } CellValueCommand command = new CellValueCommand(spreadsheet); CellRangeAddress affectedRange = new CellRangeAddress(rowIndex, rowIndex + pasteHeight - 1, colIndex, colIndex + pasteWidth - 1); command.captureCellRangeValues(affectedRange); for (int i = 0; i < pasteHeight; i++) { String line = lines[i]; Row row = activesheet.getRow(rowIndex + i); if (row == null) { row = activesheet.createRow(rowIndex + i); } String[] tokens = splitOnTab(line); for (int j = 0; j < pasteWidth; j++) { Cell cell = row.getCell(colIndex + j); if (cell == null) { cell = row.createCell(colIndex + j); } if (j < tokens.length) { String cellContent = tokens[j]; Double numVal = SpreadsheetUtil.parseNumber(cell, cellContent, spreadsheet.getLocale()); if (numVal != null) { cell.setCellType(Cell.CELL_TYPE_NUMERIC); cell.setCellValue(numVal); } else { cell.setCellValue(cellContent); } } else { cell.setCellType(Cell.CELL_TYPE_BLANK); spreadsheet.markCellAsDeleted(cell, true); } spreadsheet.getCellValueManager().markCellForUpdate(cell); spreadsheet.getCellValueManager().getFormulaEvaluator().notifyUpdateCell(cell); } } spreadsheet.getSpreadsheetHistoryManager().addCommand(command); spreadsheet.updateMarkedCells(); // re-set selection to copied area spreadsheet.setSelectionRange(rowIndex, colIndex, rowIndex + pasteHeight - 1, colIndex + pasteWidth - 1); fireCellValueChangeEvent(affectedRange); } private void fireCellValueChangeEvent(CellRangeAddress region) { Set<CellReference> cells = new HashSet<CellReference>(); for (int x = region.getFirstColumn(); x <= region.getLastColumn(); x++) { for (int y = region.getFirstRow(); y <= region.getLastRow(); y++) { cells.add(new CellReference(y, x)); } } fireCellValueChangeEvent(cells); } private void fireCellValueChangeEvent(Set<CellReference> cells) { spreadsheet.fireEvent(new CellValueChangeEvent(spreadsheet, cells)); } /** * Splits tab-delimited string into an array of Strings, inserting empty * strings between any tab characters and the beginning and end of the line * if it would be a tab. Length of array will equal number of tabs + 1. * <p> * E.g.<br/> * "1\t2" - {"1","2"}<br/> * "\t\t" - {"","",""}<br/> * * @param line * input * @return output string parts split at tabs */ private static String[] splitOnTab(String line) { List<String> list = new LinkedList<String>(); StringTokenizer tokenizer = new StringTokenizer(line, "\t", true); // marker for when last token is a tab, meaning we need one // additional empty string boolean lastCharWasTab = false; while (tokenizer.hasMoreTokens()) { String content = tokenizer.nextToken(); if (content.equals("\t")) { // empty content; insert empty string here content = ""; if (!tokenizer.hasMoreTokens()) { lastCharWasTab = true; } } else { // normal cell content, value in 'content' // skip to next content by skipping tab token // (we process 'content\t' on the same loop) if (tokenizer.countTokens() > 1) { tokenizer.nextToken(); } else if (tokenizer.countTokens() == 1) { // if the tab is the last char we need to mark it tokenizer.nextToken(); lastCharWasTab = true; } } list.add(content); if (lastCharWasTab) { list.add(""); } } return list.toArray(new String[list.size()]); } @Override public void clearSelectedCellsOnCut() { // clear ranges List<Cell> targetCells = new ArrayList<Cell>(); List<CellRangeAddress> cellRangeAddresses = spreadsheet.getCellSelectionManager().getCellRangeAddresses(); for (CellRangeAddress a : cellRangeAddresses) { for (int row = a.getFirstRow(); row <= a.getLastRow(); row++) { for (int col = a.getFirstColumn(); col <= a.getLastColumn(); col++) { Cell cell = spreadsheet.getCell(row, col); if (cell != null) { if (spreadsheet.isCellLocked(cell)) { protectedCellWriteAttempted(); return; } targetCells.add(cell); } } } } // clear single cell CellReference reference = spreadsheet.getCellSelectionManager().getSelectedCellReference(); Cell cell = spreadsheet.getCell(reference.getRow(), reference.getCol()); if (cell != null) { if (spreadsheet.isCellLocked(cell)) { protectedCellWriteAttempted(); return; } targetCells.add(cell); } CellValueCommand command = new CellValueCommand(spreadsheet); if (reference != null) { command.captureCellValues(reference); } for (CellRangeAddress range : cellRangeAddresses) { command.captureCellRangeValues(range); } spreadsheet.getSpreadsheetHistoryManager().addCommand(command); for (Cell targetCell : targetCells) { targetCell.setCellType(Cell.CELL_TYPE_BLANK); spreadsheet.markCellAsDeleted(targetCell, true); } fireCellValueChangeEvent(spreadsheet.getSelectedCellReferences()); spreadsheet.refreshAllCellValues(); } @Override public void updateCellComment(String text, int col, int row) { CreationHelper factory = spreadsheet.getWorkbook().getCreationHelper(); RichTextString str = factory.createRichTextString(text); spreadsheet.getActiveSheet().getCellComment(row - 1, col - 1).setString(str); } @Override public void setGroupingCollapsed(boolean isCols, int colIndex, boolean collapsed) { spreadsheet.setGroupingCollapsed(isCols, colIndex, collapsed); } @Override public void levelHeaderClicked(boolean isCols, int level) { spreadsheet.levelHeaderClicked(isCols, level); } }