JavaFx8 Tableview更新ObservableList

时间:2015-04-01 09:04:25

标签: java javafx-8

我有一个表格内的表格我有复选框我需要的东西,当我选择行来选中此复选框和其他复选框取消选择 我解决它通过在表视图上有监听器并迭代列表项并设置选中的false并且只选择的行为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$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.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.access$1500(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$handleMouseEvent$350(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$176/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$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/1030870354.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

请帮助我摆脱这种情况我已经在这些例外情况下通过我的表视图正常工作的方式存放了几天,但这些例外仍然存在。

这是我的全班实现     package 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);
        }
    }
}

}

这是全班。 我试图添加按钮和动作滑块我称为showAccountingFilesDetails它工作,没有发生异常,但我不明白为什么,我不想选择行和按下按钮来做我的代码令人尴尬这样做...

嘿,大家好,感谢你们的答复,我已经制作了一部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)" : "");
    }
}
}

出现相同的问题,同样的例外情况请帮助

1 个答案:

答案 0 :(得分:0)

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

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);
}
相关问题