JTable右键单击复制/粘贴菜单,只需单击一次即可复制单元格数据

时间:2014-03-22 21:05:25

标签: java swing popup jtable contextmenu

我创建了JPopupMenu。当我右键单击一个单元格时,它出现在我的JTable上。但是,我不能复制单元格中的数据,除非我先双击然后突出显示数据,然后右键单击除当前单元格以外的任何位置以显示我的弹出菜单和复制选项。

我想在单元格中复制数据,而不必双击单元格并进入单元格编辑模式,然后我需要选择数据。

我该怎么做?

popup = new JPopupMenu();
popup.setName("popupMenu");
menuItemCopy = new JMenuItem(new DefaultEditorKit.CopyAction());
menuItemCopy.setText("Copy");
menuItemCopy.setName("copy");       
popup.add(menuItemCopy);
popup.addSeparator();
menuItemPaste = new JMenuItem(new DefaultEditorKit.PasteAction());
menuItemPaste.setText("Paste");
menuItemPaste.setName("paste");
popup.add(menuItemPaste);

以下是我MouseListenerJTablemouseReleased()mousePressed()中的代码。

if(e.isPopupTrigger())
{
    JTable source = (JTable)e.getSource();
    int row = source.rowAtPoint( e.getPoint() );
    int column = source.columnAtPoint( e.getPoint() );

    gridView.popup.show(e.getComponent(), e.getX(), e.getY());              
}

3 个答案:

答案 0 :(得分:2)

两件事......

  1. 我不确定您希望DefaultEditorKit.CopyActionDefaultEditorKit.PasteAction如何使用JTable,这些假设与JTextComponents一起使用...
  2. JTable只会突出显示按下左键的行(或键盘导航更改),默认情况下单击鼠标右键不会。
  3. 现在,我想使用JTable组件弹出支持,但是一旦检测到弹出触发器,它似乎会消耗所有鼠标事件,这使得它(接近)无法突出显示右键单击行/列。

    相反,我最终在我的highlight中添加了MouseListener方法,突出了相关的行/列,然后触发弹出窗口。

    我这样做的原因是,与复制和粘贴相关联的Action除了表格之外没有其他任何概念,因此他们不知道哪些行/列点击了。

    这使得这些行动可以专注于担心选择。

    通过自定义transferable将内容直接复制到系统剪贴板,这样可以保留单元格的原始类型,这意味着您在粘贴对象时无需重新构建对象。

    import java.awt.Component;
    import java.awt.EventQueue;
    import java.awt.Point;
    import java.awt.Toolkit;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.FlavorEvent;
    import java.awt.datatransfer.FlavorListener;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.event.ActionEvent;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.AbstractAction;
    import static javax.swing.Action.NAME;
    import javax.swing.JFrame;
    import javax.swing.JPopupMenu;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    
    public class TestTable100 {
    
        public static void main(String[] args) {
            new TestTable100();
        }
    
        public TestTable100() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    DefaultTableModel model = new DefaultTableModel();
                    model.addColumn("Type");
                    model.addColumn("Column");
                    for (File file : new File(System.getProperty("user.home")).listFiles()) {
                        model.addRow(new Object[]{file, file});
                    }
    
                    JTable table = new JTable(model);
                    table.getColumnModel().getColumn(0).setCellRenderer(new FirstCellRenderer());
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new JScrollPane(table));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
    
                    final JPopupMenu pm = new JPopupMenu();
                    pm.add(new CopyAction(table));
                    pm.add(new PasteAction(table));
    
                    table.addMouseListener(new MouseAdapter() {
    
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            if (e.isPopupTrigger()) {
                                highlightRow(e);
                                doPopup(e);
                            }
                        }
    
                        @Override
                        public void mouseReleased(MouseEvent e) {
                            if (e.isPopupTrigger()) {
                                highlightRow(e);
                                doPopup(e);
                            }
                        }
    
                        protected void doPopup(MouseEvent e) {
                            pm.show(e.getComponent(), e.getX(), e.getY());
                        }
    
                        protected void highlightRow(MouseEvent e) {
                            JTable table = (JTable) e.getSource();
                            Point point = e.getPoint();
                            int row = table.rowAtPoint(point);
                            int col = table.columnAtPoint(point);
    
                            table.setRowSelectionInterval(row, row);
                            table.setColumnSelectionInterval(col, col);
                        }
    
                    });
                }
            });
        }
    
        public class FirstCellRenderer extends DefaultTableCellRenderer {
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value,
                            boolean isSelected, boolean hasFocus, int row, int column) {
    
                File f = (File) value;
    
                super.getTableCellRendererComponent(table,
                                value, isSelected, hasFocus, row, column);
                String prefix = f.isDirectory() ? "DIR" : "FILE";
                setText(prefix);
    
                return this;
            }
        }
    
        public class CopyAction extends AbstractAction {
    
            private JTable table;
    
            public CopyAction(JTable table) {
                this.table = table;
                putValue(NAME, "Copy");
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                int row = table.getSelectedRow();
                int col = table.getSelectedColumn();
    
                Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
                cb.setContents(new CellTransferable(table.getValueAt(row, col)), null);
            }
    
        }
    
        public class PasteAction extends AbstractAction {
    
            private JTable table;
    
            public PasteAction(JTable table) {
                this.table = table;
                putValue(NAME, "Paste");
                final Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
                cb.addFlavorListener(new FlavorListener() {
                    @Override
                    public void flavorsChanged(FlavorEvent e) {
                        setEnabled(cb.isDataFlavorAvailable(CellTransferable.CELL_DATA_FLAVOR));
                    }
                });
                setEnabled(cb.isDataFlavorAvailable(CellTransferable.CELL_DATA_FLAVOR));
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                int row = table.getSelectedRow();
                int col = table.getSelectedColumn();
    
                Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
                if (cb.isDataFlavorAvailable(CellTransferable.CELL_DATA_FLAVOR)) {
                    try {
                        Object value = cb.getData(CellTransferable.CELL_DATA_FLAVOR);
                        table.setValueAt(value, row, col);
                    } catch (UnsupportedFlavorException | IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
    
        }
    
        public static class CellTransferable implements Transferable {
    
            public static final DataFlavor CELL_DATA_FLAVOR = new DataFlavor(Object.class, "application/x-cell-value");
    
            private Object cellValue;
    
            public CellTransferable(Object cellValue) {
                this.cellValue = cellValue;
            }
    
            @Override
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[]{CELL_DATA_FLAVOR};
            }
    
            @Override
            public boolean isDataFlavorSupported(DataFlavor flavor) {
                return CELL_DATA_FLAVOR.equals(flavor);
            }
    
            @Override
            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                if (!isDataFlavorSupported(flavor)) {
                    throw new UnsupportedFlavorException(flavor);
                }
                return cellValue;
            }
    
        }
    }
    

答案 1 :(得分:1)

以下是使用 Clipboard

的代码

要遵循的步骤:

  • 声明一些变量来存储当前选定的行和列索引

    private static int rowIndex;
    private static int columnIndex;
    
  • ActionListener

    上添加MenuItem
    menuItemCopy.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            StringSelection stringSelection = new StringSelection(String.valueOf(table1
                    .getModel().getValueAt(rowIndex, columnIndex)));
            Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
            clpbrd.setContents(stringSelection, null);
        }
    });
    
    menuItemPaste.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
            try {
                table1.getModel().setValueAt(clpbrd.getData(DataFlavor.stringFlavor), rowIndex,
                        columnIndex);
            } catch (UnsupportedFlavorException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    });
    
  • MouseListener上添加JTable以更新rowIndexcolumnIndex的值,最后显示JPopupMenu

    table1.addMouseListener(new MouseAdapter() {
    
        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() == 3) {
                rowIndex = table1.rowAtPoint(e.getPoint());
                columnIndex = table1.columnAtPoint(e.getPoint());
    
                popup.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    
    });
    

答案 2 :(得分:0)

int row = source.rowAtPoint(e.getPoint());
int column = source.columnAtPoint(e.getPoint());
Object valueInCell = table.getValueAt(row, column);

简单!