Array mit JavaFX Elementen

Hallo,
ich versuche ein Array mit TextArea's zu machen aber bekomme immer eine Nullpointer Exception, vielleicht kann mir das jemand erklären..

Java:
@FXML private TextArea outputArea1;
@FXML private TextArea outputArea2;
@FXML private TextArea outputArea3;
@FXML private TextArea outputArea4;
private TextArea areaArray [] = {outputArea1, outputArea2, outputArea3, outputArea4};

if (t1 == "1x"){
    outputArea2.setText("Sie benötigen es 1x täglich.");
}
else if (t1 == "2x"){
    areaArray[1].setText("Sie benötigen es 2x täglich."); <- Zeile 70
}

wenn ich es wie in Variante 1 mache klappt es ohne Probleme, wenn ich es jetzt über das Array laufen lassen möchte wirft er mir folgende Exception:

Code:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at consultant/sample.Controller$1.changed(Controller.java:70)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
    at javafx.base/javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
    at javafx.base/javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
    at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113)
    at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
    at javafx.controls/javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:105)
    at javafx.controls/javafx.scene.control.SingleSelectionModel.updateSelectedIndex(SingleSelectionModel.java:223)
    at javafx.controls/javafx.scene.control.SingleSelectionModel.select(SingleSelectionModel.java:149)
    at javafx.controls/javafx.scene.control.ChoiceBox$ChoiceBoxSelectionModel.select(ChoiceBox.java:579)
    at javafx.controls/javafx.scene.control.skin.ChoiceBoxSkin.lambda$addPopupItem$7(ChoiceBoxSkin.java:383)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.controls/javafx.scene.control.MenuItem.fire(MenuItem.java:465)
    at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1380)
    at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1333)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3851)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1200(Scene.java:3579)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.mac.MacView.notifyMouse(MacView.java:127)

Danke für eure Hilfe.
Mit freundlichen Grüßen
Nico
 
Zuletzt bearbeitet von einem Moderator:
Initialisiere dein areaArray erst in der Initialize-Methode. Erst dort sind die FX-Komponenten initialisiert.
Java:
class Controller {
    @FXML private TextArea outputArea1;
    @FXML private TextArea outputArea2;
     ..
     private TextArea[] areaArrray;

    @FXML
    public void initialize() {
        areaArray = new TextArea[]{ outputArea1, outputArea2};
    }
}
 
Kleiner Verbesserungsvorschlag:

Java:
int amountOfAreas = 10;
ArrayList<TextArea> areas = new ArrayList<>();

for(int i = 0; i < amountOfAreas; i++){
    areas.add(new TextArea());
}

//...

TextArea a = areas.get(0);
if(someCondition == true){
    a.setText("Sie brauchen es mal wieder...");
}
 
Eigentlich wollte ich ihn auch auf die Verwendung von ArrayList anstelle von Object[] hinweisen. Dann muß er mit den Indizees nicht ganz so viel herumfummeln.

Aber ja, das mit der For-Schleife geht natürlich nicht. Blöd von mir.
 
Was gehen würde (ungetestet) wäre mit fx:define zu arbeiten
XML:
<TextArea fx:id="area1" />
<TextArea fx:id="area2" />
<TextArea fx:id="area3" />
...

<fx:define>
    <ArrayList  fx:id="areas">
         <fx:reference source="area1"/>
         <fx:reference source="area2"/>
         <fx:reference source="area3"/>
         ...
    </ArrayList>
</fx:define>
Und im Controller dann die ArrayList zu referenzieren
Java:
class Controller {
    @FXML private List<TextArea> areas;
}
Aber das würde ich wahrscheinlich eher nicht machen 😛
 
Was gehen würde (ungetestet) wäre mit fx:define zu arbeiten
XML:
<TextArea fx:id="area1" />
<TextArea fx:id="area2" />
<TextArea fx:id="area3" />
...

<fx:define>
    <ArrayList  fx:id="areas">
         <fx:reference source="area1"/>
         <fx:reference source="area2"/>
         <fx:reference source="area3"/>
         ...
    </ArrayList>
</fx:define>
Und im Controller dann die ArrayList zu referenzieren
Java:
class Controller {
    @FXML private List<TextArea> areas;
}
Aber das würde ich wahrscheinlich eher nicht machen 😛

Warum würdest du es nicht machen? An sich ist es doch nicht schlecht, wenn es klappt. Aber wenn man ein TextArea löscht muss man an der Stelle auch nachpflegen oder umbennen.

Theoretisch könnte man auch über node#lookup(id) die Textfelder holen und in eine Liste packen.
 

Zurück
Oben