- PR -

JTableのセルのスピンボックスの動作について

1
投稿者投稿内容
いなふみ
常連さん
会議室デビュー日: 2005/09/14
投稿数: 20
投稿日時: 2007-03-31 23:52
JDK1.4にてアプレットの開発を行っています。
JSpinner型のセルエディタクラスを作成し、JTableにスピンボックスセルを
作成しました。
このスピンボックスですが、値を直接入力しEnterキーを押下すると入力した値が
確定されますが、直接入力後Tabキー又はマウスでスピンボックスからフォーカスアウトすると
入力した値が確定されず、変更前の値に戻ってしまいます。
直接入力後、フォーカスアウト時変更した値を確定させるにはどのようにしたらよいのでしょうか?
どなたか教えて下さい。

下記、スピンボックス型のセルエディタクラスのソースです。
-------------------------------------------------------------------------------
private static class CommonJSpinnerEditor extends AbstractCellEditor implements TableCellEditor {
private JSpinner field = new JSpinner();

public JSpinnerEditor(JSpinner spinner) {
field = spinner;
}

public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
setValue(value);
return field;
}

public Object getCellEditorValue() {
return field.getValue();
}

private void setValue(Object data) {
field.setValue((Double)data);
}
}
-------------------------------------------------------------------------------
a-san
ベテラン
会議室デビュー日: 2004/06/01
投稿数: 53
投稿日時: 2007-04-01 18:02
JSpinnerを複数生成しているところがおかしいですね。
セルエディタもJSpinnerも使い回しされるので1つだけオブジェクトを生成すればOKです。その辺に原因があるのではないでしょうか?
以下が私が試したソースです。
コード:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

class JSpinnerTable extends JTable {
    private static class JSpinnerEditor extends AbstractCellEditor implements
            TableCellEditor {
        private JSpinner field = new JSpinner(); // ここでスピナを作っているので、

        public JSpinnerEditor(/*JSpinner spinner*/) { // ココは不要
            //field = spinner;
        }
        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            setValue(value);
            return field;
        }
        public Object getCellEditorValue() {
            return field.getValue();
        }
        private void setValue(Object data) {
            field.setValue((Double) data);
        }
    }
    JSpinnerTable(int row, int column) {
        super(row, column);
        for (int i=0; i<row; i++) {
            setValueAt(new Double(i), i, 1);    //1カラム目のみ値をセット
        }
    }
    JSpinnerEditor spinEditor = new JSpinnerEditor();
    public TableCellEditor getCellEditor(int row, int column) {
        if (column == 1) return spinEditor; // 1カラム目のみスピナ
        return super.getCellEditor(row, column);
    }
    public static void main(String[] args) {
        JTable table = new JSpinnerTable(10, 10);
        JFrame frame = new JFrame("JSpinnerTable");
        frame.getContentPane().add(table);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(640, 480);
        frame.setVisible(true);
    }
}

いなふみ
常連さん
会議室デビュー日: 2005/09/14
投稿数: 20
投稿日時: 2007-04-04 07:51
a-sanさん、返信ありがとうございます。

a-sanのソースで動作を確認したところ、やはり直接入力後Tabキーを押下
又はマウスで別のセルをクリックすると入力前の状態に戻ってしまいます。

JSpinnerにChangeLisnerを追加しSystem.out.printを入れてみたら
Tabキーを押下、マウスで別セルをクリックすると
@getCellEditorValue()
AstateChanged(ChangeEvent e)
の順にイベントが発生していました。
セルエディタのイベントの前にスピンボックスのイベントを発生出来ないのでしょうか?

すみませんが、よろしくお願いします。
a-san
ベテラン
会議室デビュー日: 2004/06/01
投稿数: 53
投稿日時: 2007-04-04 21:15
再現方法を勘違いしていました。たしかに、私のソースでも再現します。
以下のように修正すればよいでしょう。
それと、値がDoubleなら明示的にSpinerModelを実数として指定しないと、Integerが格納されてしまうときがあるようです。
コード:

public Object getCellEditorValue() {
try {
field.commitEdit();
} catch (ParseException e1) {
// 数値以外が入力された!
e1.printStackTrace();
}
return field.getValue();
}

private JSpinner field = new JSpinner(new SpinnerNumberModel(0.0, -100.0, 100.0, 0.1));


http://www.hcn.zaq.ne.jp/no-ji/javamemo/javax_swing_table_TableCellEditor.html

[ メッセージ編集済み 編集者: a-san 編集日時 2007-04-04 21:17 ]
1

スキルアップ/キャリアアップ(JOB@IT)