多屏幕JavaFX / FXML的java.lang.NullPointerException

时间:2013-11-27 21:51:12

标签: javafx fxml

所以,我正在做一个JavaFX多视图GUI应用程序。

下面是代码,以便您可以参考它,不要通读它以找到错误,我将首先解释下面的问题;)

我有一个主 - 启动应用程序

 public class MyFXMLMain extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Wireframe.fxml"));
        stage.setTitle("My Fitness App");
        Scene mainScene = new Scene(root,805,809);
        stage.setScene(mainScene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

ScreensController - 控制加载/设置屏幕。

public class ScreensController extends StackPane {

private HashMap<String, Node> screens = new HashMap<>(); 

public ScreensController() {
    super();
}

public void addScreen(String name, Node screen) { 
       screens.put(name, screen); 
   } 

public Node getScreen(String name) {
    return screens.get(name);
}

public boolean loadScreen(String name, String resource) {
     try { 
       FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
       Parent loadScreen = (Parent) myLoader.load(); 
       ControlledScreen myScreenController = ((ControlledScreen)                       myLoader.getController());
       myScreenController.setScreenParent(this); 
       addScreen(name, loadScreen); 
       return true; 
     }catch(Exception e) { 
       System.out.println(e.getMessage()); 
       return false; 
     } 
   }

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

   public boolean unloadScreen(String name) {
        if (screens.remove(name) == null) {
            System.out.println("Screen didn't exist");
            return false;
        } else {
            return true;
        }
    }
}

屏幕框架 - 将屏幕链接到FXML文件。

public class ScreensFramework extends Application { 

public static String MAIN_SCREEN = "MyFXMLController"; 
public static String MAIN_SCREEN_FXML = "Wireframe.fxml"; 
public static String calendarScreen = "CalendarscreenController"; 
public static String calendarScreenFXML = "Calendarscreen.fxml"; 
public static String guideScreen = "GuideScreenController"; 
public static String guideScreenFXML ="Guidescreen.fxml"; 

@Override 
public void start(Stage primaryStage) { 

  ScreensController mainContainer = new ScreensController(); 
  mainContainer.loadScreen(ScreensFramework.MAIN_SCREEN, ScreensFramework.MAIN_SCREEN_FXML); 
  mainContainer.loadScreen(ScreensFramework.calendarScreen,ScreensFramework.calendarScreenFXML); 
  mainContainer.loadScreen(ScreensFramework.guideScreen,ScreensFramework.guideScreenFXML); 

  mainContainer.setScreen(ScreensFramework.MAIN_SCREEN); 

  Group root = new Group(); 
  root.getChildren().addAll(mainContainer); 
  Scene scene = new Scene(root); 
  primaryStage.setScene(scene); 
  primaryStage.show(); 
} 
}

FXML控制器 - 链接到FXML文件并告诉FXML点击某些内容时该做什么。

public class MyFXMLController implements ControlledScreen{

@FXML private TextField givenName;
@FXML private Text targetText;
//@FXML private static TableView<Mass> theTable;
//@FXML private static TableColumn<Mass, String> dateCol;
//@FXML private static TableColumn<Mass, String> massCol;
@FXML private static LineChart<Number,Number> weightChart;
@FXML private static NumberAxis axisX;
@FXML private static NumberAxis axisY;
@FXML private static Label myLabel;
//private static User theUser = new User();
private static ScreensController myController;

@Override
public void setScreenParent(ScreensController screenPage) {
    myController = screenPage;
}
@FXML protected void handlePressedCalendarButtonAction(ActionEvent event){
    System.out.println("Hello");
}   
@FXML protected void mouseclickedcal(MouseEvent mec){
    myController.setScreen(ScreensFramework.calendarScreen);
}

}

控制屏幕 - 这样做:

   public interface ControlledScreen {

    public void setScreenParent(ScreensController screenPage);

    }

CalendarScreenController - 控制其中一个多屏幕

   public class CalendarScreenController implements Initializable, ControlledScreen {

    ScreensController myController; 

     @Override
     public void initialize(URL url, ResourceBundle rb) { 

         } 

     public void setScreenParent(ScreensController screenParent){ 
        myController = screenParent; 
     } 

     @FXML 
     private void goToMain(ActionEvent event){ 
       myController.setScreen(ScreensFramework.MAIN_SCREEN); 
     } 

    } 

以下问题

当我运行我的程序时它工作正常,但如果我点击一个按钮激活日历onclick代码:

  @FXML protected void mouseclickedcal(MouseEvent mec){
        myController.setScreen(ScreensFramework.calendarScreen);
    }

应将屏幕设置为CalendarScreen.fxml,我的多屏幕之一,但它会导致以下错误:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(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.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$ClickGenerator.postProcess(Unknown Source)
    at javafx.scene.Scene$ClickGenerator.access$8600(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access$1900(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.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.access$100(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    ... 31 more
Caused by: java.lang.NullPointerException
    at myfxml.MyFXMLController.mouseclickedcal(MyFXMLController.java:125)
    ... 40 more

第125行是代码:

@FXML protected void mouseclickedcal(MouseEvent mec){
    myController.setScreen(ScreensFramework.calendarScreen);
    }

非常感谢你看看这个。我似乎无法找到错误;(

1 个答案:

答案 0 :(得分:-1)

原来我有2个主电源并且它们是冲突的,而且在我的xml代码中,我正在调用其控制器中不存在的东西。