从一个TextArea(在一个.fxml中)读取并写入另一个TextArea(在另一个.fxml中)。不是嵌套控制器

时间:2014-01-04 10:54:21

标签: java nullpointerexception javafx-2

我将逐步解释这个问题:

我正在尝试从TextArea(在First.fxml中)读取文本,然后将相同的文本写入另一个TextArea(在Second.fxml中)。两个.fxml文件未嵌套。

  1. First.fxml有一个名为“textArea1”的TextArea和一个名为“openStage2”的按钮。
  2. “openStage2”按钮将Second.fxml加载到舞台中并显示它。
  3. Second.fxml有一个名为“textArea2”的TextArea,以及一个名为“showText”的按钮。
  4. 我想,“showText”按钮应该从“textArea2”复制文本(无论我写什么)并在“textArea1”中显示它。但我得到NullPointerException(如下所示),我想这意味着目标“textField1”没有初始化。即使已经加载了“textField1”(或First.fxml)。我希望了解为什么会这样。我感谢您的努力。谢谢!

    First.java(此类加载主fxml文件)

    public class First extends Application {
        @Override
        public void start(Stage stage) throws Exception {
            Parent root = FXMLLoader.load(getClass().getResource("First.fxml"));
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();
        }
        public static void main(String[] args) {launch(args);}
    } 
    

    FirstController.java

    public class FirstController implements Initializable {
        private Stage Stage2;
        public TextArea getTextArea1(){
            return textArea1;
        }
    
        @FXML
        private Button openStage2;
        @FXML
        private TextArea textArea1;
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {}    
    
        @FXML
        private void openStage2Action(ActionEvent event) throws IOException {
            Stage2 = new Stage();
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Second.fxml"));
            Object root = fxmlLoader.load();
            Scene scene = new Scene((Parent) root);
            Stage2.setScene(scene);
            SecondController secondController = (SecondController)fxmlLoader.getController();
            secondController.setStage2(Stage2); 
            Stage2.showAndWait(); // Stack Trace: at first.FirstController.openStage2Action(FirstController.java:55)
        }
    
    }
    

    SecondController.java

    public class SecondController implements Initializable {
        private Stage stage2;
        private FirstController firstControllerClass;
    //    private First firstClass;
    
        @FXML
        private TextArea textArea2;
        @FXML
        private Button showText;
    
    
        public void setStage2(Stage stage2){
            this.stage2 = stage2;
        }
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            // TODO
        }    
    
        @FXML
        private void showTextAction(ActionEvent event) {
            System.out.println(textArea2.getText()); // this line prints whatever text is typed in textArea2 
            firstControllerClass.getTextArea1().appendText(textArea2.getText()); // this line gives this Exception in Stack Trace: at first.SecondController.showTextAction(SecondController.java:46) 
    
            //I have also tried to access the TextArea1 by setting up a FXMLLoader and its controller, like this:
    //        FirstController firstController = (FirstController)firstClass.getFxmlLoader().getController();
    //        firstController.getTextArea1().appendText("\n"+textArea2.getText());
    
        }
    
    }
    

    堆栈追踪:

    Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1449)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
        at javafx.event.Event.fireEvent(Event.java:171)
        at javafx.scene.Node.fireEvent(Node.java:6867)
        at javafx.scene.control.Button.fire(Button.java:179)
        at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
        at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
        at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
        at javafx.event.Event.fireEvent(Event.java:171)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3311)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3151)
        at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3106)
        at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2248)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:530)
        at com.sun.glass.ui.View.notifyMouse(View.java:924)
        at com.sun.glass.ui.gtk.GtkApplication.enterNestedEventLoopImpl(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication._enterNestedEventLoop(GtkApplication.java:144)
        at com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:384)
        at com.sun.glass.ui.EventLoop.enter(EventLoop.java:83)
        at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:523)
        at javafx.stage.Stage.showAndWait(Stage.java:397)
        at first.FirstController.openStage2Action(FirstController.java:55)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
        at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1444)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
        at javafx.event.Event.fireEvent(Event.java:171)
        at javafx.scene.Node.fireEvent(Node.java:6867)
        at javafx.scene.control.Button.fire(Button.java:179)
        at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
        at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
        at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
        at javafx.event.Event.fireEvent(Event.java:171)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3311)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3151)
        at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3106)
        at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2248)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:530)
        at com.sun.glass.ui.View.notifyMouse(View.java:924)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:89)
        at java.lang.Thread.run(Thread.java:744)
    Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
        at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1444)
        ... 101 more
    Caused by: java.lang.NullPointerException
        at first.SecondController.showTextAction(SecondController.java:46)
        ... 111 more
    

1 个答案:

答案 0 :(得分:0)

不要在控制器中公开UI组件;必要时公开数据。换句话说,从FirstController中删除getTextArea()方法,并在SecondController中执行以下操作:

public class SecondController {
  private StringProperty text  = new SimpleStringProperty(this, "text", "");;
  @FXML
  private TextArea textArea2 ;
  public StringProperty textProperty() {
    return text ;
  }
  public final String getText() {
    return text.get();
  }
  public final void setText(String text) {
    this.text.set(text);
  }

  // ...

  @FXML 
  private void showTextAction(ActionEvent event) {
    text.set(textArea2.getText());
  }
}  

现在在FirstController中只需观察textProperty:

public class FirstController {

  // ...

    @FXML
    private void openStage2Action(ActionEvent event) throws IOException {
        Stage2 = new Stage();
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Second.fxml"));
        Object root = fxmlLoader.load();
        Scene scene = new Scene((Parent) root);
        Stage2.setScene(scene);
        SecondController secondController = (SecondController)fxmlLoader.getController();
        secondController.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
                textArea1.appendText(newValue);
            }
        });
        Stage2.show();  
    }
}