LoginSignup
0
1

More than 1 year has passed since last update.

javaFX、TableViewのソート後の情報取得不具合対応

Posted at

この記事について

将来的に書く予定の「JavaFX で DynamoDB Viewer作ってみた」記事の1ステップ。
結構大きな話になると思うので、少しずつ技術ポイント毎に記事を書いて、ある一定程度の要件を満たせた段階で前述まとめ記事書く予定。

第1回記事:DynamoDBの情報を読み込んでJavaFXで表示してみる
第2回記事:JavaFXで動的にテーブル列を設定する
第3回記事:AWS java SDKでDynamoDBテーブル情報を取得してみる
第4回記事:JavaFX の TableView の選択範囲をクリップボードにコピーする。
第5回記事:JavaFX でコンポーネント作って動的生成してみる
第6回記事:DynamoDBのデータ型をjava SDKから把握してみる。
第7回記事:JavaFXでジェネリック使って入力ダイアログ作成してみる
第8回記事:JavaFXで各種サイズ制御
第9回記事:JavaFXのDialogで入力値チェック制御
第10回記事:DynamoDBでPartiQLをjavaSDKで実行してみる。
第11回記事:JavaFXでダイアログの入力チェック制御をちゃんと考えてみる

※これまでの記事が基本になってます。メソッドなど細かい部分で再説明していない部分があります。不明点などありましたらコメントなど頂けたら対応しようと思います。

今回の対応問題

  • テーブルの内容をソートした後、行の詳細を開くと、ソート前位置のデータが表示される
  • テーブルの列を並べ替えた後、コピペすると、並び替え前の列の情報が取得される

現在の進捗

特に画面上の変更は無いので画像は省略。
今回の修正(github)

問題の原因

テーブルの列を並べ替えても中身の情報リストは並び変わらない

TableViewでは、ドラッグで列の移動が可能。

セル文字列取得部分
// TableView<ObservableList<String>> tableResultList;
tableResultList.getItems().get(wkRow).get(wkCol);

get(wkRow) 部分では、ちゃんとソート後の表示行の情報が取得される。
しかし、取得されるObservableList<String>の中はテーブルの列並び替えではソートされない。

詳細表示時、データ保持クラスからレコードを取得している

TableViewでは行ソートが可能。詳細情報は自前で作成したデータ保持クラスから取得するが、データ保持クラスのデータはソートしていないので、表示位置のインデックスでデータ取得するとずれてしまう。

修正する

カラム移動に起因する問題に対しての方針

TableColumnに設定できるId情報を活用する

初期処理でカラムに識別情報セットしておく

TableColumn#setIdで、カラムの識別情報を取得できる。TableView初期化時にデータのキー文字列をセットしておく。

カラム初期化部分
TableColumn<DynamoDbViewRecord, String> dataCol = new TableColumn<>(columnName);
dataCol.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().get(finalColIdx)));
// ここで設定
dataCol.setId(columnName);

クリップボードへコピー処理時

表示上のカラム位置の識別情報を取得

wkColは表示上のカラム位置
String colName = tableResultList.getColumns().get(wkCol).getId();

カラム名から初期カラム位置を取得

現時点で、データセットはTableViewとは別に保持している。そちらではカラム名のリストを所持しているので、そのキー名からデータ位置を取得。キー値にインデックス取得した方が手っ取り早いが、今後の為に識別子としてカラム名を利用する。TableViewのヘッダ名でも代用できると言えば代用できるが、今後、表示している部分に何か機能追加するかもしれないので今のうちから分離しておく。

データ保持クラスに関数追加
public Integer getColumnIndexByName(String colName) {
    if (colNameIndex.containsKey(colName)) {
        return colNameIndex.get(colName);
    }
    return -1;
}

セル文字列取得部

最終形
String selColName = tableResultList.getColumns().get(wkCol).getId();
int wkColIdx = dynamoDbResult.getColumnIndexByName(selColName);
String wkCellStr = tableResultList.getItems().get(wkRow).get(wkColIdx);

行ソート問題に対する方針

TableViewは文字列のリストだけではなく、任意のクラスを行データとして使用できる。
このツールは動的にカラムが変わるので、本体はObservableList<String>としていた。今回は、それに加えてデータのインデックスも保持するクラスを作成して、それをテーブルのレコードとする。
その上で、データ保持クラスからのデータ取得にはこのインデックスを使用する。

TableView用クラス
@Data
@Builder
public class DynamoDbViewRecord {
    int index;
    ObservableList<String> data = FXCollections.observableArrayList();
}
選択行のデータインデックス取得関数
private int getCurrentDataIndex() {
    TableViewSelectionModel<DynamoDbViewRecord> selectedModel = tableResultList.getSelectionModel();
    DynamoDbViewRecord selRec = selectedModel.getSelectedItem();
    if (selRec == null) {
        return -1;
    }
    return selRec.getIndex();
}

※この変更により、列移動時のソースも変更。そこらへんの最終ソースは こちら(github) から。

次回予定

export,importつけたいと思っています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1