Не удается понять ComboBoxTableCell в TableView

#javafx-8

#javafx-8

Вопрос:

Я прочитал все, что доступно на этом сайте и других; Я вырезал и вставил каждую строку кода, когда-либо написанную по этому вопросу (готов поспорить). Вот каков результат:

 final class Books extends Group {

private TableView table = new TableView();
private ObservableList<Book> data = FXCollections.observableArrayList();
final HBox hb = new HBox();
final TextField Title = new TextField();
final TextField Author = new TextField();
final TextField Publisher = new TextField();
final TextField Copywrite = new TextField();
final TextField ISBN = new TextField();
final Boolean CheckedOut = false;
final Label Whom;
final Button addButton = new Button("Add");
Boolean FirstRead = true;

public static class Book {

    private final SimpleStringProperty title;
    private final SimpleStringProperty author;
    private final SimpleStringProperty publisher;
    private final SimpleStringProperty copywrite;
    private final SimpleStringProperty isbn;
    private final BooleanProperty checkedout;
    private final SimpleStringProperty who;

    Book(String Titl, String Auth, String Publ,
            String Cpywrit, String IsBn, Boolean ChkdOut, String WHO) {

        this.title = new SimpleStringProperty(Titl);
        this.author = new SimpleStringProperty(Auth);
        this.publisher = new SimpleStringProperty(Publ);
        this.copywrite = new SimpleStringProperty(Cpywrit);
        this.isbn = new SimpleStringProperty(IsBn);
        this.checkedout = new SimpleBooleanProperty(ChkdOut);
        this.who = new SimpleStringProperty(WHO);

    }

    public boolean isCheckedOut() {
        return checkedout.get();
    }

    public void setCheckedOut(boolean international) {
        this.checkedout.set(international);
    }

    public BooleanProperty isCheckedOutProperty() {
        return checkedout;
    }

    public String getTitle() {
        return title.get();
    }

    public void setTitle(String Title) {
        title.set(Title);
    }

    public String getAuthor() {
        return author.get();
    }

    public void setAutor(String Author) {
        author.set(Author);
    }

    public String getPublisher() {
        return publisher.get();
    }

    public void setPublisher(String Publisher) {
        publisher.set(Publisher);
    }

    public String getCopywrite() {
        return copywrite.get();
    }

    public void setCopywrite(String Copywrite) {
        copywrite.set(Copywrite);
    }

    public String getIsbn() {
        return isbn.get();
    }

    public void setIsbn(String ISBN) {
        isbn.set(ISBN);
    }

    public Boolean getIo() {
        return checkedout.get();
    }

    public void setIo(Boolean CheckedOut) {
        checkedout.set(CheckedOut);
    }

    public String getWho() {
        return who.get();
    }

    public void setWho(String Who) {
        who.set(Who);
    }

    public ObservableValue<String> whoProperty() {
        return who;
    }
}

public Books(final File User) throws IOException {

    this.Whom = new Label("inLibrary");
    this.data = FXCollections.<Book>observableArrayList(
            (Book bk) -> new Observable[]{bk.isCheckedOutProperty()
            });
    final PhoneList p = new PhoneList(User);
    final Label label = new Label("Book List");
    label.setFont(new Font("Arial", 20));
    table.setPrefSize(600, 400);
    table.setEditable(true);
    TableColumn nameCol = bookName();
    TableColumn authorCol = bookAuthor();
    TableColumn publisherCol = bookPublisher();
    TableColumn copywriteCol = bookCopywrite();
    TableColumn isbnCol = bookISBN();

    final TableColumn<Book, Boolean> ioCol = new TableColumn<>("In/Out");
    ioCol.setMinWidth(50);
    ioCol.setEditable(true);
    ioCol.setCellValueFactory(new PropertyValueFactory<>("isCheckedOut"));
    final Callback<TableColumn<Book, Boolean>, TableCell<Book, Boolean>> iocellFactory = CheckBoxTableCell.forTableColumn(ioCol);
    ioCol.setCellFactory((TableColumn<Book, Boolean> column) -> {
        TableCell<Book, Boolean> iocell = iocellFactory.call(column);
        iocell.setAlignment(Pos.CENTER);
        return iocell;
    });
    ioCol.setCellFactory(iocellFactor

    final TableColumn<String, Book> whoCol = new TableColumn<>("Who to");
    whoCol.setMinWidth(100);
    whoCol.setEditable(true);
    whoCol.setCellValueFactory(new PropertyValueFactory<>("who"));

    whoCol.setCellFactory(ComboBoxTableCell.forTableColumn(new StringConverter<Book>() {
        @Override
        public String toString(Book string) {
            return string.getWho();
        }
        @Override
        public Book fromString(String string) {
            return null;
        }
    }, data));


    AddBook(nameCol, authorCol, publisherCol, copywriteCol, isbnCol, ioCol, whoCol, User);

    data.addListener((javafx.collections.ListChangeListener.Change<? extends Book> change) -> {
        while (change.next()) {
            if (change.wasUpdated() amp;amp; FirstRead != true) {
                try {
                    System.out.println("List changed");
                    writeFile(User);
                } catch (IOException ex) {
                    Logger.getLogger(Books.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    });

    final VBox vbox = new VBox();

    vbox.setSpacing(5);
    vbox.setPadding(new Insets(10, 0, 0, 10));
    vbox.getChildren().addAll(label, table, hb);
    getChildren().addAll(vbox);
    try {
        readFile(User);
    } catch (Exception ex) {
        Logger.getLogger(Books.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private TableColumn bookISBN() {

    TableColumn isbnCol = new TableColumn("ISBN #");
    isbnCol.setMinWidth(100);
    isbnCol.setCellValueFactory(
            new PropertyValueFactory<>("isbn"));
    isbnCol.setCellFactory(TextFieldTableCell.forTableColumn());
    return isbnCol;
}

private TableColumn bookCopywrite() {

    TableColumn copywriteCol = new TableColumn("Copywrite");
    copywriteCol.setMinWidth(100);
    copywriteCol.setCellValueFactory(
            new PropertyValueFactory<>("copywrite"));
    copywriteCol.setCellFactory(TextFieldTableCell.forTableColumn());
    return copywriteCol;
}

private TableColumn bookPublisher() {

    TableColumn publisherCol = new TableColumn("Publisher");
    publisherCol.setMinWidth(100);
    publisherCol.setCellValueFactory(
            new PropertyValueFactory<>("publisher"));
    publisherCol.setCellFactory(TextFieldTableCell.forTableColumn());
    return publisherCol;
}

private TableColumn bookAuthor() {

    TableColumn authorCol = new TableColumn("Author");
    authorCol.setMinWidth(100);
    authorCol.setCellValueFactory(
            new PropertyValueFactory<>("author"));
    authorCol.setCellFactory(TextFieldTableCell.forTableColumn());
    return authorCol;
}

private TableColumn bookName() {

    TableColumn nameCol = new TableColumn("Title");
    nameCol.setMaxWidth(100);
    nameCol.setCellValueFactory(
            new PropertyValueFactory<>("title"));
    nameCol.setCellFactory(TextFieldTableCell.forTableColumn());
    return nameCol;
}

private void AddBook(TableColumn nameCol, TableColumn authorCol, TableColumn publisherCol,
        TableColumn copywriteCol, TableColumn isbnCol, TableColumn ioCol, TableColumn whoCol, final File User) {
    table.setItems(data);
    table.getColumns().addAll(nameCol, authorCol, publisherCol, copywriteCol, isbnCol, ioCol, whoCol);

    addButton.setOnAction(
            new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent e) {
                    addBook();
                    try {
                        writeFile(User);
                    } catch (IOException ex) {
                        Logger.getLogger(Books.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                private void addBook() {
                    data.add(new Book(
                                    Title.getText(),
                                    Author.getText(),
                                    Publisher.getText(),
                                    Copywrite.getText(),
                                    ISBN.getText(),
                                    CheckedOut,
                                    Whom.getText()
                            ));

                    Title.clear();
                    Author.clear();
                    Publisher.clear();
                    Copywrite.clear();
                    ISBN.clear();
                }
            });

    hb.getChildren().addAll(Title, Author, Publisher,
            Copywrite, ISBN, addButton);
    hb.setSpacing(10);
    Title.setPromptText("Tile of Book");
    Title.setMaxWidth(nameCol.getPrefWidth());

    Author.setMaxWidth(authorCol.getPrefWidth());
    Author.setPromptText("Author");

    Publisher.setMaxWidth(publisherCol.getPrefWidth());
    Publisher.setPromptText("Publisher");

    Copywrite.setMaxWidth(copywriteCol.getPrefWidth());
    Copywrite.setPromptText("Year Copywrite");

    ISBN.setMaxWidth(isbnCol.getPrefWidth());
    ISBN.setPromptText("ISBN #");
}

private void writeFile(File User) throws IOException {
    File file = new File(User   "/Books.txt");
    FileWriter fw = new FileWriter(file);
    BufferedWriter bw = new BufferedWriter(fw);
    PrintWriter outFile = new PrintWriter(bw);

    if (table.getItems() != null) {
        data.stream().map((data1) -> {
            if (data1.getTitle().equals("")) {
                data1.setTitle("No_Title");
            }
            return data1;
        }).map((data1) -> {
            if (data1.getAuthor().equals("")) {
                data1.setAutor("No_Author");
            }
            return data1;
        }).map((data1) -> {
            if (data1.getPublisher().equals("")) {
                data1.setPublisher("No_Publisher");
            }
            return data1;
        }).map((data1) -> {
            if (data1.getCopywrite().equals("")) {
                data1.setCopywrite("No_Copywrite");
            }
            return data1;
        }).map((data1) -> {
            if (data1.getIsbn().equals("")) {
                data1.setIsbn("No_ISBN");
            }
            return data1;
        }).map((data1) -> {
            if (data1.getWho().equals("")) {
                data1.setWho("InLibrary");
            }
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getTitle());
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getAuthor());
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getPublisher());
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getCopywrite());
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getIsbn());
            return data1;
        }).map((data1) -> {
            outFile.println(data1.getIo());
            return data1;
        }).forEach((data1) -> {
            outFile.println(data1.getWho());
        });
        outFile.close();
    }
}

private void readFile(File User) throws Exception {
    try {
        String name, author, publisher, copywrite, isbn, whom;
        Boolean InOut;
        try (Scanner inFile = new Scanner(new File(User   "/Books.txt"))) {
            while (inFile.hasNextLine()) {
                name = inFile.next();
                author = inFile.next();
                publisher = inFile.next();
                copywrite = inFile.next();
                isbn = inFile.next();
                InOut = inFile.nextBoolean();
                whom = inFile.next();

                data.add(new Book(name, author, publisher, copywrite,
                        isbn, InOut, whom));
            }
        }
        table.setItems(data);

    } //insert catch statements
    catch (FileNotFoundException exception) {
        System.out.println("File not found");
    } catch (ArrayIndexOutOfBoundsException AIOOBexception) {
        System.out.println("Array Index is out of bounds");
    } catch (IllegalArgumentException IAexception) {
        System.out.println("Divide by zero error");
    } catch (NoSuchElementException NAexception) {
    }
    FirstRead = false;
}
}
  

Это выдает следующую ошибку:

 Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: mediatracker.Books$Book cannot be cast to java.lang.String
    at mediatracker.Books$1.toString(Books.java:198)
  

Начинается строка 198:

  whoCol.setCellFactory(ComboBoxTableCell.forTableColumn(new StringConverter<Book>() {
  

Может ли кто-нибудь ввести «теорию», лежащую в основе ComboBoxTableCell, и перечислить части, необходимые для выполнения этого. Все, что я хочу сделать, это изменить значение ячейки, извлеченной из списка телефонов в другом файле.

Комментарии:

1. Похоже, вы пытаетесь преобразовать объект в строку здесь?

2. вместо того, чтобы кричать, вы могли бы рассмотреть возможность показа SSCCE (или MCVE что угодно, пожалуйста, прочитайте FAQ о том, как спросить), который демонстрирует проблему

3. надеюсь, что полный код поможет решить эту проблему

4. В вашем коде много ошибок. Вероятно, вам следует просто начать с чего-то гораздо более простого.

5. ну, хорошо, единственное, что не работает, это ComboBoxTableCell — я продолжу работать над этим. спасибо за вашу помощь. Чтобы увидеть другое приложение, над которым я работаю, и вернуться к нему, когда это будет сделано, я прошу вас перейти [3D UI для MMORPG] » myks3d.webhop.me/EvelynsGEMz.jar » возможно, это «намного проще», о котором вы говорите;)

Ответ №1:

Я просто собираюсь предположить, что строка 198 является

 return (String) object ;
  

в анонимном StringConverter методе toString() . Когда вы отправляете вопрос с трассировкой стека, всегда указывайте, на какую строку в вашем коде указывает исключение.

Во-первых, всегда лучше использовать общие типы вместо необработанных типов. Поэтому вместо

 TableColumn whoCol = ...
  

у вас должно быть

 TableColumn<S,T> whoCol = ...
  

где вы заменяете S типом данных в таблице и T типом данных в столбце. Поскольку вы не привели полный пример, я не могу угадать, что S это; из сообщения об ошибке похоже, что тип данных в столбце может быть Book .

Прочитайте Javadocs для метода, который вы вызываете. Они четко указывают, что такое конвертер:

конвертер — преобразователь строк для преобразования данного элемента (типа T) в строку для отображения пользователю.

Итак, предполагая, что вы TableColumn отображаете Book s, и предполагая data , что это тип ObservableList<Book> , у вас должно быть что-то вроде

 ObservableList<Book> data = ... ;
TableColumn<S, Book> whoCol = new TableColumn<>("Who to");
// ...
whoCol.setCellFactory(ComboBoxTableCell.forTableColumn(new StringConverter<Book>() {

    @Override
    public String toString(Book book) {
        // assuming your Book class defines a getTitle() method, and that's
        // how you want to display it in your ComboBox:
        return book.getTitle(); // or get a String from book some other way
    }

    @Override
    public Book fromString(String string) {
        // I think this is not actually used, as the combo box is not editable
        // So you could probably safely just return null here.
        // But in general:
        Book book = ... ; // create a book from the string
        return book ;
    }
}, data)); 
  

Опять же, вы заменяете S тем, что используете для типа TableView ; и снова мне пришлось строить догадки о типе вашего TableColumn , поскольку вы не предоставили полный пример. Но этого должно быть достаточно, чтобы вы поняли идею.

Комментарии:

1. James_D О боже, большое вам спасибо, код абсолютно оценен, но теория была самой превосходной. Извините за крик, это не было моим намерением: D

2. Моя попытка состоит в том, чтобы изменить значение ячейки с помощью combobox, который использует ObservableList, созданный из другого файла — PhoneList, чтобы отразить человека, которому выписана книга. Пока я могу отобразить список, поместить выделение в ячейку, теперь сохранить его в текстовом файле, который был создан на более раннем шаге. Большое вам спасибо за эту помощь. обновит прогресс и попытается опубликовать весь файл.

3. При замене вашего кода вместо моего он по-прежнему выдает мне ту же ошибку: исключение в потоке «Поток приложения JavaFX» java.lang. ClassCastException: java.lang. Строка не может быть передана в mediatracker. Книги $Book в mediatracker. Books$ 1.toString(Books.java:194) 194 это: ‘whoCol.setCellFactory(ComboBoxTableCell.forTableColumn(new StringConverter<Book>() {‘ я разместил весь проект на своем веб-сервере (если это кошерно) Ссылка Я действительно не знаю java или javafx — просто пытаюсь помочь другу с этим — моя сильная сторона — это / была DOS C / C .

4. О, правда, это похоже, но не то же самое. Но вы заставили меня задуматься… пытаюсь сбросить значение: ‘private ObservableList<Book> data = FXCollections.observableArrayList();’ с ‘final PhoneList p = new PhoneList(User);’ в : ‘ final TableColumn<Строка, Книга> whoCol = new TableColumn<>(«Кому»);’ через ComboBoxTableCell. Возможно, мое мышление по этому поводу должно измениться… и вы отправили меня на более глубокие размышления. Я думал, что это TableColumn<Книга, строка> о, а тип столбца — это метка???

Ответ №2:

 `final TableColumn<Book, String> whoCol = new TableColumn<>("Who to");
    whoCol.setMinWidth(100);
    whoCol.setEditable(true);
    whoCol.setCellValueFactory(new PropertyValueFactory<>("who"));

    whoCol.setCellFactory(ComboBoxTableCell.<Book, String>forTableColumn(p.data.get(myIndex()).toString()));
    whoCol.setOnEditCommit((TableColumn.CellEditEvent<Book, String> t) -> {
        ((Book) t.getTableView().getItems().get(
                t.getTablePosition().getRow()))
                .setWho(t.getNewValue());
        try {
            writeFile(User);
        } catch (IOException ex) {
            Logger.getLogger(Books.class.getName()).log(Level.SEVERE, null, ex);
        }
    });`
  

Это работает — @James_D спасибо за вашу помощь — вы направили меня в правильном направлении

Ответ №3:

Ваши проблемы, похоже, не имеют ничего общего с ComboBoxTableCell .

Ваш метод toString() неверен; вы пытаетесь преобразовать объект в строку. Вот (вероятно) почему вы видите java.lang.ClassCastException. Можете ли вы проверить, какая строка является строкой 198?

Кроме того, я замечаю, что весь ваш метод fromString() возвращает свой аргумент. Чего именно вы пытаетесь достичь здесь, в этом фрагменте кода? Не могли бы вы дать нам немного больше справочной информации?