大家好我通过FXMLLoader加载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);
}
}
}
}
这是我的Controller类。
我在这段代码中找不到任何琐事。几天代码工作正常....
-GhostfaceChilla -
答案 0 :(得分:0)
加载FXML时,FXML加载程序会在根元素中看到fx:controller="mediabox.app.controller.MusicscreenController"
属性。这指示它实例化new MusciscreenController
。 MusicscreenController
的构造函数调用Window
构造函数。 Window
构造函数创建一个新的FXMLLoader
并调用其load()
方法,该方法解析FXML,使其创建新的MusicscreenController
。
所以你有无限的递归。
您可能只需要完全从控制器中删除构造函数,并将initialize()
方法中的大部分逻辑放在其中:
@Override
public void initialize(URL url, ResourceBundle rb) {
initLibrary();
libraryNode.requestFocus();
libraryNode.getSelectionModel().selectFirst();
}
您无法真正显示控制器中的窗口,因为在您有机会将FXML中的根节点添加到initialize
之前,构造函数和Scene
方法都可以保证完成。 (此外,您希望您的FXML-Controller对足够灵活,以便在它们不是Scene
的根时使用。)
所以你应该只从show()
构造函数调用Window
,或者你应该从调用Window
构造函数的任何地方调用它。