简体   繁体   中英

How to change JTable cell text while editing?

The effect I am trying to achieve is: Every time the user starts editing a cell in the table, I want the text of the cell to erase whatever text was originally there (the 'Start Editing' part), and if no new text is added, to just set the text to what the original text was ('Stop Editing')

It appears to me that I was wrong in assuming that setValueAt would change the text in a cell that is currently being edited - instead it seems that it will only change the value of the cell once the editing has finished (which means I probably won't need the code I put under 'Stop Editing' after all)

However, if this is indeed the case, I have no clue as to how to edit the text in a cell that is currently being edited, and so this is my question: How do I change the text in a cell that is currently being edited?

For example, making it so that when I start editing 'Test bb,' the cell changes to having no text:

在此处输入图片说明

Here is my code:

 private void tblEntriesPropertyChange(java.beans.PropertyChangeEvent evt) {                                          
    swb.tablePropertyChange(tblEntries, evt);
}                 

public void tablePropertyChange(JTable jtable, PropertyChangeEvent evt) {
    TableModel mdl = jtable.getModel();
    int c = jtable.getSelectedColumn();
    int r = jtable.getSelectedRow();
    if (r >= 0 && c >= 0) {
        String text = mdl.getValueAt(r, c) + "";
        if (evt.getNewValue() == null) {
            System.out.println("Stop Editing");
            String newText = mdl.getValueAt(r, c) + "";
            if (newText.length() <= 0) {
                jtable.setValueAt(text, r, c); // also tried: mdl.setValueAt(text, r, c);
            }
        } else {
            System.out.println("Start Editing");
            jtable.setValueAt("", r, c); // also tried: mdl.setValueAt("", r, c);
        }
    }
}

Trying to "intervene" in this kind of process can be a real trick. You have two basic options. Either you can create a custom JTable implementation and make sure that you pass something like null to whatever editor becomes active, which locks you into a single use JTable , or you can supply your own editor.

public class CleanCellEditor extends DefaultCellEditor {

    public static CleanCellEditor make() {
        JTextField field = new JTextField();
        field.setBorder(null);
        System.out.println("make");

        return new CleanCellEditor(field);
    }

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

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        return super.getTableCellEditorComponent(table, null, isSelected, row, column);
    }

}

While this is slightly better, in the fact that you can apply it to any implementation of JTable , it does mean you'll need to create one for all possible values/types you table might need support

As a basic example...

import java.awt.Component;
import java.awt.EventQueue;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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(new Object[]{"A", "B", "C", "D"}, 0);
                for (int row = 0; row < 10; row++) {
                    Vector data = new Vector(model.getColumnCount());
                    for (int col = 0; col < model.getColumnCount(); col++) {
                        data.add(row + "x" + col);
                    }
                    model.addRow(data);
                }

                JTable table = new JTable(model);
                table.setDefaultEditor(Object.class, CleanCellEditor.make());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class CleanCellEditor extends DefaultCellEditor {

        public static CleanCellEditor make() {
            JTextField field = new JTextField();
            field.setBorder(null);
            System.out.println("make");

            return new CleanCellEditor(field);
        }

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

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            return super.getTableCellEditorComponent(table, null, isSelected, row, column);
        }

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM