8

皆さんは私の最後の質問で正しい方向に私を向けるのにとても素晴らしかったです、そして私はここに私の元の質問の一種の拡張を持っています:

JTable列をStringとして設定し、Doubleとしてソートするにはどうすればよいですか?

カスタムセルレンダラーを使用して価格列を$###、## 0.00としてフォーマットしたので、セルにもJTextFieldエディターを設定しました。セルの編集は、値が更新された場合を除いて、問題なく機能します。カスタムレンダラーで設定された数値形式は、セルをフォーマットしなくなったようです(編集がコミットされた後、$が失われます)。このレンダラーは、データが最初に表示された後でもセルをレンダリングすることは想定されていませんか?

私は運が悪かったので次のものを使おうとしました:

((AbstractTableModel) table.getModel()).fireTableDataChanged();

これにより、カスタムレンダラーを使用してセルを再検証および再描画して新しい値をレンダリングするようにテーブルが強制されることを期待していましたが、残念ながらこれは機能しませんでした...

私は何かが足りないのですか...明らかに、しかし何ですか?

4

1 に答える 1

10

エディターが終了すると、テーブルのeditingStopped()メソッドはを介して新しい値を収集し、それをモデルでgetCellEditorValue()使用します。setValueAt()次に、モデルは fireTableCellUpdated()、指定されたレンダラーを呼び出す必要があります。デフォルトを拡張することで、Numberフォーマットを処理するのに十分なはずです。その他の場合は、レンダラーのインスタンスをエディターコンポーネントとして使用すると便利な場合があります。このは、典型的な実装を示しています。

補遺:デフォルトのエディターとレンダラーの実装を使用した基本的な例を次に示します。

補遺:@mKorbelからの有益なコメントのおかげで、@camickrの記事TableSelectAll 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();
            }
        });
    }
}
于 2012-04-08T23:59:40.077 に答える