2016-11-03 4 views
0

私は標準の行の選択(常に単一、マルチではない)があるときにうまくいく次のコードを持っているとき、JavaFXのTableViewで選択したセルから行を取得します。setCellSelectionEnabled(true)

//This is needed to set the X & Y coordinates of the stage for edit. 
myTable.setRowFactory(tableView -> { 
    TableRow<MyDTO> row = new TableRow<MyDTO>(); 
      row.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { 
      if (isNowSelected) { 
       lastSelectedRow.set(row); 
      } 
    }); 
    return row ; 
}); 

私は、ユーザーがその行を編集するために選択したときに彼らはこれを編集するために、私は行の下にモーダルウィンドウをポップアップ表示できるように、親で境界を取得するには、行を使用しています。

しかし、私のテーブルは、必要なルックアップがない共通フィールドに対しても編集可能です。その場合、テーブルで編集したいと思います。これはすべて機能していますが、ユーザーフレンドリーにするために、セルの選択をオンにしたいのですが、そうするとrow.selectedProptery()リスナーは起動しません。

各セルのselectedProperty()を聞くことなく、どのように達成できますか?

おかげ

+0

私はあなたが各セルの選択された特性を聞くことによってこれを行うことができると思います。それは整理するのが難しいようには思えませんが、すべてのテーブルの列に対して同じセルファクトリの実装を再利用できます。 –

+0

匿名の内部クラスが定義を必要とするので、テーブルセル定義の各タイプに対して1つを作成する必要がありました。つまり、TableCell とTableCell の定義が必要です。しかし、私は別の道を行くと思います。ありがとう! –

+0

ああ、あなたは一般的にそれをすることができると思いますか? –

答えて

1

私は、各テーブルの列のセル工場を経由して、各セルの選択プロパティを使用してリスナーを登録せずにこれを行う方法はないと思います。

しかし、これは難しくありません。一般的に(つまり、テーブルの列の種類に関係なく同じコードで)、必要な他のセルファクトリの動作を尊重することができます。ここにSSCCEがあります:

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

import javafx.application.Application; 
import javafx.beans.binding.DoubleBinding; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class SelectedTableCellTracking extends Application { 

    private final ObjectProperty<TableCell<?,?>> selectedCell = new SimpleObjectProperty<>(); 

    @Override 
    public void start(Stage primaryStage) { 
     TableView<Item> table = new TableView<>(); 
     TableColumn<Item, String> itemCol = column("Item", Item::nameProperty); 
     TableColumn<Item, Number> valueCol = column("Value", Item::valueProperty); 
     table.getColumns().add(itemCol); 
     table.getColumns().add(valueCol); 

     Random rng = new Random(); 
     for (int i = 1 ; i <= 100; i++) { 
      table.getItems().add(new Item("Item "+i, rng.nextInt(1000))); 
     } 

     table.getSelectionModel().setCellSelectionEnabled(true); 

     Rectangle highlight = new Rectangle(); 
     highlight.setManaged(false); 
     highlight.setHeight(12); 
     highlight.setFill(Color.CORAL); 
     StackPane root = new StackPane(table, highlight); 


     selectedCell.addListener((obs, oldCell, newCell) -> { 
      if (newCell == null) { 
       highlight.setVisible(false); 
      } else { 
       highlight.setVisible(true); 
       highlight.setX(newCell.localToScene(newCell.getBoundsInLocal()).getMinX()); 
       highlight.setWidth(newCell.getWidth()); 
       highlight.setY(newCell.localToScene(newCell.getBoundsInLocal()).getMaxY()); 
      } 

     }); 

     table.getColumns().forEach(this::addCellSelectionListenerToColumn); 

     Scene scene = new Scene(root, 800, 800); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private <S,T> void addCellSelectionListenerToColumn(TableColumn<S,T> col) { 
     Callback<TableColumn<S,T>, TableCell<S,T>> currentCellFactory = col.getCellFactory(); 
     col.setCellFactory(tc -> { 
      TableCell<S,T> cell = currentCellFactory.call(tc); 
      cell.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { 
       if (isNowSelected) { 
        selectedCell.set(cell); 
       } 
      }); 
      return cell ; 
     }); 
    } 


    private static <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); 
    } 
} 
関連する問題