How to maintain JTable cell rendering after cell edit

前端 未结 1 1063
忘了有多久
忘了有多久 2020-11-22 10:22

You guys were so awesome in point me in the right direction on my last question and I have sort of an extension of my original question here:

How to set a JTable col

相关标签:
1条回答
  • 2020-11-22 10:32

    When your editor concludes, the table's editingStopped() method collects the new value via getCellEditorValue() and uses it to setValueAt() in the model. The model, in turn, should fireTableCellUpdated(), which will invoke the prescribed renderer. Extending the default should be enough to handle Number formatting. In other cases, it may be convenient to use an instance of your renderer as your editor component; this example shows a typical implementation.

    Addendum: Here's a basic example using the default editor and renderer implementations.

    Addendum: Thanks to helpful comments from @mKorbel, I've updated the example to select the cell's text for editing, as described in @camickr's article Table Select All Editor.

    RenderEditNumber

    package overflow;
    
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.event.MouseEvent;
    import java.text.NumberFormat;
    import java.util.EventObject;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.text.JTextComponent;
    
    /** @see http://stackoverflow.com/a/10067560/230513 */
    public class RenderEditNumber extends JPanel {
    
        private NumberFormat nf = NumberFormat.getCurrencyInstance();
    
        public RenderEditNumber() {
            DefaultTableModel model = new DefaultTableModel(
                new String[]{"Amount"}, 0) {
    
                @Override
                public Class<?> getColumnClass(int columnIndex) {
                    return Double.class;
                }
            };
            for (int i = 0; i < 16; i++) {
                model.addRow(new Object[]{Double.valueOf(i)});
            }
            JTable table = new JTable(model) {
    
                @Override // Always selectAll()
                public boolean editCellAt(int row, int column, EventObject e) {
                    boolean result = super.editCellAt(row, column, e);
                    final Component editor = getEditorComponent();
                    if (editor == null || !(editor instanceof JTextComponent)) {
                        return result;
                    }
                    if (e instanceof MouseEvent) {
                        EventQueue.invokeLater(new Runnable() {
    
                            @Override
                            public void run() {
                                ((JTextComponent) editor).selectAll();
                            }
                        });
                    } else {
                        ((JTextComponent) editor).selectAll();
                    }
                    return result;
                }
            };
            table.setPreferredScrollableViewportSize(new Dimension(123, 123));
            table.setDefaultRenderer(Double.class, new CurrencyRenderer(nf));
            table.setDefaultEditor(Double.class, new CurrencyEditor(nf));
            this.add(new JScrollPane(table));
        }
    
        private static class CurrencyRenderer extends DefaultTableCellRenderer {
    
            private NumberFormat formatter;
    
            public CurrencyRenderer(NumberFormat formatter) {
                this.formatter = formatter;
                this.setHorizontalAlignment(JLabel.RIGHT);
            }
    
            @Override
            public void setValue(Object value) {
                setText((value == null) ? "" : formatter.format(value));
            }
        }
    
        private static class CurrencyEditor extends DefaultCellEditor {
    
            private NumberFormat formatter;
            private JTextField textField;
    
            public CurrencyEditor(NumberFormat formatter) {
                super(new JTextField());
                this.formatter = formatter;
                this.textField = (JTextField) this.getComponent();
                textField.setHorizontalAlignment(JTextField.RIGHT);
                textField.setBorder(null);
            }
    
            @Override
            public Object getCellEditorValue() {
                try {
                    return new Double(textField.getText());
                } catch (NumberFormatException e) {
                    return Double.valueOf(0);
                }
            }
    
            @Override
            public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
                textField.setText((value == null)
                    ? "" : formatter.format((Double) value));
                return textField;
            }
        }
    
        private void display() {
            JFrame f = new JFrame("RenderEditNumber");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(this);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new RenderEditNumber().display();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题