JavaFX:如何用具有相同父类(super class)的 2 个不同类填充 TableView

标签 java inheritance javafx tableview

我有 3 个类,第一个是 Library Item,这是父类(super class)。另外两个类是书籍和电影。当我想要填充我的 TableView 时,我想确保在填充 TableView 时调用了正确的属性。我知道为了便于使用而将导演和作者称为相同的更容易,但我想让它用于学习目的。为了相关性,我省略了包和导入。

图书馆项目类

public abstract class LibraryItem {
    private int itemCode;
    private String title;
    private boolean availability;
    private int memberIdentifier;
    private LocalDate dateLent;

    protected LibraryItem(int itemCode, String title, boolean availability, int memberIdentifier, LocalDate dateLent) {
        this.itemCode = itemCode;
        this.title = title;
        this.availability = availability;
        this.memberIdentifier = memberIdentifier;
        this.dateLent = dateLent;
    }

    public int getItemCode() {
        return itemCode;
    }

    public String getTitle() {
        return title;
    }

    public boolean isAvailability() {
        return availability;
    }

    public void setAvailability(boolean availability) {
        this.availability = availability;
    }

    public int getMemberIdentifier() {
        return memberIdentifier;
    }

    public void setMemberIdentifier(int memberIdentifier) {
        this.memberIdentifier = memberIdentifier;
    }

    public LocalDate getDateLent() {
        return dateLent;
    }

    public void setDateLent(LocalDate dateLent) {
        this.dateLent = dateLent;
    }
}

读书课

public class Book extends LibraryItem {
    private String author;

    protected Book(int itemCode, String title, boolean isLent, int memberIdentifier, LocalDate dateLent, String author) {
        super(itemCode, title, isLent, memberIdentifier, dateLent);
        this.author = author;
    }
}

电影课

public class Movie extends LibraryItem {
    private String director;

    protected Movie(int itemCode, String title, boolean isLent, int memberIdentifier, LocalDate dateLent, String director) {
        super(itemCode, title, isLent, memberIdentifier, dateLent);
        this.director = director;
    }
}

我在想也许我可以对实现的每一行进行某种检查,以便给出正确的值,

这是我的尝试:

public class CollectionController implements Initializable {
    @FXML
    private TableView<LibraryItem> libraryItemsTable;
    @FXML
    private TableColumn<LibraryItem, String> itemCodeColumn;
    @FXML
    private TableColumn<LibraryItem, String>  availableColumn;
    @FXML
    private TableColumn<LibraryItem, String>  titleColumn;
    @FXML
    private TableColumn<LibraryItem, String>  authorDirectorColumn;
    private LibraryService libraryService = new LibraryService();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        initializeTableView();
    }

    private void initializeTableView() {
        List<LibraryItem> libraryItems = libraryService.getLibraryItems();

        itemCodeColumn.setCellValueFactory(new PropertyValueFactory<>("itemCode"));
        availableColumn.setCellValueFactory(new PropertyValueFactory<>("availability"));
        titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
        
        // implement here check for each new row
        if (checkIfBook(row))
            authorDirectorColumn.setCellValueFactory(new PropertyValueFactory<>("author"));
        else
            authorDirectorColumn.setCellValueFactory(new PropertyValueFactory<>("director"));
        //

        libraryItemsTable.getItems().addAll(libraryItems);
    }

最佳答案

如果你听从建议here并避免使用 PropertyValueFactory,解决方案变得相当清晰:

titleColumn.setCellValueFactory(data -> 
    new SimpleStringProperty(data.getValue().getTitle()));

authorDirectorColumn.setCellValueFactory(data -> {
    LibraryItem item = data.getValue();
    if (item instanceof Book book) {
        return new SimpleStringProperty(book.getAuthor());
    } else if (item instanceof Movie movie) {
        return new SimpleStringProperty(movie.getProducer());
    } else {
        return null ;
    }
});

这是一个完整的示例(为简洁起见,我简化了模型类,但保留的内容足以证明这一点):

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        TableView<LibraryItem> table = new TableView<>();
        TableColumn<LibraryItem, String> titleColumn = new TableColumn<>("Title");
        TableColumn<LibraryItem, String> authorProducerColumn = new TableColumn<>("Author/Producer");
        table.getColumns().add(titleColumn);
        table.getColumns().add(authorProducerColumn);

        titleColumn.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().getTitle()));

        authorProducerColumn.setCellValueFactory(data -> {
            LibraryItem item = data.getValue();
            if (item instanceof Book book) {
                return new SimpleStringProperty(book.getAuthor());
            } else if (item instanceof Movie movie) {
                return new SimpleStringProperty(movie.getProducer());
            } else return null ;
        });

        for (int i = 1 ; i <= 10 ; i++) {
            Book book = new Book("Book "+i, "Author "+i);
            Movie movie = new Movie("Movie "+i, "Producer "+i);
            table.getItems().addAll(book, movie);
        }

        BorderPane root = new BorderPane(table);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public class LibraryItem {
        private String title ;
        public LibraryItem(String title) {
            this.title = title ;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

    public class Movie extends LibraryItem {
        private String producer ;
        public Movie(String title, String producer) {
            super(title);
            this.producer = producer ;
        }

        public String getProducer() {
            return producer;
        }

        public void setProducer(String producer) {
            this.producer = producer;
        }
    }

    public class Book extends LibraryItem {
        private String author ;
        public Book(String title, String author) {
            super(title);
            this.author = author ;
        }

        public String getAuthor() {
            return author;
        }

        public void setAuthor(String author) {
            this.author = author;
        }
    }

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

enter image description here

关于JavaFX:如何用具有相同父类(super class)的 2 个不同类填充 TableView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74255691/

相关文章:

java - 如何将 <br/> 标签插入 java String

java - pig 拉丁翻译器java

swift - 使用继承时,为什么不能为在协议(protocol)中返回 Self 的 Type 函数提供默认实现?

image - 如何在imageview上设置文件(图像)

java - 在两个 anchor Pane 之间切换

java - 带有 JMX 的 JEE 应用程序

java - 如何对AbstractRoutingDataSource进行安全频繁的DataSource切换?

java - java中继承是编译时还是运行时

c++ - 虚函数重定义隐藏了另一个基类的同名重载函数

java - 为 HBox 设置背景图像 - JavaFX