自动编号表行(javafx) [英] auto numbered table rows (javafx)

查看:223
本文介绍了自动编号表行(javafx)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是如何在第一列中使用tableRow的索引在JavaFX中创建一个新表。



所以我创建了一个类:NrCellFactory。

 公共类NrCellFactory< S,String>扩展TableCellFactory< S,String> {

私有类NrCell< S,String>扩展TableCell< S,String> {

public NrCell(){
setText(this.getTableRow()。getIndex()+);
}



}

@Override
protected TableCell< S,String> createTableCell(TableColumn< S,String> column){
return new NrCell();
}

}

然后我将我的列设置在哪里应显示数字:

  nrCol.setCellFactory(new NrCellFactory< Person,String>()); 

当我加载项目时,nrCol没有数据......



任何人都可以解决这个问题吗?



谢谢

解决方案

样本解决方案



以下是使用单元工厂的解决方案:

  TableColumn numberCol = new TableColumn(#); 
numberCol.setCellValueFactory(new Callback< CellDataFeatures< Person,Person>,ObservableValue< Person>>(){
@Override public ObservableValue< Person> call(CellDataFeatures< Person,Person> p){
返回新的ReadOnlyObjectWrapper(p.getValue());
}
});

numberCol.setCellFactory(new Callback< TableColumn< Person,Person>,TableCell< Person,Person>>(){
@Override public TableCell< Person,Person> call(TableColumn< Person,Person> param){
返回新的TableCell< Person,Person>(){
@Override protected void updateItem(Person item,boolean empty){
super.updateItem(item,empty );

if(this.getTableRow()!= null&& item!= null){
setText(this.getTableRow()。getIndex()+);
} else {
setText();
}
}
};
}
});
numberCol.setSortable(false);

简单替代解决方案



使用单元格值工厂的简单示例,对于正常情况下没有单元格工厂,表格的后备数据列表中的所有项目都是唯一的,并且可以通过查找其索引table.getItems()。indexOf(p.getValue())

  TableColumn numberCol = new TableColumn的( #); 
numberCol.setCellValueFactory(new Callback< CellDataFeatures< Person,String>,ObservableValue< String>>(){
@Override public ObservableValue< String> call(CellDataFeatures< Person,String> p){
返回新的ReadOnlyObjectWrapper(table.getItems()。indexOf(p.getValue())+);
}
});
numberCol.setSortable(false);

为什么尝试这样做失败



我无法确切地说你为什么尝试这样做会失败,因为我认为你的问题中没有足够的代码来准确诊断失败。我的猜测是你没有为行提供单元格值工厂,也没有在单元格的构造函数中设置文本而不是 updateItem 调用导致它不起作用。 / p>

可执行样本



以下是可执行样本:



  import javafx.application.Application; 
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;

公共类NumberedTableViewSample扩展Application {

private TableView< Person> table = new TableView< Person>();
私人最终ObservableList< Person> data =
FXCollections.observableArrayList(
new Person(Jacob,Smith,jacob.smith@example.com),
new Person(Isabella,Johnson ,isabella.johnson@example.com),
新人(Ethan,Williams,ethan.williams@example.com),
新人(Emma,琼斯,emma.jones @ example.com),
新人(迈克尔,布朗,michael.brown@example.com)
);

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

@Override
public void start(舞台舞台){
场景场景=新场景(新组());
stage.setTitle(Table View Sample);
stage.setWidth(470);
stage.setHeight(500);

final Label label = new Label(Address Book);
label.setFont(new Font(Arial,20));

table.setEditable(true);

TableColumn numberCol = new TableColumn(#);
numberCol.setMinWidth(20);
numberCol.setCellValueFactory(new Callback< CellDataFeatures< Person,Person>,ObservableValue< Person>>(){
@Override public ObservableValue< Person> call(CellDataFeatures< Person,Person> p){
返回新的ReadOnlyObjectWrapper(p.getValue());
}
});

numberCol.setCellFactory(new Callback< TableColumn< Person,Person>,TableCell< Person,Person>>(){
@Override public TableCell< Person,Person> call(TableColumn< Person,Person> param){
返回新的TableCell< Person,Person>(){
@Override protected void updateItem(Person item,boolean empty){
super.updateItem(item,empty );

if(this.getTableRow()!= null&& item!= null){
setText(this.getTableRow()。getIndex()+);
} else {
setText();
}
}
};
}
});
numberCol.setSortable(false);

TableColumn firstNameCol = new TableColumn(First Name);
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory< Person,String>(firstName));

TableColumn lastNameCol = new TableColumn(Last Name);
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory< Person,String>(lastName));

TableColumn emailCol = new TableColumn(Email);
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory< Person,String>(email));

table.setItems(data);
table.getColumns()。addAll(numberCol,firstNameCol,lastNameCol,emailCol);

final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10,0,0,10));
vbox.getChildren()。addAll(label,table);

((Group)scene.getRoot())。getChildren()。addAll(vbox);
stage.setScene(场景);
stage.show();
}

public static class Person {

private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
私人最终的SimpleStringProperty电子邮件;

private Person(String fName,String lName,String email){
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}

public String getFirstName(){
return firstName.get();
}

public void setFirstName(String fName){
firstName.set(fName);
}

public String getLastName(){
return lastName.get();
}

public void setLastName(String fName){
lastName.set(fName);
}

public String getEmail(){
return email.get();
}

public void setEmail(String fName){
email.set(fName);
}
}
}


My question is how to make a new Table in JavaFX with in the first column the index of the tableRow.

So i've created a class: NrCellFactory.

public class NrCellFactory<S, String> extends TableCellFactory<S,String> {

private class NrCell<S,String> extends TableCell<S,String>{

    public NrCell(){
        setText(this.getTableRow().getIndex()+"");
    }



}

@Override
protected TableCell<S, String> createTableCell(TableColumn<S, String> column) {
    return new NrCell();
}

}

and then i set my column where the numbers should be displayed:

 nrCol.setCellFactory(new NrCellFactory<Person,String>());

when I load the project, the nrCol has no data...

Can anyone solve the problem?

Thanks

解决方案

Sample Solution

Here's a solution using a cell factory:

TableColumn numberCol = new TableColumn("#");
numberCol.setCellValueFactory(new Callback<CellDataFeatures<Person, Person>, ObservableValue<Person>>() {
  @Override public ObservableValue<Person> call(CellDataFeatures<Person, Person> p) {
    return new ReadOnlyObjectWrapper(p.getValue());
  }
});

numberCol.setCellFactory(new Callback<TableColumn<Person, Person>, TableCell<Person, Person>>() {
  @Override public TableCell<Person, Person> call(TableColumn<Person, Person> param) {
    return new TableCell<Person, Person>() {
      @Override protected void updateItem(Person item, boolean empty) {
        super.updateItem(item, empty);

        if (this.getTableRow() != null && item != null) {
          setText(this.getTableRow().getIndex()+"");
        } else {
          setText("");
        }
      }
    };
  }
});
numberCol.setSortable(false);

Simple Alternate Solution

And a simpler sample using a cell value factory and no cell factory for the normal case where all of the items in the backing data list for the table are unique and their index can be looked up via table.getItems().indexOf(p.getValue()):

TableColumn numberCol = new TableColumn("#");
numberCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
  @Override public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
    return new ReadOnlyObjectWrapper(table.getItems().indexOf(p.getValue()) + "");
  }
});   
numberCol.setSortable(false);

Why your attempt to do this failed

I couldn't say exactly why your attempt to do this failed as I don't think there is enough code in your question to accurately diagnose the failure. My guess is that you didn't provide a cell value factory for the row and also setting the text in the cell's constructor rather than an updateItem call caused it not to work.

Executable Sample

Here is an executable sample:

import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;

public class NumberedTableViewSample extends Application {

    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data =
        FXCollections.observableArrayList(
            new Person("Jacob", "Smith", "jacob.smith@example.com"),
            new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
            new Person("Ethan", "Williams", "ethan.williams@example.com"),
            new Person("Emma", "Jones", "emma.jones@example.com"),
            new Person("Michael", "Brown", "michael.brown@example.com")
        );

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(470);
        stage.setHeight(500);

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

        TableColumn numberCol = new TableColumn("#");
        numberCol.setMinWidth(20);
        numberCol.setCellValueFactory(new Callback<CellDataFeatures<Person, Person>, ObservableValue<Person>>() {
            @Override public ObservableValue<Person> call(CellDataFeatures<Person, Person> p) {
                return new ReadOnlyObjectWrapper(p.getValue());
            }
        });

        numberCol.setCellFactory(new Callback<TableColumn<Person, Person>, TableCell<Person, Person>>() {
            @Override public TableCell<Person, Person> call(TableColumn<Person, Person> param) {
                return new TableCell<Person, Person>() {
                    @Override protected void updateItem(Person item, boolean empty) {
                        super.updateItem(item, empty);

                        if (this.getTableRow() != null && item != null) {
                            setText(this.getTableRow().getIndex()+"");
                        } else {
                            setText("");
                        }
                    }
                };
            }
        });
        numberCol.setSortable(false);

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("firstName"));

        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("lastName"));

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("email"));

        table.setItems(data);
        table.getColumns().addAll(numberCol, firstNameCol, lastNameCol, emailCol);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);
        stage.setScene(scene);
        stage.show();
    }

    public static class Person {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;
        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }
} 

这篇关于自动编号表行(javafx)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆