2012-04-30 30 views
2

TableRowSorter/DefaultRowSorterが提供するものとは異なる挿入動作を持つJTableが必要です。カスタム挿入動作が必要な場合、RowSorterのカスタム実装を行う必要がありますか?

ユーザーが行を挿入するときに、新しく挿入された行がカーソルがあった場所の下に移動し、カーソルが新しく挿入された行に配置されるような表が必要です。 私は、例えば上に示してみましょう: - :

0. Row 1 
1. Row 2 <-- cursor here 
2. Row 3 
3. Row 4 

ユーザカーソルが2行目であり、ユーザが挿入をトリガ

初期状態表は、4行を有します。新しく挿入された行が下に表示され、カーソルもそこに移動します。

0. Row 1 
1. Row 2 
2. New row <-- cursor here 
3. Row 3 
4. Row 4 

この問題を解決する方法は2つあります。

最初のアプローチはモデルを変更することです。そのため、モデル内の適切な場所に挿入が行われます。モデルインデックスは挿入された行の下のすべての行で変更されることを意味するので、私はこの解決策が嫌いです。これは私が必要とするものを達成する最も簡単な方法ですが、私が言ったように、モデルインデックスによって引き起こされる潜在的に大きなオーバーヘッドを犠牲にして...

2番目のアプローチは、独自のvideToModel []を維持するRowSorterを実装することですおよびmodelToView []配列を作成し、行が挿入されたときに正しい順序を維持します。もちろん、私はTableRowSorterを拡張して始めましたが、modelToViewとviewToModelはプライベート配列なので、アクセスできません。ローがフィルタリングされると問題が発生します。

私は自分のRowSorter実装を書くことを避けようとしています。

UPDATE 2013-10-07: 私は自分のRowSorterを実装することでこれを達成しました。両方のアプローチを試した後、私は2番目のアプローチがより柔軟になることを認識しました。

+0

モデルの途中でデータを挿入する際の具体的なパフォーマンスのヒットを知っていますか?そうでなければ、正しいモデルインデックス(選択された行のビューインデックスから変換されたもの)で 'DefaultTableModel.insertRow()'を呼び出すことで、最初のオプションに傾いています。 –

答えて

1

RowSorterを使用して正しくソートするJTableを取得する「正しい」方法は、AbstractTableModel.getColumnClass(int)を上書きすることです。次に、DefaultRowSorter.setSortKeys()を呼び出してソート順を指定することができます。

これらのメソッドを使用すると、任意の順序でモデルに行を追加/削除し、「正しい」ソート順で表示されます。

特殊な並べ替え、つまりオブジェクトのcompareTo()メソッド以外のソートを必要とする場合は、DefaultRowSorter.setComparator()と呼んで、独自の比較関数を使用してその列を処理できます。

私はあなたが「カーソル」によって何を意味するかわからないんだけど、何か新しく挿入された行が選択されるべきであることを意味している場合、ビューインデックスをとる、JTable.setRowSelectionInterval()を呼び出すことによって達成されるものなので、彼らがする必要があります変換されます(たとえば、モデル索引、おそらく挿入したモデルの最後の行をビュー索引に変換します)。

+0

ロブ、私はそれが簡単だと思う! :)私はここでComparatorがどのように役立つのか見当たりません...私はSortKeysをまったく持っていないかもしれませんが、カーソルがある行で挿入が起こるようにしたいと思っています! :)私は新しく挿入された行を選択する方法を知っているが、とにかくそれを言って感謝。助けようとすると+1! :) – DejanLekic

+0

ああ!私は今見ている - 申し訳ありませんが、私は通常2回説明する必要があります。ソートはテーブルにないデータに完全に基づいているので、私の最初の本能は、「ソート順」を保持するために余分な隠しカラムを追加することです。それが簡単だろうと確信していません - それについて考えて、私の答えを編集しましょう。 –

+0

私はあなたの最初の解決策が好きです。私は2番目の答えを投稿したので、これは完全にオフのようだ... –

1

オリジナルの回答を編集したばかりかどうかはわかりませんが、今は完全に間違っていると思います。

私はあなたの最初の解決策が最高だと思います。私はそれを最初に見た(またはあなたが数十万の行や何かを持っていたことを知っていた)まで、テーブルモデルのデータを高価にすることを心配しません。これはかなり高速な方法であるかもしれないように、おそらくVector.insertElementAt()オーバーヘッドの周りに方法はありませんけれども、それは、見えます、DefaultTableModelコードをちらっと見

int modelIndex = table.convertRowIndexToModel(table.getSelectedRow()); 
tableModel.insertRow(modelIndex, myRowVector); 

: -

だから、このようなものは、私が行くと思い何です...私は RowSorterをまったく使っているよりも低いオーバーヘッドだと喜んで賭けるでしょう。

+0

TableModelのアプローチでは実際には複雑です...テーブルはソート/フィルタリングされますが、カーソルがある行に挿入します...現在選択されているセル) – DejanLekic

+0

テーブルはこの行挿入とは別のものによって「ソート」されている可能性がありますか?挿入された行は常にソート順に一致するデータを取得するのでしょうか? –

+0

行を挿入するとソートが停止します。それは意味をなさない...もしそうでなければ、suerは挿入された行を見ることができず、それは複数の挿入とトラブルにつながる可能性がある。これが、カーソルのすぐ下に新しく挿入された行を表示させたいという主な理由です。行が挿入されたという即時のフィードバックが得られます。 – DejanLekic

関連する問題