Hassan Kbbewar
Hassan Kbbewar

Reputation: 183

JavaFx8 Tableview updating ObservableList

i have a table view inside the table i have check box i need something when i select row to make this check box selected and other check boxes to deselect i solve it by having listener on the table view and iterate over the list items and set checked false and only the selected row true but the problem i have is when i called ObservableList.setall(...) i got these exceptions after my code

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)

please help me get out of this i have been stocked for days in these exceptions by the way my table view works fine but these exceptions still exists.

here is my full class implementation 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);
        }
    }
}

}

that is full class . i have tried to add button and on actionlistener i called showAccountingFilesDetails it worked and no exception occurred but i didnt understand why and i dont want to select row and press button to do my code its embarrassing to do so ...

hey guys thanks all for your reply i have made a MCVE and there it is

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)" : "");
    }
}
}

the same proplem occur and the same exceptions please help

Upvotes: 1

Views: 2284

Answers (1)

ItachiUchiha
ItachiUchiha

Reputation: 36792

Don't really have time to clean the code. Please bear with me. Here is a working model of whatever you posted.

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)" : "");
        }
    }
}

This doesn't un-check the other checkboxes while selecting any checkbox because I didn't think it is a good idea. If you want it to work it that way, just add the loop back.

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

Upvotes: 0

Related Questions