2016-01-16 1 views
1

У меня есть ArrayList из javafx.scene.control.Control (ArrayList) с двумя разными подклассами управления (ComboBox, текстовое поле).ComboBox нельзя отбрасывать в TextField?

Так что я хочу обновить список с помощью нового ввода (example) в обоих из них.

Но когда я пытаюсь это, затмение делает ошибки, как это:

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; 
    } 
} 

EDIT: я мог бы попробовать его с двумя разделенным списками. Один для Combobox и один для Textfield.

EDIT 2: Он работает с двумя арраистами! :))

ответ

1

Если сравнить, как добавляется содержимое entries списка и как вы используете его в aktualisiereListe вы должны быть в состоянии увидеть проблему:

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

Это означает, что существует подпоследовательность 3 TextField s. Кроме того, первый элемент выпадающего

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 TextField с будут выдавать ошибку, так как 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; 
      ... 
     } 
    } 

Однако вы можете просто сохранить список, который всегда в курсе, регистрируя изменения слушателей к 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 всегда содержит самые последние значения, а также предотвращает ненужное воссоздание списков. Не нужно передавать список элементов управления методу и различать типы управления ...

+0

Спасибо. Я не знал, что есть метод InstanceOf, это намного проще! : D – Ceeya

1

Существует ComboBox в позиции (i% 3 == 2 || i% 3 == 0), которые соответствуют этому условию, поэтому литье ComboBox в TextField ((TextField) list.get (i)) вызывает ошибку.

+0

Jep, вы правы. Я решил это с двумя отдельными арраистами. – Ceeya