2017-05-17 4 views
1

私は2つの同じシーンに密接に関連しています。ユーザーがあるテーブルの特定の行を移動するときに、他のテーブルの同じインデックスを持つ行が同様に「ホバー」されるようなリスナーを設定する必要があります。JavaFX - 異なるTableViewの対応するTableRowsのプロパティをバインドします。

私はこれをカスタム行ファクトリtableView.setRowFactory(...)で解決しようとしています。あなたは私のファクトリメソッドでは、私は二TableViewオブジェクト、myOtherTableへの参照を持って見ることができるように

row.hoverProperty().addListener((obs, o, n) -> { 
     myOtherTable.[get row here].pseudoClassStateChanged(PseudoClass.getPseudoClass("hover"), true); 
}); 

:工場call(...)メソッド内で私のような、ターゲット行にCSSの擬似クラス(.myclass:hover)を切り替えることができます。私はTableRowのオブジェクトを手に入れて擬似クラスを設定する必要があると思いますが、どうやってその方法を見つけ出すことはできません。
これを行うにはもっと良い方法がありますか?

答えて

2

...むしろ、あなたはIDまたはそのような何かをストックすることができますパーソナライズされた拡張のTableRowまたはテーブルセルオブジェクトを作成するようアドバイスしていて、PseudoClass

IntegerProperty hoveredRowIndex = new SimpleIntegerProperty(-1); 
PseudoClass appearHovered = PseudoClass.getPseudoClass("appear-hovered"); 

さて、この値は、独自のインデックスを観察し、表の行を作成し、行ファクトリを作成します。

Callback<TableView<T>, TableCell<T>> rowFactory = tv -> { 
    TableRow<T> row = new TableRow<T>() { 
     private BooleanBinding shouldAppearHovered = Bindings.createBooleanBinding(
       () -> getIndex() != -1 && getIndex() == hoveredRowIndex.get(), indexProperty(), 
       hoveredRowIndex); 

     { 

      shouldAppearHovered.addListener(
        (obs, wasHovered, isNowHovered) -> pseudoClassStateChanged(appearHovered, isNowHovered)); 

      hoverProperty().addListener((obs, wasHovered, isNowHovered) -> { 
       if (isNowHovered) { 
        hoveredRowIndex.set(getIndex()); 
       } else { 
        hoveredRowIndex.set(-1); 
       } 
      }); 
     } 
    }; 
    return row; 
}; 

Tを実際のテーブルの型に置き換えます)

そして、両方のテーブルの行ファクトリを使用します。あなたは推移しているように見える必要がある行のスタイルをCSSセレクタ

.table-row-cell:appear-hovered { 
    /* ... */ 
} 

を使用するか、またはその行の個々のセルのスタイルを

.table-row-cell:appear-hovered .table-cell { 
    /* ... */ 
} 

を使用することができます。

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.binding.BooleanBinding; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.css.PseudoClass; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

public class ConnectedHoverTables extends Application { 

    private IntegerProperty hoveredRowIndex = new SimpleIntegerProperty(-1); 
    private PseudoClass appearHovered = PseudoClass.getPseudoClass("appear-hovered"); 

    @Override 
    public void start(Stage primaryStage) { 
     HBox root = new HBox(10, createTable(), createTable()); 
     root.setPadding(new Insets(20)); 
     Scene scene = new Scene(root); 
     scene.getStylesheets().add("style.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private TableView<Item> createTable() { 
     TableView<Item> table = new TableView<>(); 

     table.setRowFactory(tv -> { 
      TableRow<Item> row = new TableRow<Item>() { 
       private BooleanBinding shouldAppearHovered = Bindings.createBooleanBinding(
         () -> getIndex() != -1 && getIndex() == hoveredRowIndex.get(), indexProperty(), 
         hoveredRowIndex); 

       { 

        shouldAppearHovered.addListener(
          (obs, wasHovered, isNowHovered) -> pseudoClassStateChanged(appearHovered, isNowHovered)); 

        hoverProperty().addListener((obs, wasHovered, isNowHovered) -> { 
         if (isNowHovered) { 
          hoveredRowIndex.set(getIndex()); 
         } else { 
          hoveredRowIndex.set(-1); 
         } 
        }); 
       } 
      }; 
      return row; 
     }); 

     table.setOnMouseClicked(e -> System.gc()); 

     table.getColumns().add(column("Item", Item::nameProperty)); 
     table.getColumns().add(column("Value", Item::valueProperty)); 
     table.getItems().setAll(createData()); 
     return table; 
    } 

    private List<Item> createData() { 
     Random rng = new Random(); 
     List<Item> items = new ArrayList<>(); 
     for (int i = 1; i <= 100; i++) { 
      Item item = new Item("Item " + i, rng.nextInt(1000)); 
      items.add(item); 
     } 
     return items; 
    } 

    private <S, T> TableColumn<S, T> column(String title, Function<S, ObservableValue<T>> property) { 
     TableColumn<S, T> col = new TableColumn<>(title); 
     col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); 
     return col; 
    } 

    public static class Item { 

     private final StringProperty name = new SimpleStringProperty(); 
     private final IntegerProperty value = new SimpleIntegerProperty(); 

     public Item(String name, int value) { 
      setName(name); 
      setValue(value); 
     } 

     public final StringProperty nameProperty() { 
      return this.name; 
     } 

     public final String getName() { 
      return this.nameProperty().get(); 
     } 

     public final void setName(final String name) { 
      this.nameProperty().set(name); 
     } 

     public final IntegerProperty valueProperty() { 
      return this.value; 
     } 

     public final int getValue() { 
      return this.valueProperty().get(); 
     } 

     public final void setValue(final int value) { 
      this.valueProperty().set(value); 
     } 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

おかげで、それ**ほとんど**作品:

はここSSCCEです!私がテーブルAの行を動かすと、テーブルBのそれぞれの が時には「出現した」と時々出現しません。私がテーブルBを最初に動かすと、テーブルAはほとんど浮かんで見えません。両方のテーブルが 'hoveredRowIndex'プロパティを同時に設定しているという事実とは関係がありますか? – TXV

+0

それはあなたが欲しいものでなければなりません... SSCCEを書くようにしましょう。 –

+1

ええ、何が起こっているのはバインディングがガベージコレクションされていることです。解決策は、それをテーブル行のプロパティにすることです:この変更で更新された答え。 –

0

正しく覚えていれば、TableViewの行に直接アクセスすることはできません。行インデックスを取得する唯一の方法は、CellFactoryを定義するときにindexProperty属性にアクセスすることです。

私はホバー行のインデックスを表す単一のプロパティを作成します

関連する問題