如何正确地向TableView添加新数据并滚动到它 [英] How to correctly add new data to TableView and scroll to it

查看:362
本文介绍了如何正确地向TableView添加新数据并滚动到它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



我想动态地向TableView添加数据并滚动到新数据的位置。但是当TableView中的行达到ViewPort大小时,我会在控制台中得到它:


2015年4月18日9:14:34 AM com.sun.javafx.scene.control.skin.VirtualFlow
addTrailingCells INFO:index超过maxCellCount。检查类javafx.scene.control.TableRow的大小
计算


所以我猜我做错了。我所做的就是使用Oracle TableView示例并添加:

  //按钮添加新数据
Button bt = new Button(添加);
bt.setOnAction(e - > {

//插入新项目
int i = data.size()+ 1;
人员=新人(姓名+ i,姓名+ i,邮件+ i);
data.add(人);

//滚动到新项目
table .scrollTo(person);

});

当你使用



<$ p时会发生同样的情况$ p> table.getItems()。add(person);

而非修改清单。



罪魁祸首是scrollTo方法。使用scrollTo方法使用行索引时会出现相同的信息/错误。



问题



如何正确地向TableView添加新项目,以便不显示信息/错误?



代码



这是一个完整的例子。该表已预先填写。如果按下添加按钮,则会达到视口大小,并且控制台中会显示信息(或错误?)。

  public class TableViewSample扩展Application {

private TableView< Person> table = new TableView< Person>();
私人最终ObservableList< Person> data = FXCollections.observableArrayList();

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

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

table.setEditable(true);

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(firstNameCol,lastNameCol,emailCol);

// -------------------------------
//动态添加数据
// -------------------------------

//填表数据
for(int i = 0; i< 14; i ++){
Person person = new Person(Name+ i,Name+ i,Mail+ i);
data.add(person);
}

//按钮添加新数据
按钮bt = new按钮(添加);
bt.setOnAction(e - > {

//插入新项目
int i = data.size()+ 1;
人员=新人(姓名+ i,姓名+ i,邮件+ i);
data.add(人);

//滚动到新项目
table .scrollTo(person);

});

// -------------------------------

final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.getChildren()。addAll(table,bt);

((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);
}
}
}


解决方案

通过重置日志管理器来抑制警告:

  import javafx.application。*; 
import javafx.stage。*;
import javafx.scene。*;
import javafx.scene.control。*;
import javafx.scene.control.cell。*;
import javafx.scene.layout。*;
import javafx.beans.property。*;
import javafx.collections。*;

import java.util.logging.LogManager;

公共类TableViewSample扩展Application {
// ... setup ...

public static void main(String [] args){

//单击添加按钮时,禁止显示警告消息。
LogManager.getLogManager()。reset();

launch(args);
}

这将影响整个应用程序的记录器。如果不需要,请将违规类( com.sun.javafx.scene.control.skin.VirtualFlow )的日志记录级别更改为级别.OFF



参见:





因为这是一条警告信息,它可能被忽略,因此被压制。据我所知,新行已成功添加。以下是签入的违规代码,IMO违反了最不惊讶的原则:




Problem

I want to add data dynamically to a TableView and scroll to the new data's position. But when the rows in the TableView reach the ViewPort size, I get this in the console:

Apr 18, 2015 9:14:34 AM com.sun.javafx.scene.control.skin.VirtualFlow addTrailingCells INFO: index exceeds maxCellCount. Check size calculations for class javafx.scene.control.TableRow

So I guess I did something wrong. All I did was using the Oracle TableView example and add this:

// button to add new data
Button bt = new Button( "Add");
bt.setOnAction(e -> {

    // insert new item
    int i = data.size() + 1;
    Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
    data.add( person);

    // scroll to new item
    table.scrollTo( person);

});

The same happens when you use

    table.getItems().add( person);

instead of modifying the list.

The culprit is the scrollTo method. The same info/error occurs when you use the row index with the scrollTo method.

Question

How do you add new items correctly to a TableView, so that the info/error doesn't show up?

Code

Here's a full example. The table is pre-filled. If you hit the Add button the viewport size is reached and the info (or error?) is displayed in the console.

public class TableViewSample extends Application {

    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data = FXCollections.observableArrayList();

    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(450);
        stage.setHeight(500);

        table.setEditable(true);

        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(firstNameCol, lastNameCol, emailCol);

        // -------------------------------
        // dynamically add data
        // -------------------------------

        // fill table with data
        for( int i=0; i < 14; i++) {
            Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
            data.add( person);
        }

        // button to add new data
        Button bt = new Button( "Add");
        bt.setOnAction(e -> {

            // insert new item
            int i = data.size() + 1;
            Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
            data.add( person);

            // scroll to new item
            table.scrollTo( person);

        });

        // -------------------------------

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.getChildren().addAll(table, bt);

        ((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);
        }
    }
} 

解决方案

Suppress the warning by resetting the log manager:

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.scene.layout.*;
import javafx.beans.property.*;
import javafx.collections.*;

import java.util.logging.LogManager;

public class TableViewSample extends Application {
  // ... setup ...

  public static void main(String[] args) {

    // Suppress the warning message when the Add button is clicked.
    LogManager.getLogManager().reset();

    launch(args);
  }

This will affect the entire application's logger. If that is not desired, change the logging level for the offending class (com.sun.javafx.scene.control.skin.VirtualFlow) to Level.OFF.

See also:

Since this is a warning message, it can probably be ignored, and therefore suppressed. As far as I can tell, the new row is added successfully. Here is the offending code that was checked in, which, IMO, violates the principle of least astonishment:

这篇关于如何正确地向TableView添加新数据并滚动到它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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