Reputation: 6339
I have a javafx design in the file javafx.fxml where the root element has the following attribute
fx:controller="de.roth.jsona.javafx.ViewManagerFX"
This controller class has a singleton machanism and is binded with some ui-elements.
public class ViewManagerFX {
private static ViewManagerFX instance = new ViewManagerFX();
@FXML
private Slider volumeSlider;
@FXML
private Label volumeLabel;
public IntegerProperty volumeValue = new SimpleIntegerProperty();
@FXML
private TabPane musicTabs;
public List<StringProperty> tabNames = new ArrayList<StringProperty>();
public static ViewManagerFX getInstance() {
return (instance);
}
public void initialize() {
// Volume
volumeSlider.valueProperty().bindBidirectional(volumeValue);
volumeLabel.textProperty().bindBidirectional(volumeValue, new Format() {
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
toAppendTo.append(obj);
toAppendTo.append("%");
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
return null; // no need to be implemented
}
});
volumeValue.set(Config.getInstance().VOLUME);
}
public void addMusicFolderTab(final String t, final ArrayList<MusicListItem> items) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Tab m = new Tab("Test Tab");
musicTabs.getTabs().add(0, m);
}
});
}
}
The method addMusicFolderTab
is called from a thread
that is used to scan files and directories.
In the initialize method I can access the ui-elements but in the method addMusicFolderTab
, that is called from the filescanner-thread, the variable musicTabs
is null
. Here is the exception:
java.lang.NullPointerException
at de.roth.jsona.javafx.ViewManagerFX$3.run(ViewManagerFX.java:110)
I have no clue, why I can't access the TabPane from outside the initialize method.
Upvotes: 1
Views: 1569
Reputation: 4602
Aside from the many questionable patterns used here, the problem is that your ViewManagerFX
singleton (besides not being a singleton) never has its instance set.
When using FXML, the Controller is created and loaded dynamically by Reflection from the FXMLoader
.
What happens is that by calling ViewManagerFX.getInstance()
, you access the a different controller than the one created by the FXMLoader
. The instance you access is the one created here:
private static ViewManagerFX instance = new ViewManagerFX();
The quickest way to solve the issue is to set the instance in the initialize()
since it's called by the FXMLoader
on the instance created by the FXMLoader
.
public void initialize() {
instance = this;
// Volume
...
}
Upvotes: 6