1

一切正常,但后来我添加了泛型,现在这个 ClassCastException 不断弹出,我不知道为什么。

****重要****
所以我也尝试将其删除,但这里又出现了另一个问题。打印到牵引力控制列之前的所有值。在此之后,所有值都不会显示事件,尽管除了其中一些的数据类型之外,一切都是完全相同的。

错误

原因:java.lang.ClassCastException:app.westminster.car.rentalSystem.Car 无法在 app.westminster.car.rentalSystem.GUI.MainGUI.lambda$start$5(MainGUI .java:139) 在 javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:578) 在 javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:563) 在 javafx.scene.control.TableCell.updateItem( TableCell.java:644) 在 javafx.scene.control.TableCell.indexChanged(TableCell.java:468) 在 javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116) 在 com.sun.javafx.scene.control .skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:533) 在 com.sun.javafx.scene.control.skin.TableRowSkinBase.init(TableRowSkinBase.java:147) 在 com.sun.javafx.scene.control.skin。TableRowSkin.(TableRowSkin.java:64) 在 javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:212) 在 javafx.scene.control.impl_processCSS(Control.java:872) 在 javafx.scene.Node。 processCSS(Node.java:9056) at javafx.scene.Node.applyCss(Node.java:9153) at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1964) at com.sun .javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1797) 在 com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength(VirtualFlow.java:1879) 在 com.sun.javafx.scene .control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2528) at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1189) at javafx.scene.Parent.layout(Parent.java :1087) 在 javafx.scene.Parent.layout(Parent.java:1093) at javafx.scene.Parent.layout(Parent.java:1093) at javafx.scene.Scene.doLayoutPass(Scene.java:552) at javafx.scene.Scene.preferredSize(Scene.java:1646) at javafx。在 javafx.beans 的 javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109) 的 javafx.stage.Window$9.invalidated(Window.java:864) 的 scene.Scene.impl_preferredSize(Scene.java:1720)。 property.BooleanPropertyBase.set(BooleanPropertyBase.java:144) at javafx.stage.Window.setShowing(Window.java:940) at javafx.stage.Window.show(Window.java:955) at javafx.stage.Stage.show (Stage.java:259) 在 app.westminster.car.rentalSystem.GUI.MainGUI.start(MainGUI.java:154) 在 com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)在 com.sun.javafx.application.PlatformImpl。lambda$runAndWait$174(PlatformImpl.java:326) 在 com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295) 在 java.security.AccessController.doPrivileged(Native Method) 在 com.sun。 javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294) 在 com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 在 com.sun.glass.ui.win.WinApplication ._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177) ... 还有 1 个InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication. java:177) ... 还有 1 个InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication. java:177) ... 还有 1 个

图形用户界面类

public class MainGUI extends Application {

private static Stage stage;

@Override
public void start(Stage primaryStage) throws Exception {

    stage = primaryStage;
    Platform.setImplicitExit(false);

    stage.setTitle("Westminster Rentals");
    VBox mainLayout = new VBox();

    Scene scene = new Scene(mainLayout, 1655,800);

    Label heading1 = new Label("Welcome to Westminster Rentals");
    heading1.setStyle("-fx-font-size: 32px; -fx-font-family: -apple-system, sans-serif;");
    heading1.setPadding(new Insets(20,20,20,20));


    //_____________________Search Tab__________________________________//

    // search Tab will hold search bar, search button and rent button

    HBox searchTab = new HBox();
    searchTab.setStyle("-fx-spacing: 10px; -fx-padding: 20px");

    JFXButton searchButton = new JFXButton("Search");
    searchButton.setAlignment(Pos.CENTER);
    searchButton.setStyle("-fx-padding: 20px;-fx-background-color: #6143d5; -fx-text-fill: #fff;");

    JFXTextField searchBar = new JFXTextField();
    searchBar.setPrefWidth(500);
    searchBar.setStyle("-fx-padding: 20px;");
    searchBar.promptTextProperty().setValue("Search....");

    HBox rentTab = new HBox();
    JFXButton rent = new JFXButton("Rent a car");
    rent.setOnAction(e->{
        RentGUI.showRentPage();
    });
    rent.setStyle("-fx-padding: 20px;-fx-background-color: #1ad541; -fx-text-fill: #fff;");


    rentTab.getChildren().add(rent);
    searchTab.getChildren().addAll(searchBar,searchButton, rentTab);

    //_____________________Search Tab --END--_____________________________//


    //Main Heading will hold a vertical alignment for heading1 and the searchTab Hbox to create embedded layout
    VBox mainHeading =  new VBox();
    mainHeading.getChildren().addAll(heading1,searchTab);

    //Table view and Table columns are used to build the table attribute of the app
    // This needs to be done as below unless FXML is used to build the application
    TableView<Vehicle> tableView = new TableView<>();
    tableView.setEditable(false);

    TableColumn<Vehicle, String> makeColumn = new TableColumn<>("Make");
    makeColumn.setPrefWidth(150);
    makeColumn.setCellValueFactory(data->  new SimpleStringProperty(data.getValue().getMake()));

    TableColumn<Vehicle,String> modelColumn = new TableColumn<>("Model");
    modelColumn.setPrefWidth(200);
    modelColumn.setCellValueFactory(new PropertyValueFactory<>("model"));

    TableColumn<Vehicle,String> plateNumColumn = new TableColumn<>("Plate Number");
    plateNumColumn.setPrefWidth(200);
    plateNumColumn.setCellValueFactory(new PropertyValueFactory<>("plateNumber"));

    TableColumn<Vehicle,String> fuelTypeColumn = new TableColumn<>("Fuel Type");
    fuelTypeColumn.setPrefWidth(200);
    fuelTypeColumn.setCellValueFactory(new PropertyValueFactory<>("fuelType"));

    TableColumn<Vehicle, BigDecimal> priceColumn = new TableColumn<>("Price Per Hour (USD)");
    priceColumn.setPrefWidth(200);
    priceColumn.setCellValueFactory(new PropertyValueFactory<>("pricePerHour"));

    TableColumn<Vehicle,String> transmissionColumn = new TableColumn<>("Transmission");
    transmissionColumn.setPrefWidth(200);
    transmissionColumn.setCellValueFactory(new PropertyValueFactory<>("transmission"));

    TableColumn carColumn = new TableColumn("Car");
    carColumn.setPrefWidth(200);
    carColumn.setCellValueFactory(new PropertyValueFactory("car"));

    TableColumn<Car,Boolean> tractionControlColumn = new TableColumn<>("Traction Control?");
    tractionControlColumn.setPrefWidth(200);
    tractionControlColumn.setCellValueFactory(new PropertyValueFactory<>("tractionControl"));

    TableColumn<Car,Boolean> appleCarPlayColumn = new TableColumn<>("Apple Car Play?");
    appleCarPlayColumn.setPrefWidth(200);
    appleCarPlayColumn.setCellValueFactory(data-> new SimpleBooleanProperty(data.getValue().hasAppleCarPlay()));

    TableColumn <Car,String>parkingAssistanceColumn = new TableColumn<>("Parking Assistance?");
    parkingAssistanceColumn.setPrefWidth(200);
    parkingAssistanceColumn.setCellValueFactory(data-> new SimpleStringProperty(String.valueOf(data.getValue().hasParkingAssistant())));

    TableColumn<Car,String> blindSpotAwarenessColumn = new TableColumn<>("Blind spot awareness?");
    blindSpotAwarenessColumn.setPrefWidth(200);
    blindSpotAwarenessColumn.setCellValueFactory(data-> new SimpleStringProperty(String.valueOf(data.getValue().hasBlindSpotAwareness())));

    TableColumn bikeColumn = new TableColumn("Motorbikes");
    bikeColumn.setPrefWidth(200);
    bikeColumn.setCellValueFactory(new PropertyValueFactory("motorbike"));

    TableColumn<Motorbike, Boolean> basketColumn = new TableColumn<>("Basket?");
    basketColumn.setPrefWidth(200);
    basketColumn.setCellValueFactory(data-> new SimpleBooleanProperty(data.getValue().hasBasket()));

    TableColumn<Motorbike, Boolean> gyroColumn = new TableColumn<>("Gyroscopic Balance?");
    gyroColumn.setPrefWidth(200);
    gyroColumn.setCellValueFactory(data-> new SimpleBooleanProperty(data.getValue().hasGyroscopicBalance()));


    carColumn.getColumns().addAll(tractionControlColumn,appleCarPlayColumn,parkingAssistanceColumn,blindSpotAwarenessColumn);
    bikeColumn.getColumns().addAll(basketColumn,gyroColumn);
    tableView.getColumns().addAll(makeColumn,modelColumn,plateNumColumn,fuelTypeColumn,priceColumn,transmissionColumn,carColumn,bikeColumn);

    mainLayout.getChildren().addAll(mainHeading, tableView);
    tableView.setItems(addTableItems());

    stage.setScene(scene);
    stage.show();

}


//addTableItems will create an observable list required to enter values into the table.

private ObservableList<Vehicle> addTableItems() throws UnknownHostException {
    ObservableList<Vehicle> musicItem = FXCollections.observableArrayList();
    for (Vehicle item: Database.getDatastore().find(Vehicle.class).asList()){
        musicItem.addAll(item);
    }
    return musicItem;
}

public static void main(){
    launch();
}

public static void showStage(){
    stage.show();
}
}

带有 Main 方法的主类

public class Main extends Thread{

private static Scanner scanner = new Scanner(System.in);
private static Stage stage;

public static void main(String[] args) {
    int userResponse;
    RentalVehicleManager rentalVehicleManager = new WestminsterRentalVehicleManager();
    Thread guiControlThread = new Thread(MainGUI::main);
    guiControlThread.start();
}

}

假设我删除了 lambdas 并放入了新的 PropertyValueFactory。然后错误消失,GUI工作

牵引力控制后的值不显示

结果

4

1 回答 1

2

TableView( Vehicle) 的类型参数与您用于某些列的第一个类型参数之间存在差异。这 2 个类型参数应该匹配。否则可能会发生这样的事情。

因为Vehicleis 编译器的类型参数TableView允许您将所有可分配的内容添加Vehicle到.itemsTableView

声明basketColumnTableColumn<Motorbike, Boolean> basketColumn“告诉”编译器表中的所有项目都是Motorbikes。出于这个原因,以下代码片段将在编译后的代码中产生相同的结果:

TableColumn basketColumn = new TableColumn("Basket?"); // note the use of the raw type here
basketColumn.setPrefWidth(200);

// note the hidden cast inserted here by the compiler based on the type parameter in the declaration
// this is the cause of the ClassCastException
basketColumn.setCellValueFactory(data -> new SimpleBooleanProperty(((Motorbike) data.getValue()).hasBasket()));

由于要将Cars 和Motorbikes 都放入 中TableView,因此需要根据cellValueFactorys 中的实际类型返回结果:

TableColumn<Vehicle, Boolean> basketColumn = new TableColumn<>("Basket?");
basketColumn.setPrefWidth(200);
basketColumn.setCellValueFactory(data -> {
    Vehicle item = data.getValue();
    if (item instanceof Motorbike) {
        return new SimpleBooleanProperty(((Motorbike) item).hasBasket());
    } else {
        return null; // put something else here, if you don't want empty cells for non Motorbikes
    }
});

您的代码中还有多个其他地方需要进行类似的更改。

于 2019-11-17T08:35:02.270 回答