Tides_of_War

盤根錯節

JTable 編集中のセルの値を取得する

以下の画像は単純なJTableのサンプルです。「確認」ボタンを押した際に、JTableの各セルの値をメッセージダイアログにて表示します。
しかし3行3列目に入力されているはずの「i」が取得できておらず、nullが表示されてしまっています。

画像からは分かりづらいのですが、これは該当のセルを編集している状態で「確認」ボタンを押してしまっていることが原因です。
編集を完了(フォーカスを移動)させれば、値は取得できますが、ユーザにそれを強いるのは不親切でしょう。セルの編集中に、ボタンを押す場面は普通に考えられます。

以下のコードはJTableのセルが編集中にボタンを押された場合、編集を終了させる(値を確定させる)サンプルコードです。

package table;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

public class StopCellEditing extends JFrame {

    private JPanel contentPane;
    private JTable table;
    private JButton button;

    public StopCellEditing() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 400, 250);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JScrollPane scrollPane = new JScrollPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);

        table = new JTable();
        table.setModel(new DefaultTableModel(
            new Object[][] {
                {null, null, null},
                {null, null, null},
                {null, null, null}
            },
            new String[] {
                "1", "2", "3"
            }
        ));
        scrollPane.setViewportView(table);

        button = new JButton("確認");
        // ボタンを押した際にテーブルの入力内容を表示する
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // テーブルを編集中の場合は停止させる
                if (table.isEditing()) {
                    table.getCellEditor().stopCellEditing();
                }

                String values = "";
                for (int i = 0; i < table.getRowCount(); i++) {
                    for (int j = 0; j < table.getColumnCount(); j++) {
                        values = values +
                                (String)table.getValueAt(i, j) + " ";
                    }
                    values = values + "\r\n";
                }
                JOptionPane.showMessageDialog(null, values);
            }
        });
        contentPane.add(button, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        StopCellEditing frame = new StopCellEditing();
        frame.setVisible(true);
    }
}

要するに値を取得する前に以下の3行で編集を終了させるということですね。
(先頭に半角空白を入れると何故か勝手に詰められるので全角空白で代用してます。)

if (table.isEditing()) {
  table.getCellEditor().stopCellEditing();
}


以下実行結果です。今度は編集中にボタンを押した場合、編集が終了させられるため問題なく値が取得できることを確認できます。