从 cellrenderer 视图中的 JTable 复制值

Posted

技术标签:

【中文标题】从 cellrenderer 视图中的 JTable 复制值【英文标题】:JTable copy value from view of cellrenderer 【发布时间】:2014-10-12 13:45:38 【问题描述】:

我有一个带有单元格渲染器的JTable,我的表格不可编辑。当我选择一个单元格并复制(ctrl-c)值时,它的复制不是单元格中显示的,它正在复制存储在模型中的值。如何复制表格中显示的单元格值。

public class TableDemo 

    public static void main(String[] args) 
        Vector<String> values = new Vector<String>();
        values.add("Val1");
        values.add("Val2");
        JTable table = new JTable(new Object[][]   "key", values ,
                 "key2", values  , new String[]  "Col1", "Col2" );

        table.getColumnModel().getColumn(1).setCellRenderer(new MyTableCellRenderer());
        table.setCellSelectionEnabled(true);
        JFrame jf = new JFrame();
        jf.getContentPane().add(table);

        jf.setSize(500, 500);

        jf.setVisible(true);
    


class MyTableCellRenderer extends DefaultTableCellRenderer 

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) 
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);

        @SuppressWarnings("unchecked")
        Vector<String> values = (Vector<String>) value;
        setText(values.get(row));

        return this;
    

【问题讨论】:

渲染器只是关于绘制 JTables 视图,而不是,不要永远不要在里面创建任何对象,例如Vector 值 = (Vector) 值; 请问什么是我如何复制表格中显示的单元格值。,DYM?复制 - 粘贴,默认 ctrl+c - ctrl+v/x(或 ctrl+insert - shift+insert),然后使用 TableCellEditor 完成 是的,我需要用 ctrl-c 复制。你是说不可能获得 cellrenderer 的价值?顺便说一下,我的表格应该是不可编辑的,所以不能使用 celleditor。 javaworld.com/article/2077579/learn-java/… 【参考方案1】:

您需要实现自己的复制命令。这是解决方案。

import java.awt.Component;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;


public class TableDemo 

    public static void main(String[] args) 
        final Vector<String> values = new Vector<String>();
        values.add("Val1");
        values.add("Val2");
        final JTable table = new JTable(new Object[][]   "key", values ,
                 "key2", values  , new String[]  "Col1", "Col2" );

        table.getColumnModel().getColumn(1).setCellRenderer(new MyTableCellRenderer());
        table.registerKeyboardAction(new CopyAction(), KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_FOCUSED);
        table.setCellSelectionEnabled(true);
        final JFrame jf = new JFrame();
        jf.getContentPane().add(table);

        jf.setSize(500, 500);

        jf.setVisible(true);
    

    private static class CopyAction extends AbstractAction 

        /**
         * @inheritDoc
         */
        @Override
        public void actionPerformed(ActionEvent e) 
            final JTable tbl = (JTable) e.getSource();
            final int row = tbl.getSelectedRow();
            final int col = tbl.getSelectedColumn();
            if (row >= 0 && col >= 0) 
                final TableCellRenderer renderer = tbl.getCellRenderer(row, col);
                final Component comp = tbl.prepareRenderer(renderer, row, col);
                if (comp instanceof JLabel) 
                    final String toCopy = ((JLabel) comp).getText();
                    final StringSelection selection = new StringSelection(toCopy);
                    final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                    clipboard.setContents(selection, selection);
                
            
        

    


@SuppressWarnings("serial")
class MyTableCellRenderer extends DefaultTableCellRenderer 
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) 
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);

        @SuppressWarnings("unchecked")
        final
        Vector<String> values = (Vector<String>) value;
        setText(values.get(row));

        return this;
    

【讨论】:

包裹在 SuppressWarningsreturn this 中的所有内容都是错误的 JTables 视图可以在不触及渲染器的情况下返回其值,包括。在渲染器中也修改了值(例如图标) @mKorbel 我已经简单地扩展了问题中的示例。但你是对的,渲染器中的代码很糟糕。 @mKorbel 你有没有建议如何缩短 actionPerformed 中的代码? 您实际上应该委托给真正的表格单元格渲染器,否则如果您使用的外观使用不同的外观(例如 Aqua),您的表格外观将与其他表格不匹配. (或者,像使用 SwingX 之类的东西,复制甚至可以复制呈现的值而无需执行任何操作。)

以上是关于从 cellrenderer 视图中的 JTable 复制值的主要内容,如果未能解决你的问题,请参考以下文章

从 cellrenderer 调用父函数,例如在 vuejs ag-grid-vue 上发出

AG Grid:cellRenderer 禁用值格式化程序

为啥在gtkmm中使用CellRenderer时TreeView中会显示两次信息

ag-grid cellRenderer元素的动作不起作用

当列具有返回 React 组件的 cellRenderer 时,AgGridReact rowData 更改时出错

警告:子上下文类型失败:提供给“CellRenderer”的“数字”类型的子上下文“virtualizedCell.cellKey”无效,应为“字符串”