【问题标题】:how to copy content of the jtable to clipboard如何将jtable的内容复制到剪贴板
【发布时间】:2011-01-12 17:06:57
【问题描述】:

我有 jtable 归档数据。我想为 Jbutton 的操作创建 java 代码。我的要求是当我单击按钮时,然后将 jtable 的所有内容 复制 到剪贴板。我该怎么做。

    String[] columnNames={"DATE","Steet"};
    String[][] cells=new String[ar.size()][2];
    for(int i=0;i<ar.size();i++){
        cells[i][0]=((PRIvariable)ar.get(i)).incDate;
        cells[i][1]=((PRIvariable)ar.get(i)).selectedSteer;
    }
    table = new JTable(cells,columnNames);
    table.setVisible(true);
    table.setSize(400, 400);
    js=new JScrollPane();
    js.setViewportView(table);
    js.setBounds(10, 230,500, 215);
    js.setVisible(true);
    add(js,java.awt.BorderLayout.CENTER);
  • 在这段代码中 ar 是我的数组列表。
  • 如何编写可以复制此 Jtable 内容的代码。

【问题讨论】:

    标签: java swing jtable clipboard


    【解决方案1】:

    当我过去需要这样做时,我从这里的代码开始: http://www.javaworld.com/javatips/jw-javatip77.html

    并修改为为按钮创建一个操作,该操作会将数据和列标题从表格复制到剪贴板。

    import javax.swing.*;
    import java.awt.*;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.StringSelection;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.InputEvent;
    import java.awt.event.KeyEvent;
    import java.util.StringTokenizer;
    
    
    
    
    /**
     * ExcelAdapter enables Copy-Paste Clipboard functionality on JTables. The clipboard data format used by the adapter is
     * compatible with the clipboard format used by Excel. This provides for clipboard interoperability between enabled
     * JTables and Excel.
     */
    public class ExcelAdapter implements ActionListener {
    
    
        private String rowstring, value;
        private Clipboard clipboard;
        private StringSelection stsel;
        private JTable jTable1;
    
    
        /**
         * The Excel Adapter is constructed with a JTable on which it enables Copy-Paste and acts as a Clipboard listener.
         */
        public ExcelAdapter(JTable myJTable) {
    
            jTable1 = myJTable;
            final KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK, false);
            // Identifying the copy KeyStroke user can modify this
            // to copy on some other Key combination.
            final KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK, false);
            // Identifying the Paste KeyStroke user can modify this
            //to copy on some other Key combination.
            jTable1.registerKeyboardAction(this, "Copy", copy, JComponent.WHEN_FOCUSED);
            jTable1.registerKeyboardAction(this, "Paste", paste, JComponent.WHEN_FOCUSED);
            clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        }
    
    
        /**
         * Public Accessor methods for the Table on which this adapter acts.
         */
        public JTable getJTable() {
    
            return jTable1;
        }
    
    
        public void setJTable(JTable jTable1) {
    
            this.jTable1 = jTable1;
        }
    
    
        /**
         * This method is activated on the Keystrokes we are listening to in this implementation. Here it listens for Copy
         * and Paste ActionCommands. Selections comprising non-adjacent cells result in invalid selection and then copy
         * action cannot be performed. Paste is done by aligning the upper left corner of the selection with the 1st element
         * in the current selection of the JTable.
         */
        @Override
        public void actionPerformed(ActionEvent e) {
    
            final String actionCommand = e.getActionCommand();
    
            if (actionCommand.equals("Copy")) {
    
                StringBuilder sbf = new StringBuilder();
                // Check to ensure we have selected only a contiguous block of cells.
                final int numcols = jTable1.getSelectedColumnCount();
                final int numrows = jTable1.getSelectedRowCount();
                final int[] rowsselected = jTable1.getSelectedRows();
                final int[] colsselected = jTable1.getSelectedColumns();
    
                if (!((numrows - 1 == rowsselected[rowsselected.length - 1] - rowsselected[0] &&
                        numrows == rowsselected.length) &&
                        (numcols - 1 == colsselected[colsselected.length - 1] - colsselected[0] &&
                                numcols == colsselected.length))) {
                    JOptionPane.showMessageDialog(null, "Invalid Copy Selection",
                                                  "Invalid Copy Selection",
                                                  JOptionPane.ERROR_MESSAGE);
                    return;
                }
                for (int i = 0; i < numrows; i++) {
                    for (int j = 0; j < numcols; j++) {
                        sbf.append(jTable1.getValueAt(rowsselected[i], colsselected[j]));
                        if (j < numcols - 1) {
                            sbf.append('\t');
                        }
                    }
                    sbf.append('\n');
                }
                stsel = new StringSelection(sbf.toString());
                clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                clipboard.setContents(stsel, stsel);
    
            } else if (actionCommand.equals("Paste")) {
    
                System.out.println("Trying to Paste");
                final int startRow = (jTable1.getSelectedRows())[0];
                final int startCol = (jTable1.getSelectedColumns())[0];
                try {
                    final String trString = (String) (clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor));
                    System.out.println("String is:" + trString);
                    final StringTokenizer st1 = new StringTokenizer(trString, "\n");
                    for (int i = 0; st1.hasMoreTokens(); i++) {
                        rowstring = st1.nextToken();
                        StringTokenizer st2 = new StringTokenizer(rowstring, "\t");
                        for (int j = 0; st2.hasMoreTokens(); j++) {
                            value = (String) st2.nextToken();
                            if (startRow + i < jTable1.getRowCount() &&
                                    startCol + j < jTable1.getColumnCount()) {
                                jTable1.setValueAt(value, startRow + i, startCol + j);
                            }
                            System.out.println("Putting " + value + "at row = " + startRow + i + " column = " + startCol + j);
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
    
            }
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      JTable 已经支持复制操作。 Action Map Action 展示了如何通过 JButton 轻松使用此操作,因此您不必重写代码。

      【讨论】:

        【解决方案3】:

        这是来自 javaworld(从 1999 年开始)的 ExcelAdapter 的更新版本。 Link

        使用:

        jTable1.addKeyListener(new ClipboardKeyAdapter(jTable1));
        

        ClipboardKeyAdapter.java

                public class ClipboardKeyAdapter extends KeyAdapter {
        
                private static final String LINE_BREAK = "\r"; 
                private static final String CELL_BREAK = "\t"; 
                private static final Clipboard CLIPBOARD = Toolkit.getDefaultToolkit().getSystemClipboard(); 
        
                private final JTable table; 
        
                public ClipboardKeyAdapter(JTable table) { 
                        this.table = table; 
                } 
        
                @Override 
                public void keyReleased(KeyEvent event) { 
                        if (event.isControlDown()) { 
                                if (event.getKeyCode()==KeyEvent.VK_C) { // Copy                        
                                        cancelEditing(); 
                                        copyToClipboard(false); 
                                } else if (event.getKeyCode()==KeyEvent.VK_X) { // Cut 
                                        cancelEditing(); 
                                        copyToClipboard(true); 
                                } else if (event.getKeyCode()==KeyEvent.VK_V) { // Paste 
                                        cancelEditing(); 
                                        pasteFromClipboard();           
                                } 
                        } 
                } 
        
                private void copyToClipboard(boolean isCut) { 
                        int numCols=table.getSelectedColumnCount(); 
                        int numRows=table.getSelectedRowCount(); 
                        int[] rowsSelected=table.getSelectedRows(); 
                        int[] colsSelected=table.getSelectedColumns(); 
                        if (numRows!=rowsSelected[rowsSelected.length-1]-rowsSelected[0]+1 || numRows!=rowsSelected.length || 
                                        numCols!=colsSelected[colsSelected.length-1]-colsSelected[0]+1 || numCols!=colsSelected.length) {
        
                                JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE);
                                return; 
                        } 
        
                        StringBuffer excelStr=new StringBuffer(); 
                        for (int i=0; i<numRows; i++) { 
                                for (int j=0; j<numCols; j++) { 
                                        excelStr.append(escape(table.getValueAt(rowsSelected[i], colsSelected[j]))); 
                                        if (isCut) { 
                                                table.setValueAt(null, rowsSelected[i], colsSelected[j]); 
                                        } 
                                        if (j<numCols-1) { 
                                                excelStr.append(CELL_BREAK); 
                                        } 
                                } 
                                excelStr.append(LINE_BREAK); 
                        } 
        
                        StringSelection sel  = new StringSelection(excelStr.toString()); 
                        CLIPBOARD.setContents(sel, sel); 
                } 
        
                private void pasteFromClipboard() { 
                        int startRow=table.getSelectedRows()[0]; 
                        int startCol=table.getSelectedColumns()[0];
        
                        String pasteString = ""; 
                        try { 
                                pasteString = (String)(CLIPBOARD.getContents(this).getTransferData(DataFlavor.stringFlavor)); 
                        } catch (Exception e) { 
                                JOptionPane.showMessageDialog(null, "Invalid Paste Type", "Invalid Paste Type", JOptionPane.ERROR_MESSAGE);
                                return; 
                        }
        
                        String[] lines = pasteString.split(LINE_BREAK);
        
                        for (int i=0 ; i<lines.length; i++) { 
                                String[] cells = lines[i].split(CELL_BREAK); 
                                for (int j=0 ; j<cells.length; j++) { 
                                        if (table.getRowCount()>startRow+i && table.getColumnCount()>startCol+j) { 
                                                table.setValueAt(cells[j], startRow+i, startCol+j); 
                                        } 
                                } 
                        } 
                } 
        
                private void cancelEditing() { 
                        if (table.getCellEditor() != null) { 
                                table.getCellEditor().cancelCellEditing(); 
                    } 
                } 
        
                private String escape(Object cell) { 
                        return cell.toString().replace(LINE_BREAK, " ").replace(CELL_BREAK, " "); 
                } 
        }
        

        【讨论】:

          【解决方案4】:

          Gere 的回答效果很好,但我发现将事件从 keyReleased 更改为 keyPressed 反应更灵敏

          public void keyReleased(KeyEvent event) {
          

          public void keyPressed(KeyEvent event) {
          

          根据我的经验,如果我很快释放到 V 键,keyReleased 不会总是触发,并且需要按住更长的时间而按下的键会瞬间触发。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-18
            • 1970-01-01
            • 1970-01-01
            • 2020-09-03
            • 2019-12-05
            • 2020-10-10
            相关资源
            最近更新 更多