2014-09-12 92 views
0

大家好,我通过FXMLLoader加载一个fxml文件,总是出现错误。我得到这个类:StackOverflowError加载FXML文件

package mediabox.app.model; 

import java.io.IOException; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 
import mediabox.app.controller.Controller; 

/** 
* Objekte diser Klasse repräsentieren Fenster 
* @author Christian 
*/ 
public class Window { 

    private final Stage stage; 

    /** 
    * 
    * @param resourceURL Pfad der zu ladenden FXML Datei 
    * @param controller Controller des Fensters 
    * @param height Höhe des Fensters 
    * @param width Breite des Fensters 
    * @param resizable Gibt an ob das Fenster maximierbar sein soll 
    * @param fullscreen Gibt an ob das Fenster als Vollbild geöffnet wird 
    * @throws IOException 
    */ 
    public Window(String resourceURL, Controller controller, int height, int width, boolean resizable, boolean fullscreen) throws IOException{ 
     FXMLLoader loader = new FXMLLoader(getClass().getResource(resourceURL)); //Lädt die zugehörige FXML 
     loader.setController(controller); 
     Parent root = (Parent)loader.load(); 
     Scene scene = new Scene(root, height, width); 
     stage = new Stage(); 
     stage.setResizable(resizable); 
     stage.setFullScreen(fullscreen); 
     stage.setScene(scene); 
    } 


    /** 
    * Zeigt das Fenster 
    */ 
    public void show(){ 
     stage.show(); 
    } 

    /** 
    * Versteckt das Fenster 
    */ 
    public void hide(){ 
     stage.hide(); 
    } 
} 

这是我的窗口类。

 package mediabox.app.controller; 

import java.io.IOException; 
import java.net.URL; 
import java.sql.SQLException; 
import java.util.ResourceBundle; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.TableView; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.layout.VBox; 
import javafx.scene.media.MediaView; 
import javax.naming.NamingException; 
import mediabox.app.model.DatabaseConnector; 
import mediabox.app.model.Music; 
import mediabox.app.model.Window; 
import mediabox.app.model.exceptions.ConnectionException; 

/** 
* FXML Controller class 
* Diese Klasse repräsentiert den MusicscreenController. Er steuert alle Aktion 
* die auf auf dem Musicscreen getätigt werden. D.h auch die Aktionen die 
* innerhalb der Tabelle(Datenbank) und der Playlist ausgeführt werden. 
* @author Christian 
*/ 
public final class MusicscreenController extends Controller implements Initializable { 

    @FXML private VBox box; 

    //@FXML private Node playlistNode; 
    @FXML private final TableView libraryNode; 
    @FXML private MediaView mediaPlayerView; 


    private final Window musicscreen; 

    public MusicscreenController() throws IOException { 
     musicscreen = new Window("/mediabox/app/view/MusicscreenView.fxml", this, 0, 0, false, true); 
     musicscreen.show(); 
     libraryNode = new TableView(); 
     initLibrary(); 
     libraryNode.requestFocus(); 
     libraryNode.getSelectionModel().selectFirst(); 

    } 

    /** 
    * Initialisiert die Bibliothek 
    */ 
    @Override 
    protected void initLibrary(){ 
     try { 
      DatabaseConnector.connectTo("src/mediabox/database/database"); 
      libraryNode.getItems().addAll(DatabaseConnector.loadEntries("Music")); // Einträge der Datenbank 
                      // auslesen und der library Node hinzufügen 
     } catch (SQLException | ConnectionException | NamingException | ClassNotFoundException ex) { 
      Logger.getLogger(MusicscreenController.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

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


    @FXML 
    public void onLibraryRequest(KeyEvent e){ 
     if(e.getCode().equals(KeyCode.ENTER)){ 
      try { 
       MediaPlayerController mediaPlayerController = new MediaPlayerController((Music)libraryNode.getSelectionModel().getSelectedItem()); 
      } catch (IOException ex) { 
       Logger.getLogger(MusicscreenController.class.getName()).log(Level.SEVERE, null, ex); 
      } 

     } 
    } 


} 

这是我的控制器类。

我在这段代码中找不到任何eroor。几天的代码工作正常....

-GhostfaceChilla-

回答

0

当加载FXML中,FXML装载机看到的根元素fx:controller="mediabox.app.controller.MusicscreenController"属性。这指示它实例化一个new MusciscreenControllerMusicscreenController的构造函数调用Window构造函数。构造函数Window创建一个新的FXMLLoader并调用其方法load(),该方法解析FXML,使其创建新的MusicscreenController

所以你有无限的递归。

你可能只需要完全从控制器中删除构造函数,并把大部分的逻辑从那里在initialize()方法:

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    initLibrary(); 
    libraryNode.requestFocus(); 
    libraryNode.getSelectionModel().selectFirst(); 
} 

你真的不能显示来自控制器的窗口,同时作为构造函数和initialize方法保证在您将机器从FXML添加根节点到Scene之前完成。 (另外,你希望你的FXML - 控制器对有足够的灵活性,以便能够使用的时候都没有一个Scene的根。)

所以,你应该要么只是从Window构造函数调用show(),还是应该从你调用Window构造函数的地方调用它。