2014-09-12 78 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構造函數的地方調用它。