I have a JTable set on SINGLE_SELECTION mode, i.e. the user can only select one row at a time. I am trying to override the CTRL+C KeyListener so that it will copy the whole table to the clipboard.
At the moment, I have added a KeyListener to the JTable itself in its constructor:
public MyTable(AbstractTableModel model) {
super(model);
getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
addKeyListener(new ExcelClipboardKeyAdapter(this));
}
The KeyListener looks like this:
public class ExcelClipboardKeyAdapter extends KeyAdapter {
private static final String LINE_BREAK = System.lineSeparator();
private static final String CELL_BREAK = "\t";
private static final Clipboard CLIPBOARD = Toolkit.getDefaultToolkit().getSystemClipboard();
private final JTable table;
public ExcelClipboardKeyAdapter(JTable table) {
this.table = table;
}
@Override
public void keyReleased(KeyEvent event) {
if (event.isControlDown()) {
if (event.getKeyCode() == KeyEvent.VK_C) { // Copy
copyToClipboard();
System.out.println("here");
}
}
}
private void copyToClipboard() {
int numCols = table.getColumnCount();
int numRows = table.getRowCount();
StringBuilder excelStr = new StringBuilder();
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
excelStr.append(escape(table.getValueAt(i, j)));
if (j < numCols - 1) {
excelStr.append(CELL_BREAK);
}
}
excelStr.append(LINE_BREAK);
}
StringSelection sel = new StringSelection(excelStr.toString());
CLIPBOARD.setContents(sel, sel);
}
private String escape(Object cell) {
return (cell == null? "" : cell.toString().replace(LINE_BREAK, " ").replace(CELL_BREAK, " "));
}
}
However, when I press CTRL+C, the keyreleased
method is not called and does not print "here". The content of the clipboard only contains the selected line.
Any ideas would be welcome.
EDIT
Actually it sometimes works a few times then it stops working and copies one row again... weird...