1

我有一个 javafx.scene.control.Control (ArrayList) 的 ArrayList,它有两个不同的 Control 下类(ComboBox,Textfield)。

所以我想用他们两个中的新输入(示例)更新列表。

但是当我尝试它时,eclipse会出现这样的错误:

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.control.ComboBox cannot be cast to javafx.scene.control.TextField
    at application.DocumentBuildUp.aktualisiereListe(DocumentBuildUp.java:34)
    at application.MainStage$2.handle(MainStage.java:99)
    at application.MainStage$2.handle(MainStage.java:1)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Node.fireEvent(Unknown Source)
    at javafx.scene.control.Button.fire(Unknown Source)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source)
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyMouse(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

我希望你能帮忙。

这是代码。DokumentBuilUp 类有 updateList 的方法。我将其命名为“aktualisiereListe”。:))

MainStage 类:

public class MainStage extends Application {

    /**
     * Globale Variablen
     */
     private int abstandszaehler = 0;
     private ScrollPane rahmen = new ScrollPane();
     private XMLActions xA = new XMLActions();
     private Pane partPane = new Pane();
     private Group huelle = new Group();
     private int iD = 0;
     private List<Control> entries = new ArrayList<Control>();
     private DocumentBuildUp dBU = new DocumentBuildUp(entries);



     /**
     * The main class for a JavaFX application extends the javafx.application.Application class. 
     * The start() method is the main entry point for all JavaFX applications.
     */
    public static void main(String[] args) {
        launch(args);
    }


    @Override
    public void start(Stage primaryStage) {
        //Policy bezüglich Scrollingverhalten
        rahmen.setHbarPolicy(ScrollBarPolicy.ALWAYS);
        rahmen.setVbarPolicy(ScrollBarPolicy.ALWAYS);

        //Fenster konfigurieren und anzeigen
        primaryStage.setTitle("XML-Zeilenersteller");
        primaryStage.setResizable(false);


        //Erzeugt notwendige Elemente im GUI
         erzeugeEinzelneElemente();

        partPane.setStyle("-fx-background-color: lightsteelblue");
        huelle.getChildren().addAll(partPane);
        rahmen.setContent(huelle);
        Scene mainScene = new Scene(rahmen, 900, 590);
        primaryStage.setScene(mainScene);
        primaryStage.show();
    }







    /**
     * HauptElemente für die Root
     */
    public void erzeugeEinzelneElemente(){
        //Buttons
        Button newXMLLine = new Button();
        newXMLLine.setText("Einfügen neuer XML-Zeile");
        newXMLLine.setLayoutX(735);
        newXMLLine.setLayoutY(80);
        newXMLLine.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                setEverythingInALine();
            }
        });

        Button newXMLDocument = new Button();
        newXMLDocument.setText("Erstelle XML-Dokument");
        newXMLDocument.setLayoutX(735);
        newXMLDocument.setLayoutY(550);
        newXMLDocument.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {


                dBU.aktualisiereListe(entries);

                System.out.println("Test2");
            }
        });

        //Überschrift
        Text header = new Text(105, 50, "XML Lines Creator");
        header.setFont(new Font(30)); header.setStyle("-fx-underline: true;");

        /**
         * Hinzufügen zur GUI
         */
        partPane.getChildren().addAll(newXMLDocument,newXMLLine,header);
    }






    /**
     * Methode zur Erstellungen der Zeilen an Comboboxen, Textfelder
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void setEverythingInALine(){
        //Comboboxen
        ComboBox cB = new ComboBox(xA.getList());   
        partPane.getChildren().add(cB);
        cB.setLayoutX(80);
        cB.setLayoutY(80 + abstandszaehler);
        entries.add(cB);
        iD++;
//        cB.setId(Integer.toString(iD));

        //Textfield
        TextField tFID= new TextField ("ID");
        partPane.getChildren().add(tFID);
        tFID.setLayoutX(185);
        tFID.setLayoutY(80 + abstandszaehler);
        entries.add(tFID);



        TextField tFName= new TextField ("Name");
        partPane.getChildren().add(tFName);
        tFName.setLayoutX(340);
        tFName.setLayoutY(80 + abstandszaehler);
        entries.add(tFName);


        TextField tFWert= new TextField ("Wert");
        partPane.getChildren().add(tFWert);
        tFWert.setLayoutX(495);
        tFWert.setLayoutY(80 + abstandszaehler);
        entries.add(tFWert);


        System.out.println(Integer.toString(iD));

        //Zaehler für den Abstand
        abstandszaehler = abstandszaehler + 30;

        System.out.println(entries);
    }
}

类 DocumentBuilUp:

public class DocumentBuildUp{

    @SuppressWarnings("unused")
    private List<Control> list;

    public DocumentBuildUp(List<Control> list){
        this.list = list;
    }

    public List<String> aktualisiereListe(List<Control> list ){

        List<String> stringEntries = new ArrayList<String>();

        for(int i=0; i<=list.size()-1; i++){

            //Brauche die Zahl beim Anklicken der Zeile Listener?   
            if(i%3 == 1){
                ComboBox cB = (ComboBox) list.get(i);
                stringEntries.add((String) cB.getValue()); 
            }

            if(i%3 == 2 || i%3 == 0){
                TextField tF = (TextField) list.get(i);
                stringEntries.add(tF.getText());
            }
        }
        System.out.println(stringEntries);

        return stringEntries;
    }
}

编辑:我可以尝试使用两个单独的列表。一个用于组合框,一个用于文本字段。

编辑 2:它与两个 Arraylist 一起工作!:))

4

2 回答 2

1

如果您比较entries列表内容的添加方式和使用方式,aktualisiereListe您应该能够看到问题:

public void setEverythingInALine(){
    ...
    entries.add(someCombobox);
    ...
    entries.add(someTextfield);
    ...
    entries.add(someTextfield2);
    ...
    entries.add(someTextfield3);
}

这意味着有一个 3TextField秒的子序列。第一个元素也是一个组合框

public List<String> aktualisiereListe(List<Control> list ){
    ...
    for(int i=0; i<=list.size()-1; i++){
        if(i%3 == 1){
            ComboBox cB = (ComboBox) list.get(i);
            ...
        }

        if(i%3 == 2 || i%3 == 0){
            TextField tF = (TextField) list.get(i);
            ...
        }
    }
    ...
}

在这里,您假设第一个元素(索引 0)是TextField( 0 % 3 = 0),但事实并非如此。3 TextFields 的子序列也会产生错误,因为 3 个连续索引将产生所有 3 个不同的模 3 值:

 1 % 3 = 1
 2 % 3 = 2
 3 % 3 = 0

这会导致另一个ClassCastException.

我会考虑将元素添加到列表中并以这种方式检索它们是一种不好的做法,因为您无法在不破坏其他元素的情况下更改元素的顺序(当然可以,但有非常严格的限制)aktualisiereListe。更好的方法是使用instanceof检查元素类型:

    for(Control c : list) {
        if(c instanceof ComboBox){
            ComboBox cB = (ComboBox) c;
            ...
        } else {
            TextField tF = (TextField) c;
            ...
        }
    }

但是,您可以通过向 s 注册更改侦听器来简单地保持一个始终是最新的列表Control,这是我更喜欢的:

public class ListModifyingChangeListener implements ChangeListener<String> {
    private final int index;
    private final List<String> list;

    public ListModifyingChangeListener(int index, List<String> list) {
        this.index = index;
        this.list = list;
    }

    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        list.set(index, newValue);
    }

}
    List<String> liste; // this could be declared a field

    ComboBox<String> cB = ...
    ...

    // create fixed sized list with initial values
    liste = Arrays.asList(cB.getValue(), tFID.getText(), tFName.getText(), tFWert.getText());

    // register listeners that modify a certain element of liste on change
    cB.valueProperty().addListener(new ListModifyingChangeListener(0, liste));
    tFID.textProperty().addListener(new ListModifyingChangeListener(1, liste));
    tFName.textProperty().addListener(new ListModifyingChangeListener(2, liste));
    tFWert.textProperty().addListener(new ListModifyingChangeListener(3, liste));

这确保liste始终包含最新的值,并防止不必要的列表重新创建。无需将控件列表传递给方法并区分控件类型...

于 2016-01-16T11:31:01.277 回答
1

(i%3 == 2 || i%3 == 0) 的位置有 ComboBox 满足此条件,因此将 ComboBox 转换为 TextField ( (TextField) list.get(i) ) 面临错误。

于 2016-01-16T11:36:34.720 回答