Javafx 获取列中TableView中对象的运行计数
我有两种类型的对象在一个表中,为简单起见,我将它们称为狗和猫,这两种对象都从动物延伸而来。我正在尝试对对象进行连续计数。目前,我将重点关注狗的物体 我为一个TableColumn创建了一个值工厂,它如下所示:Javafx 获取列中TableView中对象的运行计数,javafx,javafx-8,Javafx,Javafx 8,我有两种类型的对象在一个表中,为简单起见,我将它们称为狗和猫,这两种对象都从动物延伸而来。我正在尝试对对象进行连续计数。目前,我将重点关注狗的物体 我为一个TableColumn创建了一个值工厂,它如下所示: column.setCellFactory(callback -> new TableCell<>() { @Override protected void updateItem(String item, boolean empty) {
column.setCellFactory(callback -> new TableCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty) {
if (getTableView().getItems().get(getIndex()) instanceof Dog) {
int count = setDogCount(getTableView(), getIndex(), 0);
setText(String.valueOf(count));
} else {
setText("");
}
} else {
setText("");
}
}
});
column.setCellFactory(回调->新建TableCell(){
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(!空){
if(getTableView().getItems().get(getIndex())实例狗){
int count=setDogCount(getTableView(),getIndex(),0);
setText(String.valueOf(count));
}否则{
setText(“”);
}
}否则{
setText(“”);
}
}
});
我使用的递归方法如下:
private int setDogCount(TableView<Animal> table, int index, int count){
if(index == 0){
if(table.getItems().get(index) instanceof Dog) {
return count + 1;
} else {
return count;
}
}
if(table.getItems().get(index) instanceof Dog){
return setDogCount(table, --index, ++count);
}else {
return setDogCount(table, --index, count);
}
}
private int setDogCount(TableView
如您所见,索引0与索引3切换,从而适当地更改了计数列,但现在我没有数字1和两个数字3。这是因为它只更新切换的行
编辑3:
这是一个小应用程序,可以查看这些更改。当您运行它时,请单击“已知命令”列一次,查看我遇到的问题
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
BorderPane root = new BorderPane();
TableView<Animal> table = new TableView<>();
TableColumn<Animal, String> count = new TableColumn<>("Count");
TableColumn<Animal, String> name = new TableColumn<>("Name");
TableColumn<Animal, String> sound = new TableColumn<>("Sound");
TableColumn<Animal, String> commandsKnown = new TableColumn<>("Commands Known");
table.getColumns().addAll(count, name, sound, commandsKnown);
root.setCenter(table);
count.setCellFactory(callback -> new TableCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
if (getTableView().getItems().get(getIndex()) instanceof Dog) {
int count = setDogCount(getTableView(), getIndex(), 0);
setText(String.valueOf(count));
} else {
setText("");
}
} else {
setText("");
}
}
});
name.setCellValueFactory(data -> data.getValue().nameProperty());
sound.setCellValueFactory(data -> data.getValue().soundProperty());
commandsKnown.setCellValueFactory(data -> {
if(data.getValue() instanceof Dog){
return ((Dog) data.getValue()).commandsKnownProperty();
}
return new SimpleStringProperty("");
});
ObservableList<Animal> animals = FXCollections.observableArrayList();
animals.add(new Dog("Tweeter", "Woof", "Sit, rollover, shake, drop"));
animals.add(new Dog("Sub Woofer", "Woof", "Sit, rollover, shake"));
animals.add(new Cat("Kitter Cat", "Meow"));
animals.add(new Dog("Bass", "Woof", "Sit, rollover, shake, fetch"));
table.setItems(animals);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private int setDogCount(TableView<Animal> table, int index, int count){
if(index == 0){
if(table.getItems().get(index) instanceof Dog) {
return count + 1;
} else {
return count;
}
}
if(table.getItems().get(index) instanceof Dog){
return setDogCount(table, --index, ++count);
}else {
return setDogCount(table, --index, count);
}
}
public static void main(String[] args) {
launch(args);
}
public class Animal{
StringProperty name = new SimpleStringProperty();
StringProperty sound = new SimpleStringProperty();
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getSound() {
return sound.get();
}
public StringProperty soundProperty() {
return sound;
}
public void setSound(String sound) {
this.sound.set(sound);
}
}
public class Dog extends Animal{
StringProperty commandsKnown = new SimpleStringProperty();
public Dog(String name, String sound, String commandsKnown){
setName(name);
setSound(sound);
setCommandsKnown(commandsKnown);
}
public String getCommandsKnown() {
return commandsKnown.get();
}
public StringProperty commandsKnownProperty() {
return commandsKnown;
}
public void setCommandsKnown(String commandsKnown) {
this.commandsKnown.set(commandsKnown);
}
}
public class Cat extends Animal{
public Cat(String name, String sound){
setName(name);
setSound(sound);
}
}
}
导入javafx.application.application;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.control.TableCell;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
公共类主扩展应用程序{
@凌驾
public void start(Stage primaryStage)引发异常{
BorderPane根=新的BorderPane();
TableView table=新TableView();
TableColumn计数=新的TableColumn(“计数”);
TableColumn名称=新的TableColumn(“名称”);
TableColumn声音=新的TableColumn(“声音”);
TableColumn commandsKnown=新TableColumn(“已知命令”);
table.getColumns().addAll(计数、名称、声音、commandsKnown);
root.setCenter(表);
count.setCellFactory(回调->新建TableCell(){
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(!空){
if(getTableView().getItems().get(getIndex())实例狗){
int count=setDogCount(getTableView(),getIndex(),0);
setText(String.valueOf(count));
}否则{
setText(“”);
}
}否则{
setText(“”);
}
}
});
name.setCellValueFactory(数据->数据.getValue().nameProperty());
sound.setCellValueFactory(数据->数据.getValue().soundProperty());
commandsKnown.setCellValueFactory(数据->{
if(data.getValue()狗的实例){
return((Dog)data.getValue()).commandsKnownProperty();
}
返回新的SimpleStringProperty(“”);
});
ObservableList animals=FXCollections.observableArrayList();
动物。添加(新狗(“高音”、“呜呜”、“坐、翻滚、摇晃、跌落”);
动物。添加(新狗(“超低音扬声器”,“低音”,“坐,翻滚,摇”);
添加(新猫(“小猫”,“喵喵”));
动物。添加(新狗(“低音”,“低音”,“低音”,“坐下,翻滚,摇晃,取回”);
表2.设置项目(动物);
primaryStage.setScene(新场景(根));
primaryStage.show();
}
私有int setDogCount(TableView表、int索引、int计数){
如果(索引==0){
if(table.getItems().get(index)instanceof Dog){
返回计数+1;
}否则{
返回计数;
}
}
if(table.getItems().get(index)instanceof Dog){
返回setDogCount(表,-索引,++计数);
}否则{
返回setDogCount(表,-索引,计数);
}
}
公共静态void main(字符串[]args){
发射(args);
}
公营动物{
StringProperty名称=新的SimpleStringProperty();
StringProperty声音=新的SimpleStringProperty();
公共字符串getName(){
返回name.get();
}
公共字符串属性nameProperty(){
返回名称;
}
公共void集合名(字符串名){
this.name.set(name);
}
公共字符串getSound(){
返回声音。get();
}
公共属性soundProperty(){
回音;
}
公共无效设置声音(字符串声音){
这个。声音。设置(声音);
}
}
公家犬{
StringProperty commandsKnown=新的SimpleStringProperty();
公共狗(字符串名称、字符串声音、字符串命令){
集合名(名称);
设置声音(声音);
setCommandsKnown(commandsKnown);
}
公共字符串getCommandsKnown(){
返回commandsKnown.get();
}
public StringProperty命令sknownproperty(){
返回commandsKnown;
}
public void setCommandsKnown(字符串commandsKnown){
this.commandsKnown.set(commandsKnown);
}
}
公营猫科动物{
公用猫(字符串名称、字符串声音){
集合名(名称);
设置声音(声音);
}
}
}
我建议您使用静态变量来跟上狗的
ID
示例代码如下:
完整代码:
狗类
/**
*
* @author blj0011
*/
public class Dog extends Animal
{
static int dogCounter = 0;
private String commnads;
private final int dogId;
public Dog(String name, String sound, String commands)
{
super(name, sound);
this.commnads = commands;
dogId = ++dogCounter;
}
public String getCommnads()
{
return commnads;
}
public void setCommnads(String commnads)
{
this.commnads = commnads;
}
public int getDogId()
{
return dogId;
}
}
/**
*
* @author blj0011
*/
public class Cat extends Animal
{
public Cat(String name, String sound)
{
super(name, sound);
}
}
猫类
/**
*
* @author blj0011
*/
public class Dog extends Animal
{
static int dogCounter = 0;
private String commnads;
private final int dogId;
public Dog(String name, String sound, String commands)
{
super(name, sound);
this.commnads = commands;
dogId = ++dogCounter;
}
public String getCommnads()
{
return commnads;
}
public void setCommnads(String commnads)
{
this.commnads = commnads;
}
public int getDogId()
{
return dogId;
}
}
/**
*
* @author blj0011
*/
public class Cat extends Animal
{
public Cat(String name, String sound)
{
super(name, sound);
}
}
public class TableWithExternalCounterSO extends Application {
/**
* Updates the counter data from the given source list, assuming that
* both have the same size (if that's not true, adjust counter size
* as needed)
*/
private void updateDogCounterFrom(ObservableList<ObjectProperty<Integer>> dogCounter,
ObservableList<? extends PetOwner> owners) {
int count = 0;
for (int i = 0; i < owners.size(); i++) {
PetOwner owner = owners.get(i);
if (owner.petProperty().get() == Pet.DOG) {
dogCounter.get(i).set(++count);
} else {
dogCounter.get(i).set(-1);
}
}
}
private Parent createContent() {
// the base data
ObservableList<PetOwner> owners = PetOwner.owners();
// a list for the counters, that must be kept in sync with changes in the table
ObservableList<ObjectProperty<Integer>> dogCounter = FXCollections.observableArrayList();
owners.forEach(owner -> dogCounter.add(new SimpleObjectProperty<Integer>(-1)));
// initial sync
updateDogCounterFrom(dogCounter, owners);
SortedList<PetOwner> sorted = new SortedList<>(owners);
sorted.addListener((ListChangeListener<? super PetOwner>) c -> {
// sync after change
updateDogCounterFrom(dogCounter, c.getList());
});
TableView<PetOwner> table = new TableView<>(sorted);
sorted.comparatorProperty().bind(table.comparatorProperty());
TableColumn<PetOwner, String> name = new TableColumn<>("Name");
name.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<PetOwner, Pet> pet = new TableColumn<>("Pet");
pet.setCellValueFactory(new PropertyValueFactory<>("pet"));
TableColumn<PetOwner, Integer> dogIndex = new TableColumn<>("Running Dog#");
dogIndex.setSortable(false);
dogIndex.setCellValueFactory(cd -> {
// astonishingly, this is called for every cell after sorting,
// that is all cells are newly created
int index = cd.getTableView().getItems().indexOf(cd.getValue());
return dogCounter.get(index);
});
dogIndex.setCellFactory(cb -> {
return new TableCell<PetOwner, Integer>() {
@Override
protected void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty || item != null && item.intValue() < 0) {
setText("");
} else {
setText(String.valueOf(item));
}
}
};
});
table.getColumns().addAll(name, pet, dogIndex);
BorderPane pane = new BorderPane(table);
return pane;
}
private enum Pet {
CAT, DOG
}
public static class PetOwner {
ObjectProperty<Pet> pet;
StringProperty name;
PetOwner(String name, Pet pet) {
this.pet = new SimpleObjectProperty<>(this, "pet", pet);
this.name = new SimpleStringProperty(this, "name", name);
}
public ObjectProperty<Pet> petProperty() {
return pet;
}
public StringProperty nameProperty() {
return name;
}
public static ObservableList<PetOwner> owners() {
ObservableList<PetOwner> owners = FXCollections.observableArrayList();
for (int i = 0; i < 20; i++) {
owners.add(new PetOwner("O " + i, i % 3 == 0 ? Pet.CAT : Pet.DOG) );
}
return owners;
}
@Override
public String toString() {
return name.get( ) + " " + pet.get();
}
}