JavaFx8 Tableview 更新 ObservableList

JavaFx8 Tableview updating ObservableList

我在 table 中有一个 table 视图 我有一个复选框 当我 select 行制作这个复选框时我需要一些东西 selected 和其他检查要删除的箱子select 我通过在 table 视图上设置侦听器并遍历列表项并设置为 checked false 并且只有 selected 行为 true 来解决它,但我遇到的问题是当我调用 ObservableList.setall( ...) 在我的代码

之后我得到了这些异常
AccountingFilesTable.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showAccountingFilesDetails(newValue));
private void showAccountingFilesDetails(AccountingFiles newValue) {
AccountingFiles curraccfile = AccountingFilesTable.getSelectionModel().getSelectedItem();
   AccountingFilesTable.getSelectionModel().clearSelection();

    System.out.println(curraccfile.getAccountingFilesName());

    for (AccountingFiles af : accountingData) {

        mainEm.getTransaction().begin();
        af.setAccountingFilesActiveStatus(false);
        mainEm.getTransaction().commit();
        //accountingData.set(accountingData.indexOf(af), af);
        System.out.println("in looooooooooooop");
    }
    mainEm.getTransaction().begin();
    curraccfile.setAccountingFilesActiveStatus(true);
    mainEm.getTransaction().commit();
    List<AccountingFiles> listOfAccountingFiles = mainEm.createNamedQuery("AccountingFiles.findAll").getResultList();


    accountingData.setAll(listOfAccountingFiles);

}
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136)
at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TableView.java:2959)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2395)
at javafx.scene.control.TableView$TableViewSelectionModel.clearAndSelect(TableView.java:1898)
at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.simpleSelect(TableCellBehaviorBase.java:215)
at com.sun.javafx.scene.control.behavior.TableCellBehaviorBase.doSelect(TableCellBehaviorBase.java:148)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3486)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent0(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda6/1128584231.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:927)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null5(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda/1030870354.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

请帮我解决这个问题 我的 table 视图工作正常,但这些异常仍然存在。

这是我的完整 class 实现 包裹 front.view;

import back.entities.AccountingFiles;
import back.entities.AccountingFilesDetails;
import back.utility.Connector;
import hal.main.MainApp;

import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javax.persistence.EntityManager;


public class AccountingFilesFormController implements Initializable {

@FXML
private TableView<AccountingFiles> AccountingFilesTable;

@FXML
private TableView<AccountingFilesDetails> AccountingFilesDetailsTable;

@FXML
private TableColumn<AccountingFilesDetails, Boolean> accountingFilesDetailsSelectedFile;

@FXML
private TableColumn<AccountingFilesDetails, LocalDate> accountingFilesDetailsStartDate;

@FXML
private TableColumn<AccountingFilesDetails, LocalDate> accountingFilesDetailsEndDate;

@FXML
private TableColumn<AccountingFilesDetails, String> accountingFilesDetailsFileName;

@FXML
private TableColumn<AccountingFilesDetails, String> accountingFilesDetailsLocation;

@FXML
private TableColumn<AccountingFilesDetails, String> accountingFilesDetailsBackupLocation;

@FXML
private TableColumn<AccountingFilesDetails, Boolean> accountingFilesDetailsClosed;

@FXML
private TableColumn<AccountingFiles, Boolean> currentAccountingSelectedFile;

@FXML
private TableColumn<AccountingFiles, String> accountingFileName;

@FXML
private TableColumn<AccountingFiles, String> accountingFilePassword;

private ObservableList<AccountingFiles> accountingData = FXCollections.observableArrayList();
private ObservableList<AccountingFilesDetails> accountingDetails = FXCollections.observableArrayList();

EntityManager mainEm = Connector.getMainEntityManager();
;

MainApp mainApp;

public void setMainApp(MainApp mainApp) {
    this.mainApp = mainApp;
    System.out.println(AccountingFilesTable);
}

@Override
public void initialize(URL url, ResourceBundle rb) {

    accountingFileName.setCellValueFactory(new PropertyValueFactory<AccountingFiles, String>("accFileName"));
    accountingFileName.setCellFactory(TextFieldTableCell.<AccountingFiles>forTableColumn());
    accountingFilePassword.setCellValueFactory(new PropertyValueFactory<AccountingFiles, String>("accFilePassword"));
    accountingFilePassword.setCellFactory(param -> new PasswordLabelCell());
    currentAccountingSelectedFile.setCellValueFactory(new PropertyValueFactory<AccountingFiles, Boolean>("currentAccSelectedFile"));
    currentAccountingSelectedFile.setCellFactory(CheckBoxTableCell.forTableColumn(currentAccountingSelectedFile));
    currentAccountingSelectedFile.setEditable(false);
    AccountingFilesTable.setEditable(true);
    addingItems();
AccountingFilesTable.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showAccountingFilesDetails(newValue));

}

public void addingItems() {
    List<AccountingFiles> listOfAccountingFiles = mainEm.createNamedQuery("AccountingFiles.findAll").getResultList();
    accountingData.addAll(listOfAccountingFiles);
    AccountingFilesTable.setItems(accountingData);
}

@FXML
private void handleSelect() {
    System.out.println("begin handleSelect");
    AccountingFiles curraccfile = AccountingFilesTable.getSelectionModel().getSelectedItem();
    AccountingFilesTable.getSelectionModel().clearSelection();
    System.out.println("after clearSelection");

    System.out.println(curraccfile.getAccountingFilesName());

    for (AccountingFiles af : accountingData) {

        mainEm.getTransaction().begin();
        af.setAccountingFilesActiveStatus(false);
        mainEm.getTransaction().commit();

        System.out.println("in looooooooooooop");
    }
    System.out.println("after the loop finished");
    mainEm.getTransaction().begin();
    curraccfile.setAccountingFilesActiveStatus(true);
    mainEm.getTransaction().commit();
    System.out.println("after the lastcommit of  finished");
    List<AccountingFiles> listOfAccountingFiles = mainEm.createNamedQuery("AccountingFiles.findAll").getResultList();



    accountingData.setAll(listOfAccountingFiles);
    System.out.println("after setall method");


}

private void showAccountingFilesDetails(AccountingFiles newValue) {

    handleSelect();

     }


}


}

public class PasswordLabelCell extends TableCell<AccountingFiles, String> {

    private Label label;

    public PasswordLabelCell() {
        label = new Label();
        this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        this.setGraphic(null);
    }

    private String genDotString(int len) {
        String dots = "";

        for (int i = 0; i < len; i++) {
            dots += "\u2022";
        }

        return dots;
    }

    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (!empty) {
            label.setText(genDotString(item.length()));
            setGraphic(label);
        } else {
            setGraphic(null);
        }
    }
}

}

已满 class。 我尝试添加按钮,并在 actionlistener 上调用了 showAccountingFilesDetails 它起作用了,没有发生异常,但我不明白为什么,我不想 select 行并按下按钮来执行我的代码,这样做很尴尬...

大家好谢谢大家的回复我已经制作了一个 MCVE

import java.util.Arrays;
import java.util.List;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableWithCheckbox extends Application {

final TableView<Player> table = new TableView<Player>();
ObservableList<Player> data;

@Override
public void start(Stage primaryStage) {
    final BorderPane root = new BorderPane();

    table.setItems(createData());
    final TableColumn<Player, String> firstNameColumn = new TableColumn<>("First Name");
    final TableColumn<Player, String> lastNameColumn = new TableColumn<>("Last Name");
    final TableColumn<Player, Boolean> selectedColumn = new TableColumn<>("selected");
    firstNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("firstName"));
    lastNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("lastName"));
    selectedColumn.setCellValueFactory(new PropertyValueFactory<Player, Boolean>("selected"));
    final Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>> cellFactory = CheckBoxTableCell.forTableColumn(selectedColumn);
    selectedColumn.setCellFactory(new Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>>() {
        @Override
        public TableCell<Player, Boolean> call(TableColumn<Player, Boolean> column) {
            TableCell<Player, Boolean> cell = cellFactory.call(column);
            cell.setAlignment(Pos.CENTER);
            return cell;
        }
    });
    selectedColumn.setCellFactory(cellFactory);
    selectedColumn.setEditable(false);

    table.setEditable(true);
    table.getColumns().addAll(selectedColumn, firstNameColumn, lastNameColumn);

    root.setCenter(table);

    Button button1 = new Button("add");
    button1.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            data.add(new Player("hbghj", "hjhbbccc77", false));
        }
    });

    root.setTop(button1);
    primaryStage.setScene(new Scene(root, 400, 600));
    primaryStage.show();
}

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

private ObservableList<Player> createData() {
    List<Player> players = Arrays.asList(
            new Player("Hugo", "Lloris", true),
            new Player("Brad", "Friedel", false),
            new Player("Kyle", "Naughton", false),
            new Player("Younes", "Kaboul", false),
            new Player("Benoit", "Assou-Ekotto", false),
            new Player("Jan", "Vertonghen", false),
            new Player("Michael", "Dawson", false),
            new Player("William", "Gallas", false),
            new Player("Kyle", "Walker", false),
            new Player("Scott", "Parker", false),
            new Player("Mousa", "Dembele", false),
            new Player("Sandro", "Cordeiro", false),
            new Player("Tom", "Huddlestone", false),
            new Player("Gylfi", "Sigurdsson", false),
            new Player("Gareth", "Bale", false),
            new Player("Aaron", "Lennon", false),
            new Player("Jermane", "Defoe", false),
            new Player("Emmanuel", "Adebayor", false)
    );
    data = FXCollections.<Player>observableArrayList(
            new Callback<Player, Observable[]>() {
                @Override
                public Observable[] call(Player player) {
                    return new Observable[]{player.selectedProperty()};
                }
            }
    );
    data.addAll(players);
    data.addListener(new ListChangeListener<Player>() {
        @Override
        public void onChanged(
                javafx.collections.ListChangeListener.Change<? extends Player> change) {
            System.out.println("List changed");
            while (change.next()) {
                if (change.wasUpdated()) {
                    System.out.println("What code a do here");
                    System.out.println();
                }
            }
        }
    });
    table.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object oldValue, Object newValue) {

            Player currPlayer = table.getSelectionModel().getSelectedItem();
            table.getSelectionModel().clearSelection();
            System.out.println("after clearSelection");

            for (Player pl : players) {

                pl.setSelected(false);

            }

            currPlayer.setSelected(true);

        }
    });
    return data;
}

public static class Player {

    private final StringProperty firstName;
    private final StringProperty lastName;
    private final BooleanProperty selected;

    Player(String firstName, String lastName, boolean international) {
        this.firstName = new SimpleStringProperty(this, "firstName", firstName);
        this.lastName = new SimpleStringProperty(this, "lastName", lastName);
        this.selected = new SimpleBooleanProperty(this, "selected", international);
    }

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

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

    public StringProperty firstNameProperty() {
        return firstName;
    }

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

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

    public StringProperty lastNameProperty() {
        return lastName;
    }

    public boolean isSelected() {
        return selected.get();
    }

    public void setSelected(boolean international) {
        this.selected.set(international);
    }

    public BooleanProperty selectedProperty() {
        return selected;
    }

    @Override
    public String toString() {
        return firstName.get() + " " + lastName.get() + (selected.get() ? " (injured)" : "");
    }
}
}

出现同样的问题,同样的异常请帮忙

真的没有时间清理代码。请多多包涵。这是您发布的任何内容的工作模型。

import java.util.Arrays;
import java.util.List;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableWithCheckbox extends Application {

    final TableView<Player> table = new TableView<Player>();
    ObservableList<Player> data;

    @Override
    public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();

        table.setItems(createData());
        final TableColumn<Player, String> firstNameColumn = new TableColumn<>(
                "First Name");
        final TableColumn<Player, String> lastNameColumn = new TableColumn<>(
                "Last Name");
        final TableColumn<Player, Boolean> selectedColumn = new TableColumn<>(
                "selected");
        firstNameColumn
                .setCellValueFactory(new PropertyValueFactory<Player, String>(
                        "firstName"));
        lastNameColumn
                .setCellValueFactory(new PropertyValueFactory<Player, String>(
                        "lastName"));
        selectedColumn
                .setCellValueFactory(new PropertyValueFactory<Player, Boolean>(
                        "selected"));
        final Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>> cellFactory = CheckBoxTableCell
                .forTableColumn(selectedColumn);
        selectedColumn
                .setCellFactory(new Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>>() {
                    @Override
                    public TableCell<Player, Boolean> call(
                            TableColumn<Player, Boolean> column) {
                        TableCell<Player, Boolean> cell = cellFactory
                                .call(column);
                        cell.setAlignment(Pos.CENTER);
                        return cell;
                    }
                });
        selectedColumn.setCellFactory(cellFactory);
        selectedColumn.setEditable(false);

        table.setEditable(true);
        table.getColumns().addAll(selectedColumn, firstNameColumn,
                lastNameColumn);
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        root.setCenter(table);

        Button button1 = new Button("add");
        button1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                data.add(new Player("hbghj", "hjhbbccc77", false));
            }
        });

        root.setTop(button1);
        primaryStage.setScene(new Scene(root, 400, 600));
        primaryStage.show();
    }

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

    private ObservableList<Player> createData() {
        List<Player> players = Arrays.asList(
                new Player("Hugo", "Lloris", true), new Player("Brad",
                        "Friedel", false),
                new Player("Kyle", "Naughton", false), new Player("Younes",
                        "Kaboul", false), new Player("Benoit", "Assou-Ekotto",
                        false), new Player("Jan", "Vertonghen", false),
                new Player("Michael", "Dawson", false), new Player("William",
                        "Gallas", false), new Player("Kyle", "Walker", false),
                new Player("Scott", "Parker", false), new Player("Mousa",
                        "Dembele", false), new Player("Sandro", "Cordeiro",
                        false), new Player("Tom", "Huddlestone", false),
                new Player("Gylfi", "Sigurdsson", false), new Player("Gareth",
                        "Bale", false), new Player("Aaron", "Lennon", false),
                new Player("Jermane", "Defoe", false), new Player("Emmanuel",
                        "Adebayor", false));
        data = FXCollections
                .<Player> observableArrayList(new Callback<Player, Observable[]>() {
                    @Override
                    public Observable[] call(Player player) {
                        return new Observable[] { player.selectedProperty() };
                    }
                });
        data.addAll(players);
        data.addListener(new ListChangeListener<Player>() {
            @Override
            public void onChanged(
                    javafx.collections.ListChangeListener.Change<? extends Player> change) {
                System.out.println("List changed");
                while (change.next()) {
                    if (change.wasUpdated()) {
                        System.out.println("What code a do here");
                        System.out.println();
                    }
                }
            }
        });
        table.getSelectionModel().selectedItemProperty()
                .addListener(new ChangeListener<Player>() {
                    @Override
                    public void changed(ObservableValue observableValue,
                            Player oldValue, Player newValue) {

                        Player currPlayer = table.getSelectionModel()
                                .getSelectedItem();

                        System.out.println("after clearSelection");

                        currPlayer.setSelected(true);
                    }
                });
        return data;
    }

    public static class Player {

        private final StringProperty firstName;
        private final StringProperty lastName;
        private final BooleanProperty selected;

        Player(String firstName, String lastName, boolean international) {
            this.firstName = new SimpleStringProperty(this, "firstName",
                    firstName);
            this.lastName = new SimpleStringProperty(this, "lastName", lastName);
            this.selected = new SimpleBooleanProperty(this, "selected",
                    international);
        }

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

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

        public StringProperty firstNameProperty() {
            return firstName;
        }

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

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

        public StringProperty lastNameProperty() {
            return lastName;
        }

        public boolean isSelected() {
            return selected.get();
        }

        public void setSelected(boolean international) {
            this.selected.set(international);
        }

        public BooleanProperty selectedProperty() {
            return selected;
        }

        @Override
        public String toString() {
            return firstName.get() + " " + lastName.get()
                    + (selected.get() ? " (injured)" : "");
        }
    }
}

这不会在选中任何复选框时 un-check 其他复选框,因为我认为这不是一个好主意。如果您希望它以这种方式工作,只需添加回环即可。

for (Player pl : players) {
    pl.setSelected(false);
}