biz
biz

Reputation: 53

Why is data still remaining after I remove an item from a ListView and a corresponding ObservableList?

I'm creating a ListView using javafx and allowing the user to Add, Check Out, Check In, and Delete elements of the ListView. When an element is deleted, though, and another element is put into its place, the program acts as if the deleted element is still present therefor if I try to check out the newly added element, it instead checks out the one I just tried to delete.

Simply put, this is what happen:
Add --> "item 1"
Add --> "item 2"
Delete --> "item 1" (item 1 is now removed and item 2 shifts up in the ViewList)
Check out --> "item 2" (a prompt appears allowing the user to state who the item is checked out to and the date it was checked out)

After the user fills in the information, the line now reads "item 1 was checked out to "name" on "date"."
It should say item 2 instead of item 1 and I can't figure out why it is doing so.

LibraryGUI.java

import java.util.ArrayList;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.ChoiceBoxListCell;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class LibraryGUI extends Application implements EventHandler<ActionEvent> {
    private Library lib = new Library();
    private ObservableList<String> item = FXCollections.observableArrayList();
    private ListView<String> items = new ListView<String>(item);
    private ArrayList<String> titles = new ArrayList<String>();
    private ArrayList<String> formats = new ArrayList<String>();
    private String title, format, loanedTo, dateLoaned;
    private Button add, checkOut, checkIn, delete, accept1, accept2, accept3, accept4, cancel1, cancel2, cancel3,
            cancel4;
    private TextField tf1, tf2, tf3, tf4;
    private Stage stage1, stage2, stage3, stage4;
    private int itemNum;

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        LibraryGUI gui = new LibraryGUI();
        primaryStage.setTitle("Personal Lending Library");
        items.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        Scene scene = new Scene(gui.layout(), 325, 340);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public Pane layout() {

        add = new Button("Add");
        add.setOnAction(this);
        add.setLayoutX(5);
        add.setLayoutY(310);
        add.setPrefWidth(75);

        checkOut = new Button("Check Out");
        checkOut.setOnAction(this);
        checkOut.setLayoutX(85);
        checkOut.setLayoutY(310);
        checkOut.setPrefWidth(75);

        checkIn = new Button("Check In");
        checkIn.setOnAction(this);
        checkIn.setLayoutX(165);
        checkIn.setLayoutY(310);
        checkIn.setPrefWidth(75);

        delete = new Button("Delete");
        delete.setOnAction(this);
        delete.setLayoutX(245);
        delete.setLayoutY(310);
        delete.setPrefWidth(75);

        Pane layout = new Pane();
        items.setItems(item);
        items.setCellFactory(ChoiceBoxListCell.forListView(item));
        items.setLayoutX(5);
        items.setLayoutY(5);
        items.setPrefWidth(315);
        items.setPrefHeight(300);
        layout.getChildren().addAll(items, add, checkOut, checkIn, delete);
        return layout;
    }

    @Override
    public void handle(ActionEvent event) {
        if (event.getSource() == add) {

            accept1 = new Button("Accept");
            accept1.setPrefWidth(70);
            accept1.setLayoutX(125);
            accept1.setLayoutY(65);
            accept1.setOnAction(this);
            cancel1 = new Button("Cancel");
            cancel1.setPrefWidth(70);
            cancel1.setLayoutX(205);
            cancel1.setLayoutY(65);
            cancel1.setOnAction(this);

            Text dialog = new Text("Media Item Name:");
            dialog.setLayoutX(20);
            dialog.setLayoutY(45);

            tf1 = new TextField();
            tf1.setPrefHeight(20);
            tf1.setPrefWidth(150);
            tf1.setLayoutX(125);
            tf1.setLayoutY(30);

            Pane layout1 = new Pane();
            layout1.getChildren().addAll(tf1, dialog, accept1, cancel1);

            stage1 = new Stage();
            stage1.setTitle("Item Name");
            stage1.setScene(new Scene(layout1, 400, 100));
            stage1.show();
        }

        if (event.getSource() == cancel1) {
            stage1.close();
        }

        if (event.getSource() == accept1) {
            title = tf1.getText();
            titles.add(tf1.getText());
            stage1.close();

            accept2 = new Button("Accept");
            accept2.setPrefWidth(70);
            accept2.setLayoutX(125);
            accept2.setLayoutY(65);
            accept2.setOnAction(this);
            cancel2 = new Button("Cancel");
            cancel2.setPrefWidth(70);
            cancel2.setLayoutX(205);
            cancel2.setLayoutY(65);
            cancel2.setOnAction(this);

            Text dialog = new Text("Media Item Format:");
            dialog.setLayoutX(15);
            dialog.setLayoutY(45);

            tf2 = new TextField();
            tf2.setPrefHeight(20);
            tf2.setPrefWidth(150);
            tf2.setLayoutX(125);
            tf2.setLayoutY(30);
            format = tf2.getText();

            Pane layout2 = new Pane();
            layout2.getChildren().addAll(tf2, dialog, accept2, cancel2);

            stage2 = new Stage();
            stage2.setTitle("Item Format");
            stage2.setScene(new Scene(layout2, 400, 100));
            stage2.show();
        }

        if (event.getSource() == cancel2) {
            title = null;
            titles.remove(titles.size() - 1);
            stage2.close();
        }

        if (event.getSource() == accept2) {
            format = tf2.getText();
            formats.add(tf2.getText());
            lib.addNewItem(title, format);
            items.getItems().add(title + " (" + format + ")");
            stage2.close();

        }

        if (event.getSource() == checkOut) { //item is being checked out
            item = items.getSelectionModel().getSelectedItems();

            for (int i = 0; i < items.getItems().size(); i++) {
                if (items.getSelectionModel().getSelectedItem()
                        .equals(lib.getItemList().get(i).getTitle() + " (" + lib.getItemList().get(i).getFormat() + ")")

                        && !lib.getItemList().get(i).onLoan) {
                    itemNum = i;

                    accept3 = new Button("Accept");
                    accept3.setPrefWidth(70);
                    accept3.setLayoutX(125);
                    accept3.setLayoutY(65);
                    accept3.setOnAction(this);
                    cancel3 = new Button("Cancel");
                    cancel3.setPrefWidth(70);
                    cancel3.setLayoutX(205);
                    cancel3.setLayoutY(65);
                    cancel3.setOnAction(this);

                    Text dialog = new Text("Loaned To:");
                    dialog.setLayoutX(60);
                    dialog.setLayoutY(45);

                    tf3 = new TextField();
                    tf3.setPrefHeight(20);
                    tf3.setPrefWidth(150);
                    tf3.setLayoutX(125);
                    tf3.setLayoutY(30);

                    Pane layout3 = new Pane();
                    layout3.getChildren().addAll(accept3, cancel3, dialog, tf3);

                    stage3 = new Stage();
                    stage3.setTitle("Check Out");
                    stage3.setScene(new Scene(layout3, 400, 100));
                    stage3.show();

                }
            }
        }

        if (event.getSource() == accept3) {
            loanedTo = tf3.getText();
            lib.getItemList().get(itemNum).loanedTo = loanedTo;
            stage3.close();

            accept4 = new Button("Accept");
            accept4.setPrefWidth(70);
            accept4.setLayoutX(125);
            accept4.setLayoutY(65);
            accept4.setOnAction(this);
            cancel4 = new Button("Cancel");
            cancel4.setPrefWidth(70);
            cancel4.setLayoutX(205);
            cancel4.setLayoutY(65);
            cancel4.setOnAction(this);

            Text dialog = new Text("Date Loaned:");
            dialog.setLayoutX(50);
            dialog.setLayoutY(45);

            tf4 = new TextField();
            tf4.setPrefHeight(20);
            tf4.setPrefWidth(150);
            tf4.setLayoutX(125);
            tf4.setLayoutY(30);

            Pane layout3 = new Pane();
            layout3.getChildren().addAll(accept4, cancel4, dialog, tf4);

            stage4 = new Stage();
            stage4.setTitle("Check Out");
            stage4.setScene(new Scene(layout3, 400, 100));
            stage4.show();

        }

        if (event.getSource() == accept4) {
            stage4.close();
            dateLoaned = tf4.getText();
            lib.getItemList().get(items.getSelectionModel().getSelectedIndex()).dateLoaned = dateLoaned;
            lib.getItemList().get(items.getSelectionModel().getSelectedIndex()).onLoan = true;

            items.getItems().set(items.getSelectionModel().getSelectedIndex(),
                    titles.get(items.getSelectionModel().getSelectedIndex()) + " ("
                            + formats.get(items.getSelectionModel().getSelectedIndex()) + ") loaned to " + loanedTo
                            + " on " + dateLoaned);
        }

        if (event.getSource() == checkIn) {
            for (int i = 0; i < items.getItems().size(); i++) {
                if (items.getSelectionModel().getSelectedItem().contains(lib.getItemList().get(i).getTitle())
                        && items.getSelectionModel().getSelectedItem().contains(lib.getItemList().get(i).getFormat())
                        && lib.getItemList().get(i).onLoan) {
                    itemNum = i;
                    items.getItems().set(items.getSelectionModel().getSelectedIndex(),
                            titles.get(items.getSelectionModel().getSelectedIndex()) + " ("
                                    + formats.get(items.getSelectionModel().getSelectedIndex()) + ")");

                    lib.getItemList().get(items.getSelectionModel().getSelectedIndex()).dateLoaned = null;
                    lib.getItemList().get(items.getSelectionModel().getSelectedIndex()).onLoan = false;

                }
            }
        }

        if (event.getSource() == delete) { //item is being deleted from all lists
            items.getItems().remove(items.getSelectionModel().getSelectedIndex());
            for (int i = 0; i < items.getItems().size(); i++) {
                if (items.getSelectionModel().getSelectedItem().contains(lib.getItemList().get(i).getTitle())
                        && items.getSelectionModel().getSelectedItem().contains(lib.getItemList().get(i).getFormat())) {
                    itemNum = i;
                    lib.getItemList().remove(items.getSelectionModel().getSelectedIndex());
                    items.getItems().remove(items.getSelectionModel().getSelectedIndex());
                    titles.remove(items.getSelectionModel().getSelectedIndex());
                    formats.remove(items.getSelectionModel().getSelectedIndex());

                }
            }
        }

    }

}

Library.java

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class Library {

    private ObservableList<MediaItem> item = FXCollections.observableArrayList();

    public ObservableList<MediaItem> getItemList() {
        return item;
    }

    void addNewItem(String title, String format) {
        item.add(new MediaItem(title, format));

    }

I only recently started programming in Java so my code most likely isn't quite optimized. Any and all help will be greatly appreciated. Thanks.

Upvotes: 0

Views: 480

Answers (1)

MMAdams
MMAdams

Reputation: 1498

This isn't a complete answer, since I didn't run your code, but looking at it I had a couple of suggestions for you.

First off, having your entire class be an ActionEvent and having a single 'handle' method is probably not ideal. I would split up that handle method into separate methods, named like this public void handleAdd(ActionEvent event) and add them to your buttons like this add.setOnAction((ActionEvent e) -> handleAdd(e));. This makes more sense because each button has a specific action associated with it, and that action is contained in a specific method.

Secondly, do you need four lists and a Library object (which looks to be just a wrapper for another list)? You're trying to keep five different lists in sync with each other, and that's bound to cause problems like the ones you're seeing now as well as headache for you or whomever has to read and maintain the code in the future. Consider instead just having your Library and making your ListView use type MediaItem instead of String and add loanedto and dateloaned as properties of MediaItem, assuming that's a class you wrote yourself. You can still show the titles properly in the ListView by setting a cell factory like this:

items.setCellFactory(new Callback<ListView<MediaItem>, ListCell<MediaItem>>() {
    @Override
    public ListCell<MediaItem> call(ListView<MediaItem> param) {
        return new ListCell<MediaItem>() {
            @Override
            protected void updateItem(MediaItem item, boolean empty) {
                super.updateItem(item, empty);
                if(item != null) {
                    setText(item.getTitle());
                }else{
                    setText("");
                }
            }
        };
    }
});

Upvotes: 1

Related Questions