Cut,Copy,Paste
This article is out of date, please refer to http://books.zkoss.org/wiki/ZK_Spreadsheet_Essentials for more up to date information.
Purpose
ZK Spreadsheet uses Range to represent a cell, a row, a column, or selection of cells. We can use Range to get information or execute command. Here, we use Range to demonstrate how to implement cut, copy, and paste command.
Copy
1. We can construct Range object by Ranges. It has various functions, for example
Ranges.range(sheet, "A1:D4");
2. We can use AbstractComponent.getAttribute(String) to save the user's current selection range
private void setSource() {
Rect selectedRect = spreadsheet.getSelection();
Range range = Ranges.range(spreadsheet.getSelectedSheet(),
selectedRect.getTop(),
selectedRect.getLeft(),
selectedRect.getBottom(),
selectedRect.getRight());
//save user selection range
spreadsheet.setAttribute(KEY_SOURCE_RANGE, range);
spreadsheet.setAttribute(KEY_SOURCE_RECT, selectedRect);
}
Cut
We can save a boolean object to distinguish between cut and paset command.
The reason why we need save this variable is because paste function needs to know whether it is cut or paste.
If it is cut, we need to clear the previous selection's content; if it is copy, we can keep the previous selection.
private void onCut() {
spreadsheet.setAttribute(KEY_IS_CUT, Boolean.valueOf(true));
.....
}
private boolean isCut() {
Boolean isCut = (Boolean)spreadsheet.getAttribute(KEY_IS_CUT);
return isCut != null && isCut;
}
Paste
We can use Range.copy(Range) to copy the user's selection
1. Retrieve the user's previous selection. We can retrieve by AbstractComponent.getAttribute(String, Object), for example
private void onPaste() {
Range srcRange = (Range)spreadsheet.getAttribute(KEY_SOURCE_RANGE);
Rect srcRect = (Rect)spreadsheet.getAttribute(KEY_SOURCE_RECT);
....
2. Construct the destination Range object
After we get the previous selection range and current position, we can construct destination Range, and execute copy
int columnCount = srcRect.getRight() - srcRect.getLeft();
int rowCount = srcRect.getBottom() - srcRect.getTop();
Rect dstRect = spreadsheet.getSelection();
int rowIndex = dstRect.getTop();
int columnIndex = dstRect.getLeft();
Range dst = Ranges.range(spreadsheet.getSelectedSheet(),
rowIndex,
columnIndex,
rowIndex + rowCount,
columnIndex + columnCount);
srcRange.copy(dst);
3. If command is cut, clear the highlight area of a spreadsheet and clear the previous selection's content.
private void clearCutRangeIfNeeded() {
if (!isCut())
return;
Range srcRange = (Range)spreadsheet.getAttribute(KEY_SOURCE_RANGE);
srcRange.clearContents();
/* clear cell style*/
CellStyle defaultCellStyle = spreadsheet.getBook().getCellStyleAt((short)0);
srcRange.setStyle(defaultCellStyle);
}
private void clearHighlightIfNeeded() {
if (isCut())
spreadsheet.setHighlight(null);
}
ZUML
In zul, we declare a composer for event handling.
<zk>
<div height="100%" width="100%" apply="demo.CopyPasteComposer">
<spreadsheet id="spreadsheet"
src="/demo_sample.xls"
maxrows="200"
maxcolumns="40"
vflex="1"
width="100%"
ctrlKeys="^c^v^x">
</spreadsheet>
<menupopup id="cellMenu">
<menuitem id="cutMenu" label="Cut" />
<menuitem id="copyMenu" label="Copy" />
<menuitem id="pasteMenu" label="Paste" />
</menupopup>
</div>
</zk>
Composer
In composer, we need to handle events, including onCellRightClick, Menuitem's onClick event and onCtrlKey event.
Here, we use GenericForwardComposer as it allow us to write intuitive onXxx$myid event handler methods and it can auto-wired variable.
Open Menu
onCellRightClick is a spreadsheet's event, this event occurs when the user right clicks on a cell. We use this event to popup menu, allowing users to select cut, copy or paste function.
Also, we can retrieve the mouse position from CellMouseEvent and set menupopup's popup position.
public void onCellRightClick$spreadsheet(CellMouseEvent event) {
cellMenu.open(event.getClientx(), event.getClienty());
}
Execute Command
We can register menuitem's onClick event to execute corresponding command.
public void onClick$cutMenu() {
onCut();
}
public void onClick$copyMenu(Event evt) {
onCopy();
}
public void onClick$pasteMenu(Event evt) {
onPaste();
}
Use Control Key
We can also register control key event to execute corresponding command.
public void onCtrlKey$spreadsheet(KeyEvent evt) {
if (evt.isCtrlKey()) {
switch (evt.getKeyCode()) {
case 'C':
onCopy();
break;
case 'V':
onPaste();
break;
case 'X':
onCut();
break;
}
}
}
View the complete source of ZUML copyAndPaste.zul
View the complete source of composer CopyPasteComposer.java
Version History
Version | Date | Content |
---|---|---|
All source code listed in this book is at Github.