訂正:最初の回答は間違っていたようです。申し訳ありません。
CellのvisibilityはTableViewやCellの基底クラスの方の制御の影響を強く受けるようで、せっかくsetVisible(false)にしても直後にsetVisible(true)にされてしまうことがあるようです。多分Cell領域がTableViewの可視領域に入るとそのような動きになるのではないでしょうか(あくまで想像です)。
本件はどのような対処にするのがよいのか自分には少々難しいです。CheckBoxTableCellのようなカスタムセルの場合、setGraphic()やsetVisible()によって外観を制御しているのですが実際にどのような制御を行っているかは必ずしも明文化されてないと思います。下手に派生クラス側で制御しようとすると基底クラスに予期せぬ制御をされてしまう可能性がある以上、基底クラスの実装まで踏み込んでみないと確実な方法がわかりません。しかし本来隠蔽されているはずの実装に基づき実装するのは危険ですよね・・・。公開されている仕様のみでうまく制御できる方法が思いつけばそれはそれでよいのですが・・・
一応それらしく動くあまり乱暴ではなさそうな方法があったので一応参考までにコードを載せてみます。しかし充分にCheckBoxTableCellの振る舞いを調べた上での実装ではないのでこの実装でよいかどうかはCheckBoxTableCellがどのタイミングでsetGraphicを呼び出すかをよく調べた方がよいと思います。また、こうした対処の常でJDKのバージョンが変わる際に再度検証が必要かも知れません。JavaFXはJDK8時点では充分安定しておらずJDK9で大規模なリファクタリングが行われているようですので要注意と思います。
java
1Callback<TableColumn<Parson, Boolean>, TableCell<Parson, Boolean>> cb2 = tc -> new CheckBoxTableCell<Parson, Boolean>() {
2 @Override
3 public void updateItem(Boolean item, boolean empty) {
4 super.updateItem(item, empty);
5 updateVisiblity();
6 }
7
8 @Override
9 public void updateIndex(int i) {
10 super.updateIndex(i);
11 updateVisiblity();
12 }
13
14 private void updateVisiblity() {
15 int index = getIndex();
16 boolean visibility = index != -1 &&
17 getItem() != null &&
18 getTableView().getItems().get(index).getDataType() != 1;
19 if (!visibility)
20 setGraphic(null);
21 }
22};
23...
24checkCol.setCellFactory(cb2);
以下最初の回答
そもそもやり方が間違っているのかもしれない
個人的にはアプローチはよいと思います。ただCellの振る舞いについて注意が必要な点がありそこにはまってしまったのが原因だと思います。
###原因
Cellは特定のアイテムに結び付いているのではなく特定のプロパティの「値」に結び付いているだけなので、表示対象のBoolean値が変化した場合ならupdateItemが呼び出されますが、そうでない限りは例え別のインスタンスのプロパティーに再割り当てされたとしてもupdateItemは起動されないのです。
これは自分も全く同じことで過去にはまったのですが、ご質問を拝見したときすぐに気づけませんでした。自分にとってそれほどに勘違いしやすい仕様に思えますが、よーく考えてみると妥当な仕様だと納得した覚えがあります。表示内容は基本的に「表示しようとしている値に依存する」という考え方がベースのため「別のインスタンスに切り替わったからといってupdateItemを呼び出す必要はない」という設計なのでしょう。
###対処
updateItemによって状態を変化させるのではなく、表示対象のアイテムが切り替わったタイミングで変化させるという方法が考えられると思います。例えばソート順を変化させないならこのCellが置かれているTableRowの変化タイミングを検知すればそれができると思います。
Java
1return new CheckBoxTableCell<Parson, Boolean>() {
2 {
3 tableRowProperty().addListener((observable, oldRow, newRow) -> {
4 Parson item = (Parson)newRow.getItem();
5 setVisible(item.getDataType() != 1);
6 });
7 }
8};
しかしソート順が変化した場合はどうなるでしょうか・・・やってみてないので実験してみるとよいと思います。ちゃんと調べてないのですが最新のJDK8ではソート順が変化してもtableRowとアイテムの対応関係は変化しないのではないかと思います。
ただJDK8の途中でTableViewのソートの実装が変わったという情報を見たことがあるので念のためtableRowプロパティーとtableRowプロパティーのitemプロパティーの両方を監視した方がよいのかも知れません。(その点は自信ないので確認した方がよいと思います)
もしそこまで配慮するなら以下のようにできます。
Java
1return new CheckBoxTableCell<Parson, Boolean>() {
2 ChangeListener<Parson> itemListener = (observable, oldItem, newItem) -> {
3 // newItemに従ってセルの状態を変更する処理
4 Parson item = (Parson)newRow.getItem();
5 setVisible(item.getDataType() != 1);
6 };
7 { // Cellインスタンスの初期化ブロック(無名クラスにはコンストラクターが書けないので...)
8 tableRowProperty().addListener((observable, oldRow, newRow) -> {
9 if (oldRow != null) oldRow.itemProperty().removeListener(itemListener);
10 if (newRow != null) newRow.itemProperty().addListener(itemListener);
11 });
12 }
13};
(ご質問のコードではlambda式ではなく無名クラスが使われていたりしますね。でもJavaFXなのでJava8前提でよい気がします。そこでlambda式を用いたコード例にしました)