2015-03-16 2 views
0

Я объявил два FXML файлов и контроллер для каждого из них: rootlayoutcontroller является контроллером для rootlayout.fxml и overviewcontroller является контроллером для overview.fxmlLoader конкретизация бросает NullPointer в JavaFX

rootlayout имеет панель меню с открытым файлом, а в контрольном контроллере есть кнопка рисования.

У меня есть еще один класс под названием DataStructure. Я хочу открыть файл и отправить путь к диспетчеру обзора. Затем, когда я нажимаю Draw, конструктор DartaStructure получает экземпляр, с параметром path. Но как только я нажимаю кнопку «Открыть», на открывшемся диалоге выбора файла программа выдает нулевой указатель для метода handleOpen(). Иногда я получаю источник не найден!

В основном классе я обертываю обзор в rootlayout и показываю сцену.

RootLayoutController:

public class RootLayoutController { 
private final Model model; 

public RootLayoutController(Model model){ 
this.model = model; 
} 

/** 
* Opens a FileChooser to let the user select a .z3lgm file to load. 
*/ 
@FXML 
private void handleOpen() { 

    FileChooser fileChooser = new FileChooser(); 

    // Set extension filter 
    FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
      "3lgm2 files (*.z3lgm)", "*z3lgm"); 
    fileChooser.getExtensionFilters().add(extFilter); 

    // Show open file dialog 
    File file = fileChooser.showOpenDialog(main.getPrimaryStage());  
    if (file != null) { 
     path = file.toString();  
     model.setText(path);//error 


    } 

} 
} 

OverViewController:

public class OverViewController implements Initializable { 
private final Model model; 

public OverViewController(Model model){ 
    this.model = model; 
} 
public void treeTableDraw(ActionEvent event) { 

    String p = model.getText(); 
    new Controller(p); 
    drawTable(); 
    numberOfFunctions = dc.getFuncAll().size(); 
    numberOfOrganizations = dc.getSortedAssignedOrg().size(); 
    funcLabel.setText(numberOfFunctions + ""); 
    orgLabel.setText(numberOfOrganizations + ""); 
    btnDraw.setDisable(true); 

} 
} 

стека Ошибка:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770) 
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653) 
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) 
at javafx.event.Event.fireEvent(Event.java:198) 
at javafx.scene.control.MenuItem.fire(MenuItem.java:462) 
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405) 
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$341(ContextMenuContent.java:1358) 
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$$Lambda$326/15872584.handle(Unknown Source) 
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) 
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) 
at javafx.event.Event.fireEvent(Event.java:198) 
at javafx.scene.Scene$MouseHandler.process(Scene.java:3758) 
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486) 
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) 
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$209/5704663.get(Unknown Source) 
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384) 
at com.sun.glass.ui.View.handleMouseEvent(View.java:555) 
at com.sun.glass.ui.View.notifyMouse(View.java:927) 
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) 
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139) 
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$41/19140780.run(Unknown Source) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.reflect.InvocationTargetException 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) 
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) 
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1767) 
... 46 more 
Caused by: java.lang.NullPointerException 
at view.RootLayoutController.handleOpen(RootLayoutController.java:174) 
... 56 more 

Главный класс:

public class Main extends Application { 
private Stage primaryStage; 
private BorderPane rootLayout; 
private Model model = new Model; 

// private ObservableList<DataConstructor> treeTableData = 
// FXCollections.observableArrayList(); 

@Override 
public void start(Stage primaryStage) { 

    this.primaryStage = primaryStage; 
    this.primaryStage.setTitle("IT-Saturation"); 
    initRootLayout(); 
    showOverView(); 

} 

private void showOverView() { 
    try { 
     FXMLLoader loader = new FXMLLoader(); 

     loader.setLocation(Main.class.getResource("/view/OverView.fxml")); 
     loader.setController(new OverViewController(model)); 
    // Parent firstUI = loader.load(); 
     AnchorPane overView = (AnchorPane) loader.load(); 
     rootLayout.setCenter(overView); 
     // OverViewController controller = loader.getController(); 
     // controller.setMainApp(this); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void initRootLayout() { 
    try { 
     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(Main.class.getResource("/view/RootLayout.fxml")); 
     loader.setController(new RootLayoutController(model)); 

     rootLayout = (BorderPane) loader.load(); 
     // show scene containing the root layout 
     Scene scene = new Scene(rootLayout); 
     scene.getStylesheets().add(
       getClass().getResource("application.css").toExternalForm()); 
     primaryStage.setScene(scene); 
     // gives controller access to main 
     RootLayoutController controller = loader.getController(); 
     controller.setMainApp(this); 
     primaryStage.show(); 

    } catch (IOException e) { 

     e.printStackTrace(); 
    } 


} 

/** 
* Returns the main stage. 
* 
* @return primaryStage 
*/ 
public Stage getPrimaryStage() { 
    return primaryStage; 
} 

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





public void showMostComputerizedStatistics() { 
    try { 
     // Load the fxml file and create a new stage for the popup. 
     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(Main.class 
       .getResource("view/BirthdayStatistics.fxml")); 
     AnchorPane page = (AnchorPane) loader.load(); 
     Stage dialogStage = new Stage(); 
     dialogStage.setTitle("Birthday Statistics"); 
     dialogStage.initModality(Modality.WINDOW_MODAL); 
     dialogStage.initOwner(primaryStage); 
     Scene scene = new Scene(page); 
     dialogStage.setScene(scene); 

     // Set the persons into the controller. 
     MostComputerizedController controller = loader.getController(); 

     dialogStage.show(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

} 

Это RootLayout FXML:

<?xml version="1.0" encoding="UTF-8"?> 
 

 
<?import javafx.scene.input.*?> 
 
<?import javafx.scene.control.*?> 
 
<?import java.lang.*?> 
 
<?import javafx.scene.layout.*?> 
 
<?import javafx.scene.layout.BorderPane?> 
 

 
<BorderPane prefHeight="500.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" > 
 
    <top> 
 
     <MenuBar BorderPane.alignment="CENTER"> 
 
     <menus> 
 
      <Menu text="_File"> 
 
      <items> 
 
        <MenuItem onAction="#handleOpen" text="_Open" /> 
 
        <MenuItem mnemonicParsing="false" onAction="#handleExportPic" text="Export as picture" /> 
 
        <MenuItem mnemonicParsing="false" text=" Save as" /> 
 
        <MenuItem mnemonicParsing="false" onAction="#doPrint" text="Print" /> 
 
       <MenuItem onAction="#handleExit" text="E_xit"> 
 
        <accelerator> 
 
         <KeyCodeCombination alt="UP" code="X" control="DOWN" meta="UP" shift="UP" shortcut="UP" /> 
 
        </accelerator></MenuItem> 
 
      </items> 
 
      </Menu> 
 
      <Menu mnemonicParsing="false" onAction="#handleMostComputerizedStatistics" text="Statistics"> 
 
       <items> 
 
       <MenuItem mnemonicParsing="false" onAction="#handleMostComputerizedStatistics" text="Show Statistics" /> 
 
       </items> 
 
      </Menu> 
 
      <Menu mnemonicParsing="false" text="Help"> 
 
      <items> 
 
       <MenuItem mnemonicParsing="false" text="About" /> 
 
      </items> 
 
      </Menu> 
 
     </menus> 
 
     </MenuBar> 
 
    </top> 
 
</BorderPane>

И это обзор FXML:

<?xml version="1.0" encoding="UTF-8"?> 
 

 
<?import javafx.scene.text.*?> 
 
<?import javafx.scene.control.*?> 
 
<?import java.lang.*?> 
 
<?import javafx.scene.layout.*?> 
 
<?import javafx.scene.layout.AnchorPane?> 
 

 
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" > 
 
    <children> 
 
     <SplitPane dividerPositions="0.2391304347826087" layoutX="62.0" layoutY="52.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
 
     <items> 
 
      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" SplitPane.resizableWithParent="false"> 
 
       <children> 
 
        <Button fx:id="btnDraw" layoutX="24.0" layoutY="297.0" mnemonicParsing="false" onAction="#treeTableDraw" text="Draw" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="36.0" /> 
 
        <Label fx:id="funcLabel" layoutX="24.0" layoutY="155.0" opacity="0.72" prefHeight="15.0" prefWidth="38.0" text="0" AnchorPane.bottomAnchor="190.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="77.0"> 
 
        <font> 
 
         <Font size="10.0" /> 
 
        </font></Label> 
 
        <Label fx:id="orgLabel" layoutX="17.0" layoutY="219.0" opacity="0.72" prefHeight="14.0" prefWidth="38.0" text="0" AnchorPane.bottomAnchor="165.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="84.0" AnchorPane.topAnchor="219.0"> 
 
        <font> 
 
         <Font size="10.0" /> 
 
        </font></Label> 
 
        <Label layoutX="63.0" layoutY="155.0" text="Functions" AnchorPane.bottomAnchor="190.0"> 
 
        <font> 
 
         <Font size="11.0" /> 
 
        </font> 
 
        </Label> 
 
        <Label layoutX="56.0" layoutY="219.0" text="Organizations" AnchorPane.bottomAnchor="165.0" AnchorPane.topAnchor="213.0"> 
 
        <font> 
 
         <Font size="10.0" /> 
 
        </font> 
 
        </Label> 
 
        <Button fx:id="btnReset" layoutX="21.0" layoutY="345.0" mnemonicParsing="false" onAction="#treeTableReset" onKeyPressed="#treeTableReset" prefHeight="25.0" prefWidth="81.0" text="Reset" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="36.0" /> 
 
       </children></AnchorPane> 
 
      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" SplitPane.resizableWithParent="false"> 
 
       <children> 
 
        <ScrollPane fx:id="scrollPane" prefHeight="398.0" prefWidth="480.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
 
        <content> 
 
         <TreeTableView fx:id="treeTable" editable="true" prefHeight="375.0" prefWidth="246.0" /> 
 
        </content> 
 
        </ScrollPane> 
 
       </children></AnchorPane> 
 
     </items> 
 
     </SplitPane> 
 
    </children> 
 
</AnchorPane>

+0

Похоже, что getController() возвращает null. Вы определили класс контроллера в файле fxml? Можете ли вы опубликовать файл fxml? – Prometheus

+0

нет, контроллер не находится в fxml. Я добавил файлы fxml по вашему желанию. – Iman

ответ

1

FXMLLoader.getController() вернется null если вы называете его до load() был вызван (потому что, если он не загрузил файл FXML, он не знает, что такое контроллер).

Но это все еще не будет делать то, что вы хотите. Вам нужна ссылка на экземпляр контроллера, связанный с корнем файла FMXL , который отображается в пользовательском интерфейсе. Это не помогает просто получить произвольный экземпляр контроллера, независимо от того, выполняете ли вы его, получая его из другого FXMLLoader или создавая его напрямую.

Контрольный экземпляр, который вы хотите, - это тот, который вы можете получить, позвонив по телефону loader.getController() в метод showOverview() в ваш класс Main. Если вы хотите, чтобы контроллеры связывались друг с другом, вам необходимо организовать экземпляр RootLayoutController, чтобы иметь ссылку на этот экземпляр OverViewController.

Возможно, лучше не иметь контроллеров, имеющих прямой доступ друг к другу, но позволять им связываться с данными в общей модели данных. This question имеет простой пример такого подхода.

+0

спасибо. Я сделал это как пример. Я создал класс Model с только getter и setter для строки. Но я все еще ошибаюсь. – Iman

+0

мои извинения. Я забыл новую модель в основном. Теперь это работает. большое спасибо. Это заняло больше времени, чем создание динамического treetableview. – Iman

+0

Все это основано на некоторых шаблонах проектирования, в основном на модели-view-controller и его производных. Как только вы увидели архитектуру несколько раз, это становится довольно естественным. –

Смежные вопросы