Я создал приложение JavaFX, которое почти завершено. Я экспортировал его как runnable JAR. При открытии этого JAR я вижу только пустое окно. Я выполнил некоторые другие ответы из stackoverflow, но я не получил его работу. Он работает только в среде Eclipse!Java: Экран не был загружен
Мои экраны контроллера:
package gui;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
public class ScreensController extends StackPane {
\t private HashMap<String, Node> screens = new HashMap<>();
\t public static String sourcePath = "";
\t private CoreService coreService;
\t
\t public ScreensController(){
\t \t super();
\t }
\t
\t
\t public void addScreen(String name, Node screen) {
\t screens.put(name, screen);
\t }
\t
\t public boolean loadScreen(String name, String resource) {
\t \t System.out.println("ID: "+name);
\t \t System.out.println("Resource: "+resource);
\t \t String file = System.getProperty("user.dir")+"\\bin\\"+resource;
// \t \t System.out.println(file);
\t \t
\t try {
\t FXMLLoader myLoader = new FXMLLoader();
\t File f = new File(file);
\t URL url = f.toURI().toURL();
\t myLoader.setLocation(url);
// \t System.out.println("Location: "+myLoader.getLocation());
\t
\t Parent loadScreen = (Parent) myLoader.load();
\t ControlledScreen myScreenControler =
\t ((ControlledScreen) myLoader.getController());
\t myScreenControler.setScreenParent(this);
\t addScreen(name, loadScreen);
\t System.out.println("Anzahl Screens: "+screens.size());
\t return true;
\t }catch(Exception e) {
\t \t System.out.println("Fehler beim Laden von "+file);
\t \t System.out.println(e.getMessage());
\t \t return false;
\t }
\t
\t }
\t
\t public boolean setScreen(final String name) {
\t \t @SuppressWarnings("unused")
\t \t Node screenToRemove;
if(screens.get(name) != null){ //screen loaded
\t if(!getChildren().isEmpty()){ //if there is more than one screen
\t \t \t getChildren().add(0, screens.get(name)); //add the screen
\t \t \t screenToRemove = getChildren().get(1);
\t \t \t getChildren().remove(1); //remove the displayed screen
\t }else{
\t \t getChildren().add(screens.get(name)); //no one else been displayed, then just show
\t }
\t return true;
}else {
\t System.out.println("Screen hasn't been loaded!!! \n");
\t return false;
}
\t }
\t
\t public boolean unloadScreen(String name) {
\t \t if(screens.remove(name) == null) {
\t \t \t System.out.println("Screen didn't exist!!!");
\t return false;
\t } else {
\t return true;
\t }
\t }
\t public void print() {
\t \t Set<String> keys = screens.keySet();
\t \t Iterator<String> it = keys.iterator();
\t \t while (it.hasNext()){
\t \t \t System.out.println("Key: "+it.next());
\t \t }
\t \t
\t }
\t
\t public CoreService getCoreService(){
\t \t return this.coreService;
\t }
\t
\t public void setCoreService(CoreService coreService){
\t \t this.coreService = coreService;
\t }
\t
}
И здесь я использую его:
package gui;
import java.util.Optional;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class MainMenu extends Application {
private Stage mainStage;
private static CoreService coreService;
\t
\t public static final String MAIN_SCREEN = "main";
\t public static final String MAIN_SCREEN_FXML = "gui\\MainMenu.fxml"; \t
\t
\t @Override
\t public void start(Stage primaryStage) {
\t \t
\t \t this.mainStage = primaryStage;
\t
\t \t ScreensController mainContainer = new ScreensController();
\t \t
\t \t mainContainer.loadScreen(MainMenu.MAIN_SCREEN, MainMenu.MAIN_SCREEN_FXML); \t
\t \t
\t \t mainContainer.setCoreService(MainMenu.coreService);
\t \t
\t \t mainContainer.setScreen(MainMenu.MAIN_SCREEN);
\t \t Group root = new Group();
\t \t root.getChildren().addAll(mainContainer);
\t \t Scene scene = new Scene(root);
\t \t primaryStage.setScene(scene);
\t \t primaryStage.setOnCloseRequest(confirmCloseEventHandler);
\t \t primaryStage.show();
\t \t
\t }
\t
private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
\t //Source: http://stackoverflow.com/questions/29710492/javafx-internal-close-request
Alert closeConfirmation = new Alert(
Alert.AlertType.CONFIRMATION,
"Are you sure you want to exit?"
);
Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(
ButtonType.OK
);
exitButton.setText("Exit");
closeConfirmation.setHeaderText("Confirm Exit");
closeConfirmation.initModality(Modality.APPLICATION_MODAL);
closeConfirmation.initOwner(mainStage);
closeConfirmation.setX(mainStage.getX() + 150);
closeConfirmation.setY(mainStage.getY() - 300 + mainStage.getHeight());
Optional<ButtonType> closeResponse = closeConfirmation.showAndWait();
if (!ButtonType.OK.equals(closeResponse.get())) {
event.consume();
}
};
\t
\t public static void main(String[] args, CoreService aService) { \t
\t \t // Weitergeben des CoreServices
\t \t coreService = aService;
\t \t launch(args);
\t }
}
I не вижу, где ошибка. Когда я запускаю программу из командной строки, он говорит, что файл MainMenu.fxml не найден. В моем приложении оно находится в пакете gui. -> gui/MainMenu.fxml
Было бы хорошо, если бы кто-то нашел мою ошибку!
Спасибо, я попытался почти то, что вы предложили, но я пропустил, чтобы добавить ведущую косую черту перед пути ! Спасибо за ответ! –