javaswingjtablekeystroke

Copying the cell value of selected JTable cell instead of row


I'm trying to enable ctrl c on the actual cell of the Jtable, instead of the whole row. I know how to disable the ctrl c on the whole row.

KeyStroke cStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK);
inputMap.put(cStroke,  "none");

I have tried the following to add a ctrl c to the cell itself: adding a keylistener to the table itself. It did not work. And the following code:

Action actionListener = new AbstractAction() {
    public void actionPerformed(ActionEvent actionEvent) {
        System.out.println("activated");
    }
};
KeyStroke cStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK);
inputMap.put(cStroke,  actionListener);

It did not print activated.

I have read JTable: override CTRL+C behaviour but it does not contain an answer, at least not a specific answer..


Solution

  • You can copy selected cell's content to the clipboard like this:

    import javax.swing.*;
    import java.awt.Toolkit;
    import java.awt.datatransfer.StringSelection;
    import java.awt.event.ActionEvent;
    
    public class CopyCell
    {
      public static void main(String[] args)
      {
        JTable table = new JTable(
            new String[][] {{"R1C1", "R1C2"}, {"R2C1", "R2C2"}},
            new String[] {"Column 1", "Column 2"});
    
        table.getActionMap().put("copy", new AbstractAction()
        {
          @Override
          public void actionPerformed(ActionEvent e)
          {
            String cellValue = table.getModel().getValueAt(table.getSelectedRow(), table.getSelectedColumn()).toString();
            StringSelection stringSelection = new StringSelection(cellValue);
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, stringSelection);
          }
        });
    
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new JScrollPane(table));
        f.setBounds(300, 200, 400, 300);
        f.setVisible(true);
      }
    }