Sunday, 18 August 2013

NPE in switching screens

NPE in switching screens

I want to implement managing multiple screens from this example
I cut most of the code and I managed to create this code:
Controller class
public interface ControlledScreen {
//This method will allow the injection of the Parent ScreenPane
public void setScreenParent(ScreensController screenPage);
}
Screens controller
import java.util.HashMap;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;
public class ScreensController extends StackPane {
//Holds the screens to be displayed
private HashMap<String, Node> screens = new HashMap<>();
public ScreensController() {
super();
}
//Add the screen to the collection
public void addScreen(String name, Node screen) {
screens.put(name, screen);
}
//Returns the Node with the appropriate name
public Node getScreen(String name) {
return screens.get(name);
}
//This method tries to displayed the screen with a predefined name.
//First it makes sure the screen has been already loaded. Then if
there is more than
//one screen the new screen is been added second, and then the current
screen is removed.
// If there isn't any screen being displayed, the new screen is just
added to the root.
public boolean setScreen(final String name) {
if (screens.get(name) != null) { //screen loaded
final DoubleProperty opacity = opacityProperty();
if (!getChildren().isEmpty()) { //if there is more than one
screen
Timeline fade = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity,
1.0)),
new KeyFrame(new Duration(1000), new
EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
getChildren().remove(0);
//remove the displayed screen
getChildren().add(0, screens.get(name)); //add
the screen
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new
KeyValue(opacity, 0.0)),
new KeyFrame(new Duration(800), new
KeyValue(opacity, 1.0)));
fadeIn.play();
}
}, new KeyValue(opacity, 0.0)));
fade.play();
} else {
setOpacity(0.0);
getChildren().add(screens.get(name)); //no one else
been displayed, then just show
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity,
0.0)),
new KeyFrame(new Duration(2500), new
KeyValue(opacity, 1.0)));
fadeIn.play();
}
return true;
} else {
System.out.println("screen hasn't been loaded!!! \n");
return false;
}
/*Node screenToRemove;
if(screens.get(name) != null){ //screen loaded
if(!getChildren().isEmpty()){ //if there is more than one screen
getChildren().add(0, screens.get(name)); //add the screen
screenToRemove = getChildren().get(1);
getChildren().remove(1); //remove the
displayed screen
}else{
getChildren().add(screens.get(name)); //no one else been
displayed, then just show
}
return true;
}else {
System.out.println("screen hasn't been loaded!!! \n");
return false;
}*/
}
//This method will remove the screen with the given name from the
collection of screens
public boolean unloadScreen(String name) {
if (screens.remove(name) == null) {
System.out.println("Screen didn't exist");
return false;
} else {
return true;
}
}
}
My implementation:
public class DX57DC extends Application implements ControlledScreen{
public static ScreensController myController;
public static String screen1ID = "main";
public static String screen2ID = "second";
public static ScreensController mainContainer;
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public static ScreensController screenParent;
@Override
public void setScreenParent(ScreensController screenParent){
DX57DC.myController = screenParent;
}
@Override
public void start(Stage primaryStage)
{
mainContainer = new ScreensController();
final Rectangle rect = new Rectangle(300, 300);
rect.setFill(Color.SILVER);
final Rectangle rezct = new Rectangle(300, 300);
rezct.setFill(Color.AZURE);
//mainContainer.addScreen(DX57DC.screen1ID, root);
mainContainer.addScreen(DX57DC.screen1ID, rect);
mainContainer.addScreen(DX57DC.screen2ID, rezct);
mainContainer.setScreen(DX57DC.screen2ID);
// BorderPane as button
bpi.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
myController.setScreen(DX57DC.screen1ID);
}
});
}
As you can see I removed the fxml stuff from the original example. In my
simple implementation I want only to switch rectangles in order to make it
work. I get NPE error when I run the example and switch the second screen
at this line:
myController.setScreen(DX57DC.screen2ID);
Can you tell me where I'm wrong?

No comments:

Post a Comment