【问题标题】:How can I select a table row with a single click using a custom TableCellEditor?如何使用自定义 TableCellEditor 通过单击选择表格行?
【发布时间】:2012-01-04 00:23:12
【问题描述】:

我有一个 JTable 和一个自定义 TableCellRenderer 和一个自定义 TableCellEditor。默认情况下,第一次点击表格行从renderer切换到editor,第二次点击选择行。

有什么方法可以让我在 单击 时选择行(并切换到编辑器)?

我试过用:

table.getSelectionModel().setSelectionInterval(row, row);

在我的getTableCellEditorComponent 中但它不起作用,如果我将它添加到我的getTableCellRendererComponent 中它会起作用,但只是有时。

这是一个完整的例子:

public class SelectRowDemo extends JFrame {

    public SelectRowDemo() {
        CellRendererAndEditor rendererAndEditor = new CellRendererAndEditor();
        StringTableModel model = new StringTableModel();
        JTable table = new JTable(model);
        table.setDefaultEditor(String.class, rendererAndEditor);
        table.setDefaultRenderer(String.class, rendererAndEditor);

        model.addElement("");
        model.addElement("");
        model.addElement("");

        add(new JScrollPane(table));
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception e) {
                    e.printStackTrace();
                }

                new SelectRowDemo();
            }

        });
    }

    class CellRendererAndEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

        private final JLabel renderer = new JLabel();
        private final JLabel editor = new JLabel();

        @Override
        public Object getCellEditorValue() {
            return editor.getText();
        }

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

            String str = "renderer ";
            str += (isSelected) ? "selected" : "not selected";

            renderer.setText(str);
            return renderer;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int row, int column) {

            table.getSelectionModel().setSelectionInterval(row, row);

            String str = "editor ";
            str += (isSelected) ? "selected" : "not selected";

            editor.setText(str);
            return editor;
        }

    }

    class StringTableModel extends AbstractTableModel {

        private final List<String> data = new ArrayList<String>();

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public Object getValueAt(int row, int column) {
            return data.get(row);
        }

        @Override
        public Class<?> getColumnClass(int column) {
            return String.class;
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return true;
        }

        @Override
        public void setValueAt(Object aValue, int row, int column) {
            if(aValue instanceof String) {
                data.set(row, (String)aValue);
                fireTableRowsUpdated(row, column);
            } else throw new IllegalStateException("aValue is not a String");
        }

        public void addElement(String s) {
            data.add(s);
        }

    }

}

【问题讨论】:

  • 你试过了吗XxxCellEditor#setClickCountToStart()
  • 您不应该尝试在编辑器中更改选择模型(或表格的任何属性)。编辑器是用来编辑的。
  • @mKorbel:该方法不相关。
  • 我不明白这个问题的最终目标。是好奇心吗?如果调用了编辑器,那么显然该行已被选中。为什么编辑不能假设这一点?编辑器的目的是允许用户输入新数据,然后将数据保存在模型中。数据是否保存正确?如果您尝试基于行对数据进行某种验证,那么我猜这应该在编辑器的停止编辑方法中完成,此时我猜所选行可用。
  • 我正面临这个确切的问题。有人有解决办法吗?

标签: java swing jtable selection tablecelleditor


【解决方案1】:

发生的情况是表格 UI 在更改选择之前开始编辑单元格。如果在 getTableCellEditor() 和 shouldSelectCell() 中放置 println,编辑器会首先被调用,isSelected == false,然后它会调用 shouldSelectCell 并更改选择。

您可以在 BasicTableUI.adjustSelection(MouseEvent) 中确切地看到它发生的位置。

  boolean dragEnabled = table.getDragEnabled();

            if (!dragEnabled && !isFileList && table.editCellAt(pressedRow, pressedCol, e)) {
                setDispatchComponent(e);
                repostEvent(e);
            }

            CellEditor editor = table.getCellEditor();
            if (dragEnabled || editor == null || editor.shouldSelectCell(e)) {
                table.changeSelection(pressedRow, pressedCol, 
                        BasicGraphicsUtils.isMenuShortcutKeyDown(e), 
                        e.isShiftDown());
            }

出于渲染目的,我只是将其渲染为已选择 == true,因为它会在该事件完成处理之前进行。

【讨论】:

  • 我无法听从建议。你能否详细解释一下,我该怎么做才能解决这个问题。我有一个单元格的编辑器和渲染器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多