同一列中不同类型的对象

时间:2018-04-09 13:03:38

标签: java javafx

我有一张表格,显示有关多次旅行的信息。其中一列是驱动程序,它告诉谁被指定为某次旅行的驾驶员。我想要实现的是,如果没有分配驱动程序(数据库中为null),您应该能够单击该特定单元格中的按钮并选择驱动程序。

事实证明这比我最初的想法更具挑战性。这是个主意: enter image description here

我在下面找到了问题,但我不确定如何在我的系统中实现该解决方案。 JavaFX 2 TableView : different cell factory depending on the data inside the cell

我应该研究什么?是否有记录的方法来实现这一目标?

以下是代码:

public class BookViewController {

    private String dbUrl = "jdbc:postgresql://localhost:5432/BookingApp";
    private String dbUsername = "postgres";
    private String dbPassword = "secret";
    @FXML
    private TextField personnr;
    @FXML
    private TextField name;
    @FXML
    private TextField email;
    @FXML
    private TextField telnr;
    @FXML
    private Button addTraveler;
    @FXML
    private Button removeTraveler;
    @FXML
    private TableView<Traveler> travelers;
    @FXML
    private TableColumn<?, ?> personnrColumn;
    @FXML
    private TableColumn<?, ?> nameColumn;
    @FXML
    private TableColumn<?, ?> emailColumn;
    @FXML
    private TableColumn<?, ?> telnrColumn;
    @FXML
    private TableView<Trip> trips;
    @FXML
    private TableColumn<?, ?> originColumn;
    @FXML
    private TableColumn<?, ?> destinationColumn;
    @FXML
    private TableColumn<?, ?> departureColumn;
    @FXML
    private TableColumn<?, ?> arrivalColumn;
    @FXML
    private TableColumn<?, ?> driverColumn;
    @FXML
    private TableColumn<?, ?> priceAmountColumn;
    @FXML
    private TableColumn<?, ?> seatsColumn;
    @FXML
    private Button bookTrip;
    private Trip rowData;
    private ObservableList<Trip> tripData;

    protected void initialize(Trip rowData) {
        this.rowData = rowData;
        addTraveler.setDisable(true);
        removeTraveler.setDisable(true);
        populateTravelPlan();
    }

    @FXML
    private void populateTravelPlan() {
        originColumn.setCellValueFactory(new PropertyValueFactory<>("origin"));
        destinationColumn.setCellValueFactory(new PropertyValueFactory<>("destination"));
        departureColumn.setCellValueFactory(new PropertyValueFactory<>("departure"));
        arrivalColumn.setCellValueFactory(new PropertyValueFactory<>("arrival"));
        driverColumn.setCellValueFactory(new PropertyValueFactory<>("driver"));
        priceAmountColumn.setCellValueFactory(new PropertyValueFactory<>("priceAmount"));
        seatsColumn.setCellValueFactory(new PropertyValueFactory<>("seats"));        

        try {
            Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
            tripData = FXCollections.observableArrayList();
            ResultSet rs = null;
            if(rowData.getTrip1() != 0 && rowData.getTrip2() == 0 && rowData.getTrip3() == 0) {
                rs = conn.createStatement().executeQuery(
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip1() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "order by departure;");
            } else if(rowData.getTrip1() != 0 && rowData.getTrip2() != 0 && rowData.getTrip3() == 0) {
                rs = conn.createStatement().executeQuery(
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip1() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "union\r\n" + 
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip2() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "order by departure;");
            } else if(rowData.getTrip1() != 0 && rowData.getTrip2() != 0 && rowData.getTrip3() != 0) {
                rs = conn.createStatement().executeQuery(
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip1() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "union\r\n" + 
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip2() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "union\r\n" + 
                        "select trip.tripid, connexion.origin, connexion.destination, trip.departure, trip.arrival, trip.driverpnr, trip.priceamount, trip.seats\r\n" + 
                        "from trip, connexion\r\n" + 
                        "where trip.tripid = " + rowData.getTrip3() + "\r\n" + 
                        "and trip.connexionid = connexion.connexionid\r\n" + 
                        "order by departure;");
            }
            if(rs.next()) {    
                tripData.add(new Trip(rs.getInt(1), rs.getString(2), rs.getString(3), ""+rs.getTimestamp(4), ""+rs.getTimestamp(5), rs.getString(6), ""+rs.getInt(7), ""+rs.getInt(8)));
                while(rs.next()) {
                    tripData.add(new Trip(rs.getInt(1), rs.getString(2), rs.getString(3), ""+rs.getTimestamp(4), ""+rs.getTimestamp(5), rs.getString(6), ""+rs.getInt(7), ""+rs.getInt(8)));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        trips.setItems(tripData);
    }
} 

3 个答案:

答案 0 :(得分:1)

根据评论编辑(感谢@fabian)。

这假设Trip有一个方法Trip.getDriver(),它将驱动程序作为String返回显示。

自定义CellFactory的{​​{1}}:

driverColumn

每次更新单元格时,可能还有其他选项,而不是重新创建按钮,但我希​​望你能得到一般的想法。

您可以使用相同的技术更改项目的显示方式(例如根据值添加样式),添加复选框等控件。

作为单独的说明,我建议您可以考虑将数据库连接代码移出Platform(JavaFX)线程,例如使用//give driverColumn proper types TableColumn<Trip,String> driverColumn; //... driverColumn.setCellValueFactory(new Callback<CellDataFeatures<Trip, String>, ObservableValue<String>>() { public ObservableValue<String> call(CellDataFeatures<Trip, String> p) { // p.getValue() returns the Trip instance for a particular TableView row return new SimpleStringProperty(p.getValue().getDriver()); } }); driverColumn.setCellFactory(param -> new TableCell<Trip,String>{ public void updateItem(String driver, boolean empty) { super.updateItem(driver, empty); //reset any previous values, as cells may be reused setText(null); setGraphic(null); if(empty) { //contingency if cell is empty } else if(driver!=null) { setText(driver); } else { //driver is null Button b = new Button("Choose Driver"); //... hook up button actions, etc setGraphic(b); } } }); 接口。

答案 1 :(得分:0)

为驱动程序列添加CellFactory,并在该创建的单元格中为数据创建不同的内容:

 driverColumn.setCellFactory(this::createDriverCell);

 private TableCell<Trip,String> createDriverCell(TableColumn<Trip, String> table) {
    return new TableCell<Trip, String>() {
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
              // configure empty
            } else if (item == null) {
              // create no driver content
            } else {
              // create different content
            }
        }           
    };
}

答案 2 :(得分:0)

使用cellFactory创建显示不同内容的单元格,具体取决于单元格项目。以下代码假定您的cellValueFactory返回ObservableValue,它还实现了WritableValue,并允许您以这种方式将数据存储在项目中。

为简单起见,以下示例使用StringProperty s表(您未发布Trip类):

@Override
public void start(Stage primaryStage) {
    TableView<StringProperty> table = new TableView<>();

    // fill table
    for (int i = 0; i < 20; i++) {
        table.getItems().add(new SimpleStringProperty());
    }

    TableColumn<StringProperty, String> column = new TableColumn<>();
    column.setCellValueFactory(TableColumn.CellDataFeatures::getValue); // returns the row item itself
    column.setCellFactory(col -> new TableCell<StringProperty, String>() {

        private final Button button;

        {
            button = new Button("Set Value...");
            button.setOnAction(evt -> {
                TextInputDialog dialog = new TextInputDialog();
                Optional<String> opt = dialog.showAndWait();
                String result = opt.orElse(null);
                if (result != null) {
                    ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex());
                    if (ov instanceof WritableValue) {
                        ((WritableValue) ov).setValue(result);
                    }
                }
            });
        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                // empty cell
                setText("");
                setGraphic(null);
            } else {
                if (item == null) {
                    // editable cell
                    setText("");
                    setGraphic(button);
                } else {
                    // uneditable cell
                    setText(item);
                    setGraphic(null);
                }
            }
        }

    });

    table.getColumns().add(column);

    Scene scene = new Scene(table);

    primaryStage.setScene(scene);
    primaryStage.show();
}