如何在编辑时选择JTable单元格中的所有文本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在编辑时选择JTable单元格中的所有文本相关的知识,希望对你有一定的参考价值。

我想让我的可编辑JTable中的编辑器在开始编辑时选择单元格中的所有文本。我尝试了一些事情,都围绕从TableCellEditor.getTableCellEditorComponent方法返回的组件上调用JTextComponent.selectAll()。我尝试过的所有事情都没有。

在我最近的尝试中,我改变了Swing教程中的SimpleTableDemo类,以使用调用selectAll方法的自定义TableCellEditor。在调试器中,我可以看到正在调用selectAll()方法,但是表仍然进入编辑模式而不选择单元格中的文本(或者可能在显示之前清除选择)。该代码如下。谁能告诉我哪里出错了?

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.text.JTextComponent;


import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;


public class SimpleTableDemo extends JPanel {
    private boolean DEBUG = false;


    public SimpleTableDemo() {
        super(new GridLayout(1, 0));

        String[] columnNames = {"First Name",
                                "Last Name",
                                "Sport",
                                "# of Years",
                                "Vegetarian"};

        Object[][] data = {
                {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)},
                {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)},
                {"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)},
                {"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)},
                {"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)}
        };

        final JTable table = new SelectingTable(data, columnNames);
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);

        if (DEBUG) {
            table.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    printDebugData(table);
                }
            });
        }

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    private void printDebugData(JTable table) {
        int numRows = table.getRowCount();
        int numCols = table.getColumnCount();
        javax.swing.table.TableModel model = table.getModel();

        System.out.println("Value of data: ");
        for (int i = 0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j = 0; j < numCols; j++) {
                System.out.print("  " + model.getValueAt(i, j));
            }
            System.out.println();
        }
        System.out.println("--------------------------");
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        SimpleTableDemo newContentPane = new SimpleTableDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }


    class SelectingTable extends JTable {
        public SelectingTable(Object[][] data, String[] columnNames) {
            super(data, columnNames);
            TableColumnModel model = super.getColumnModel();
            for (int i = 0; i < super.getColumnCount(); i++) {
                TableColumn tc = model.getColumn(i);
                tc.setCellEditor(new SelectingEditor(new JTextField()));
            }
        }

        class SelectingEditor extends DefaultCellEditor {

            public SelectingEditor(JTextField textField) {
                super(textField);
            }

            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);
                if (c instanceof JTextComponent) {
                    JTextComponent jtc = (JTextComponent) c;
                    jtc.requestFocus();
                    jtc.selectAll();
                }
                return c;
            }
        }
    }
}
答案

Table Select All Editor应该适合你。它是首选解决方案,因此您无需继续创建自定义编辑器。这是包含整数的列应该只接受整数。随你当前的代码

您的代码部分工作。如果使用F2键开始编辑,则选择文本。但是,当您使用鼠标并双击单元格时,第二个鼠标事件将传递给编辑器,以便将插入符号放置在您单击的位置,这将删除选择。解决方案是:

final JTextComponent jtc = (JTextComponent)c;
jtc.requestFocus();
//jtc.selectAll();
SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        jtc.selectAll();
    }
});
另一答案
public class SelectAllCellEditor extends DefaultCellEditor
{
    public SelectAllCellEditor(final JTextField textField ) {
        super( textField );
        textField.addFocusListener( new FocusAdapter()
        {
            public void focusGained( final FocusEvent e )
            {
                textField.selectAll();
            }
        } );
    }
}
另一答案

JTable可以在单元中具有许多不同的组件。编辑时通常是JTextField。您需要首先获取该字段然后选择。您可以通过处理模式来获取文本的长度。此代码应该让您入门,您可能希望将其放在List选择处理程序中。即。

 ListSelectionModel rowSM = this.getSelectionModel();
 rowSM.addListSelectionListener(new ListSelectionListener() {
    public void valueChanged(ListSelectionEvent e){
       DefaultCellEditor ed = (DefaultCellEditor)this.getCellEditor();
       JTextField jf = (JTextField)ed.getComponent();
       jf.select(0, *text.length()*);
       jf.requestFocusInWindow();
    }
 });

值得注意的是,您需要找到text.length()。可能是这样的东西:

this.getModel().getValueAt(this.getSelectedRow(), this.getSelectedColumn()).length();

免责声明我没有测试过这段代码。

以上是关于如何在编辑时选择JTable单元格中的所有文本的主要内容,如果未能解决你的问题,请参考以下文章

在jTable(自动保存)中编辑后如何保存单元格中的数据?

在Jtable单元格中的复选框旁边插入文本

在jTable(自动保存)中编辑后,如何将单元格中的数据保存在sql中?

JTable-在单元格中绘制内容(文本)

如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

仅在选择时设置Jtable单元格可编辑