У меня установлена JTable в режиме SINGLE_SELECTION, то есть пользователь может выбрать только одну строку за раз.
Я пытаюсь переопределить CTRL + C KeyListener, чтобы он скопировал всю таблицу в буфер обмена.
На данный момент я добавил KeyListener к самому JTable в его конструкторе:
public MyTable(AbstractTableModel model) {
super(model);
getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
addKeyListener(new ExcelClipboardKeyAdapter(this));
}
KeyListener выглядит так:
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, " "));
}
}
Однако, когда я нажимаю CTRL + C , метод keyreleased
не вызывается и не печатает «здесь». Содержимое буфера обмена содержит только выделенную строку.
Любые идеи приветствуются.
EDIT
На самом деле иногда это работает несколько раз, затем перестает работать и снова копирует одну строку ... странно ...