当前位置: 首页 > 知识库问答 >
问题:

如何修复滚动时的TableView

法弘壮
2023-03-14

我是JavaFX的新手,不知道如何解决这个问题。所以,我在TableView中有一个复选框列。例如,我先选择3个框,然后向下滚动表格。但当我进入表格顶部时,复选框没有被选中。以下是一些代码:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.util.LinkedList;
import java.util.List;

public class App extends Application
{
List<User> list = new LinkedList<>();
TableColumn<User, Integer> id;
TableColumn<User, String> firstName;
TableColumn<User, Boolean> selected;
TableView<User> tableView;

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

@Override
public void start(Stage stage) throws Exception
{
    stage.setHeight(500);
    stage.setWidth(500);
    stage.setMinHeight(200);
    stage.setMinHeight(100);
    stage.setTitle("Table view");

    tableView = new TableView<>();

    ObservableList<User> list = FXCollections.observableArrayList();
    for(int i = 0; i < 40; i++)
    {
        list.add(new User(i, "first name", "last name"));
    }

    id = new TableColumn("ID");
    id.setCellValueFactory(new PropertyValueFactory<User, Integer>("id"));

    firstName = new TableColumn("First Name");
    firstName.setCellValueFactory(new PropertyValueFactory<User, String>("firstName"));

    TableColumn<User, String> lastName = new TableColumn("Last Name");
    lastName.setCellValueFactory(new PropertyValueFactory<User, String>("lastName"));

    selected = new TableColumn("Select");

    Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> booleanCellFactory =     new Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>>()
    {
        @Override
        public TableCell<User, Boolean> call(TableColumn<User, Boolean> p)
        {
            return new CheckBoxCell();
        }
    };
    selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));
    selected.setCellFactory(booleanCellFactory);

    tableView.getColumns().addAll(id, firstName, lastName, selected);
    tableView.setItems(list);

    BorderPane pane = new BorderPane();
    pane.setCenter(tableView);

    Scene scene = new Scene(pane);
    stage.setScene(scene);
    stage.show();
}

class CheckBoxCell extends TableCell<User, Boolean>
{
    private CheckBox checkbox;

    @Override
    protected void updateItem(Boolean item, boolean empty)
    {
        super.updateItem(item, empty);
        checkbox = new CheckBox();
        checkbox.setAlignment(Pos.CENTER);
        setAlignment(Pos.CENTER);
        setGraphic(checkbox);
        checkbox.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent actionEvent)
            {

                if(!checkbox.isSelected())
                {
                    list.remove(tableView.getItems().get(getTableRow().getIndex()));
                } else
                {
                    list.add(tableView.getItems().get(getTableRow().getIndex()));
                }
                System.out.println(list);
            }
        });
    }
}
}    

和数据类"User":

public class User
{
private int id;
private String firstName;
private String lastName;

User(int id, String firstName, String lastName)
{
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
}

public int getId()
{
    return id;
}

public void setId(int id)
{
    this.id = id;
}

public String getFirstName()
{
    return firstName;
}

public void setFirstName(String firstName)
{
    this.firstName = firstName;
}

public String getLastName()
{
    return lastName;
}

public void setLastName(String lastName)
{
    this.lastName = lastName;
}

}

共有2个答案

郑浩博
2023-03-14

有很多问题。

首先,TableCell实例将被重用。您需要将复选框的值设置为项的值。

@Override
protected void updateItem(Boolean item, boolean empty)
{
    super.updateItem(item, empty);
    checkbox = new CheckBox();

    if(!empty && item != null)
        checkbox.setSelected(item);

    ....

  }

其次,有两个变量名为listTableView未绑定到列表

您应该替换这一行:

List<User> list = new LinkedList<>();

有了这个:

ObservableList<User> list = FXCollections.observableArrayList();

最后,您应该为您的数据对象使用JavaFX属性,它们将在TableView中执行得更快(不需要使用反射来访问值),并且可以更好地处理JavaFX控件。

您可以在Oracle网站上了解这些属性。

燕雨石
2023-03-14

在表列“slected”的代码中

selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));

您正在将propertyvalue工厂设置为“active”,但用户类中没有“active”属性。当您移动滚动条tableview触发updateItem方法时,因为您没有活动属性(即使您的属性默认值为false)复选框。选举产生(项目);行将取消选中复选框,因为项目值始终为false。

要解决此问题,请定义用户类中活动的BooleanProperty,并在用户选中/取消选中复选框时更新属性值。

下面是完整的代码

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.layout.BorderPane;
import java.util.LinkedList;
import java.util.List;

public class TestApp extends Application {

        List<User> list = new LinkedList<>();
        TableColumn<User, Integer> id;
        TableColumn<User, String> firstName;
        TableColumn<User, Boolean> selected;
        TableView<User> tableView;

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

@Override
public void start(Stage stage) throws Exception
        {
        stage.setHeight(500);
        stage.setWidth(500);
        stage.setMinHeight(200);
        stage.setMinHeight(100);
        stage.setTitle("Table view");

        tableView = new TableView<>();

        ObservableList<User> list = FXCollections.observableArrayList();
        for(int i = 0; i < 40; i++)
        {
        list.add(new User(i, "first name", "last name"));
        }

        id = new TableColumn("ID");
        id.setCellValueFactory(new PropertyValueFactory<User, Integer>("id"));

        firstName = new TableColumn("First Name");
        firstName.setCellValueFactory(new PropertyValueFactory<User, String>("firstName"));

        TableColumn<User, String> lastName = new TableColumn("Last Name");
        lastName.setCellValueFactory(new PropertyValueFactory<User, String>("lastName"));

        selected = new TableColumn("Select");

        Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> booleanCellFactory =     new Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>>()
        {
@Override
public TableCell<User, Boolean> call(TableColumn<User, Boolean> p)
        {
        return new CheckBoxCell();
        }
        };
        selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));
        selected.setCellFactory(booleanCellFactory);

        tableView.getColumns().addAll(id, firstName, lastName, selected);
        tableView.setItems(list);

        BorderPane pane = new BorderPane();
        pane.setCenter(tableView);

        Scene scene = new Scene(pane);
        stage.setScene(scene);
        stage.show();
       }

class CheckBoxCell extends TableCell<User, Boolean>
{
    private CheckBox checkbox = new CheckBox();
    public CheckBoxCell(){
        checkbox.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent actionEvent)
            {

                if(!checkbox.isSelected())
                {
                    list.remove(tableView.getItems().get(getTableRow().getIndex()));
                    User user = getTableView().getItems().get(getTableRow().getIndex());
                    user.setActive(false);
                } else
                {
                    list.add(tableView.getItems().get(getTableRow().getIndex()));
                    User user = getTableView().getItems().get(getTableRow().getIndex());
                    user.setActive(true);
                }
                System.out.println(list);
            }
        });
    }

    @Override
    protected void updateItem(Boolean item, boolean empty)
    {
        super.updateItem(item, empty);
       if(!empty && item != null) {
           checkbox.setAlignment(Pos.CENTER);
           checkbox.setSelected(item);
           setAlignment(Pos.CENTER);
           setGraphic(checkbox);
       }
    }
}

用户类别:

public class User
{
    private IntegerProperty id;
    private StringProperty firstName;
    private StringProperty lastName;
    private BooleanProperty active;

    User(int id, String firstName, String lastName)
    {
        this.id = new SimpleIntegerProperty(id);
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
        this.active = new SimpleBooleanProperty(false);
    }

    public int getId() {
        return id.get();
    }

    public IntegerProperty idProperty() {
        return id;
    }

    public void setId(int id) {
        this.id.set(id);
    }

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

    public StringProperty firstNameProperty() {
        return firstName;
    }

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

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

    public StringProperty lastNameProperty() {
        return lastName;
    }

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

    public boolean getActive() {
        return active.get();
    }

    public BooleanProperty activeProperty() {
        return active;
    }

    public void setActive(boolean active) {
        this.active.set(active);
    }
}
 类似资料:
  • 问题内容: 我具有以下表结构: 我正在尝试修复标题,以便如果向下滚动它仍然可见,我怎样才能做到这一点? 问题答案: 为了达到我的目标,我编写了以下代码(如所问的那样)- 这是我写的插件。 如何使用: 希望能对某人有所帮助。 无论如何,感谢大家的支持… :)

  • 问题内容: 我正在创建一个标头,一旦滚动到一定数量的像素,它就会固定并保持在原位。 我可以只使用CSS和html来执行此操作吗,还是也需要jquery? 我创建了一个演示,以便您可以理解。任何帮助将是巨大的! 问题答案: 您需要一些JS来进行滚动事件。最好的方法是为固定位置设置一个新的CSS类,当滚动超过某个点时,该类将分配给相关的div。 HTML CSS jQuery 编辑:扩展示例 如果触发

  • 我有以下布局:- 我试图实现这一点,当我滚动时,一旦侧红色div到达顶部,它们就固定在那个位置,从那里绿色div可以滚动更多(基本上,我想让我的红色div总是在框架中)。 我使用flex对齐了3个分区:- 以下是我的HTML:- 以下是我的css:- 以下是我的JS:- 有人能帮我吗?红色div应该被固定,一旦他们到达顶部,中心div应该是可滚动的。

  • 我有一个android应用程序,启动时会显示2秒钟的白色屏幕。我的其他应用程序不能做到这一点,但这一个可以做到。我还实现了一个splashscreen,希望它能解决这个问题。我应该增加闪屏睡眠时间吗?谢谢

  • 我正在使用Selenium来自动化应用程序,但是当我试图单击标记时,它会抛出以下错误: 元素无法滚动到视图中。 我在C#和Firefox V62中使用Selenium! 下面是我的代码:

  • 问题内容: 当我运行它说npm audit fixnpm audit。 但是,输出 这是否意味着它不应该由用户修复? 当我运行它时,它会给我表的列表,类似于此: 在此示例中,链接页面的补救部分说。但是,其中有几行: 不再有lodash依赖项。因此它应该已经是v4.17.5。我还检查了哪条线。在有这些线路: 我认为该版本显示在“ _id”中,而不是在“ _from”中,因此版本是正确的,但漏洞仍会出