Copy JTable cell value with right click

I am showing some results in a JTable that consists of 2 columns.

File - Result

I have implemented JPopupMenu which displays a copy entry and I am trying to copy the value of a cell where I right-clicked.

filelistTable.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if(SwingUtilities.isRightMouseButton(e)) { TablePopupMenu popup = new TablePopupMenu(filelistTable, e.getPoint()); filelistTable.setComponentPopupMenu(popup); } } }); 

-

  public TablePopupMenu(JTable table, Point p) { this.table = table; this.p = p; JMenuItem mntmKopieren = new JMenuItem("Kopieren"); mntmKopieren.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { copyCellToClipboard(); } }); add(mntmKopieren); } public void copyCellToClipboard() { int r = table.rowAtPoint(p); int c = table.columnAtPoint(p); System.out.println(table.getValueAt(table.convertRowIndexToView(r), table.convertRowIndexToView(c))); StringSelection entry = new StringSelection(table.getValueAt(table.convertRowIndexToView(r), table.convertRowIndexToView(c)).toString()); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents( entry, this ); } 

Anyway, this only works for a small number of tests. Am I doing something wrong or is something missing? It looks as if the cell would not even be correctly selected.

+4
source share
1 answer

Two things turn off slightly:

  • setting the Popup component in a click is too late in the mouseEvents sequence (pop-ups usually start when clicked or released, which happen before clicking)
  • the value is taken from the wrong cell: all coordinates in JTable are in the coordinate system, their conversion to view the coordinates will be completely disabled.

This suggests that getting the context associated with the cell is poorly supported. Often best (snippet below)

  • override getPopupLocation (MouseEvent) and save the location somewhere
  • implement a popup / action to access location

It doesnโ€™t work (as it should be done in a well-organized application), the pop-up window may be caused by the keyboard: if this happens, you will need to provide some other marker (fi focused cell) in order to act.

 final String popupLocation = "table.popupLocation"; final JTable table = new JXTable(new AncientSwingTeam()) { @Override public Point getPopupLocation(MouseEvent event) { // event may be null if triggered by keyboard, fi // thanks to @Mad for the heads up! ((JComponent) event.getComponent()).putClientProperty( popupLocation, event != null ? event.getPoint() : null); return super.getPopupLocation(event); } }; JPopupMenu popup = new JPopupMenu(); Action printLocation = new AbstractAction("print cell") { @Override public void actionPerformed(ActionEvent e) { Point p = (Point) table.getClientProperty(popupLocation); if (p != null) { // popup triggered by mouse int row = table.rowAtPoint(p); int column = table.columnAtPoint(p); LOG.info("" + table.getValueAt(row, column)); } else { // popup triggered otherwise // could choose fi by leadRow/ColumnSelection ... } } }; popup.add(printLocation); table.setComponentPopupMenu(popup); 

Edit (caused by crazy comment):

You should check MouseEvent.isPopupTrigger as the trigger point is platform dependent. That means you need to control mousePressed, mouseReleased and mouseClicked

No, this is not necessary (just tested :-): the mechanism that shows componentPopup in response to mouseEvent - occurs in BasicLookAndFeel.AWTEventHelper - does this only if it is popupTrigger.

After reading the api doc (should have done yesterday ;-) again, it turns out that the method is always called before componentPopup is displayed, that is, also, if it is launched in other ways, the fi keyboard. In this case, the event parameter is null - and the source code will blow. On the bright side, with this guarantee, the entire logic of finding the target cell / s can be transferred to this method. They didnโ€™t try, although perhaps this is not feasible (fi if then the location should be based on leadRow / ColumnSelection, which cannot be fully processed at this time)

+5
source

Source: https://habr.com/ru/post/1435018/


All Articles