当setCellSelectionEnabled(真)从JavaFX中的TableView中选定单元格会排

问题描述:

我有下面的代码有标准的行选择时,我伟大的工程(总单,从来没有多)。当setCellSelectionEnabled(真)从JavaFX中的TableView中选定单元格会排

//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

我需要创建一个对每种类型的表格单元格定义的不幸,因为匿名内部类需要的定义 - 即TableCell的与TableCell的。但我想我会采取不同的方式。谢谢! –

+0

啊,我认为你可以做到这一点,不是吗? –

我不认为有办法做到这一点无需注册,每个单元的选择属性监听器,通过对每个表列的单元格工厂。

然而,这是不是太困难,可以(使用相同的代码的表列无论类型,即),也尊重你需要的任何其他电池工厂的行为一般都做。这是一个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); 
    } 
}