I am new to JavaFX and I was just typing some code...but whenever I try to run the application the second time I get an error stating: application launch must not be called more than once:
My first code was:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.application.*;
public class App extends Application{
public void start (Stage primaryStage){
primaryStage.setTitle("Chess");
primaryStage.show();
}
public static void main(String args[]){
Application.launch (args);
}
}
then after doing some search I changed it to:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.application.*;
public class App extends Application{
public void start (Stage primaryStage){
Platform.setImplicitExit(true);
primaryStage.setTitle("Chess");
primaryStage.show();
}
public static void main(String args[]){
Application.launch (args);
}
}
But it still shows the same error:
java.lang.IllegalStateException: Application launch must not be called more than once
Why you are adding
Platform.setImplicitExit(true);
it is by default true, you don't need to call main method, just compile and run your application.
Related
I am running a simple javafx program on eclipse IDE. However, whenever I run my code, a launch error is displayed. There is no description of the error by the IDE and I am not sure what is causing that.
Also, I have e(fx)clipse and Gluon plugin installed.
My code is very simple and I don't think that it is causing this error, however, I have attached it below for reference.
package application;
import Menus.MainMenu;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
MainMenu mainMenu = new MainMenu();
primaryStage = mainMenu.getMainStage();
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Code for MainMenu is
package Menus;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainMenu {
private static final int HEIGHT = 600;
private static final int WIDTH = 800;
private AnchorPane mainPane;
private Scene mainScene;
private Stage mainStage;
public MainMenu() {
mainPane = new AnchorPane();
mainScene = new Scene(mainPane);
mainStage = new Stage();
mainStage.setScene(mainScene);
mainStage.setFullScreen(true);
}
public Stage getMainStage() {
return mainStage;
}
}
Check the log file for the exact error and resolve it at :
C:\app\eclipse\configuration\
Check if the JRE is properly configured in eclipse as well as environment variables.
Do not just click on the run button, check if you are running the proper program path by clicking on the arrow next to run. (This is a common problem with beginners)
If you find everything else troublesome, try re-installing the IDE and running a simple hello world. If the problem persists, it is something to do with the environment variables or your eclipse setup.
my apologies if this is an easy thing for you, but my mind boggles. After several years of not programming at all, I am working on a pet project (2d tile based game engine) where I would like to use Java FX headless in order to make use of the graphics capabilities.
I have understood from here and here
that you need to a Java FX Application in order to have the graphics system initialized.
So I basically took the ImageViewer example and implemented Runnable:
package net.ck.game.test;
import java.io.BufferedReader;
import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ImageTest extends Application implements Runnable {
protected static final Logger logger = (Logger) LogManager.getLogger(ImageTest.class);
BufferedReader x;
#Override public void start(#SuppressWarnings("exports") Stage stage) {
logger.error(Thread.currentThread().getName() + ", executing run() method!");
Image standardImage = new Image("file:graphics/image1.png");
logger.error("image height image1: "+ standardImage.getHeight());
logger.error("image width image1:" + standardImage.getWidth());
Image movingImage = new Image("file:graphics/image2.png");
ArrayList<Image> images = new ArrayList<Image>();
images.add(movingImage);
images.add(standardImage);
ImageView iv1 = new ImageView();
iv1.setImage(standardImage);
ImageView iv2 = new ImageView();
iv2.setImage(movingImage);
Group root = new Group();
Scene scene = new Scene(root);
scene.setFill(Color.BLACK);
HBox box = new HBox();
box.getChildren().add(iv1);
box.getChildren().add(iv2);
root.getChildren().add(box);
stage.setTitle("ImageView");
stage.setWidth(415);
stage.setHeight(200);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void run()
{
Application.launch(ImageTest.class);
}
}
When I run this as its own application, this works fine and displays the two images I want it to display.
When I run it like this in the "game" constructor:
public class Game {
private boolean animated;
public boolean isAnimated() {
return animated;
}
public void setAnimated(boolean animated) {
this.animated = animated;
}
public Game() {
setAnimated(true);
if (isAnimated() == true)
{
ImageTest imageTest = new ImageTest();
new Thread(imageTest).start();
}
}
There are no errors, ImageTest runs in its own thread, the application window opens, but it is empty.
I do not understand this at all, why is that?
Can someone pleaese shed some light on this?
UPDATE:
I had different working contexts by accident. Fixing this fixed the problem.
UPDATE: I had different working contexts by accident. Fixing this fixed the problem.
I have this code to play music (found online):
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
public class MusicBackground {
public static void main(String[] args) throws Exception {
URL url = MusicBackground.class.getResource("backgroundMusic.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
Thread.sleep(1000);
clip.loop();
}
}
It works fine alone. But the thing is that after I implemented it into my game, it either plays the music when I'm launching the music class, or when I run the entire game, it runs the game without the music. Here is my Boot class for my game:
import static helpers.Artist.BeginSession;
import org.lwjgl.opengl.Display;
import helpers.Clock;
import helpers.StateManager;
public class Boot {
public Boot() {
//Call static method in Artist class to initialize OpenGL calls
BeginSession();
//Main game loop
while (!Display.isCloseRequested()) {
Clock.update();
StateManager.update();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args) {
new Boot();
}
}
I know that the music background class is in public static void main. But how do I implement it into the boot class ?
Change your background music class to implement runnable:
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
import java.lang.Runnable;
public class MusicBackground implements Runnable {
public void run() throws Exception {
URL url = MusicBackground.class.getResource("backgroundMusic.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
Thread.sleep(1000);
clip.loop();
}
}
Then you can spawn a thread for the background music in your game's main thread. If you just direct call or paste that background music code in the main game loop, then the .sleep call will cause the entire program to sleep (as it is currently one thread). So, this is what your main method will look like now:
import static helpers.Artist.BeginSession;
import org.lwjgl.opengl.Display;
import helpers.Clock;
import helpers.StateManager;
public class Boot {
public Boot() {
//Call static method in Artist class to initialize OpenGL calls
BeginSession();
Thread backgroundPlayer;
Try {
backgroundPlayer = new Thread(new MusicBackground());
backgroundPlayer.start();
}
catch(Exception e)
{
System.out.println("Problem firing the background thread");
e.printStackTrace();
}
//Main game loop
while (!Display.isCloseRequested()) {
Clock.update();
StateManager.update();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args) {
new Boot();
}
}
I am creating a dialog and call Platform.runLater() in the controller initialize() method.
When I try to open the dialog with showAndWait() it loads the FXML (I know it does because the warning is printed before Running Later and After first showAndWait) but doesn't open the dialog. Only a second call to showAndWait() will open it. It there a reason for this wired behavior or is this a bug?
The console output is:
Starting dialog creation
Running Later
After first showAndWait
Closing
After second showAndWait
but is should be:
Starting dialog creation
Init
Running Later
Closing
After first showAndWait
Closing
After second showAndWait
There is also this warning:
Apr 20, 2018 12:20:32 AM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 9.0.1 by JavaFX runtime of version 8.0.161
But as far as I know this just means that my JavaFX version is outdated.
Main class:
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(new BorderPane()));
stage.show();
System.out.println("Starting dialog creation");
Dialog<Optional<List<String>>> popup = new Dialog<>();
FXMLLoader loader = new FXMLLoader(Main.class.getClassLoader().getResource("Dialog.fxml"));
try {
popup.setDialogPane(loader.load());
} catch (IOException e) {
e.printStackTrace();
}
Controller controller = loader.getController();
controller.dialog = popup;
popup.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
popup.showAndWait();
System.out.println("After first showAndWait");
popup.showAndWait();
System.out.println("After second showAndWait");
}
}
Controller:
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Dialog;
public class Controller {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
public Dialog<Optional<List<String>>> dialog;
#FXML
void initialize() {
System.out.println("Init");
Platform.runLater(() -> {
System.out.println("Running Later");
dialog.setResult(Optional.empty());
dialog.setOnCloseRequest(e -> {
System.out.println("Closing");
});
});
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.DialogPane?>
<DialogPane contentText="This is a text" headerText="Test" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller" />
While working on trying to make some simple buttons with Event Driven Programming I was looking at an example in my textbook (Intro to Java Programming 10th edi.) I followed some code from the book to try and replicate it myself for a project I'm working on. The program compiles, but when it runs I get:
Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class ButtonPackage.ButtonEvent
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$156(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: ButtonPackage.ButtonEvent.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:818)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
... 1 more
After getting advice from the answers I was able to get it working. Below is the corrected condensed code:
package ButtonPackage;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
/**
* Created by Brandon on 12/5/2015.
*/
public class ButtonEvent extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override //Override start method Application Class
public void start(Stage primaryStage) {
//create pane set properties
HBox pane = new HBox(10);
pane.setAlignment(Pos.CENTER);
Button btEnter = new Button("ENTER NUMBER");
Button btCheck = new Button("CHECK IF WINNER");
EnterNumber handler1 = new EnterNumber();
btEnter.setOnAction(handler1);
CheckWinner handler2 = new CheckWinner();
btCheck.setOnAction(handler2);
pane.getChildren().addAll(btEnter, btCheck);
//Create scene place on stage
Scene scene = new Scene(pane);
primaryStage.setTitle("HandleEvent"); //Set Stage Title
primaryStage.setScene(scene); //Place scene in stage
primaryStage.show(); //Display stage
}//end start
}//end ButtonEvent
class EnterNumber implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
System.out.println("ENTER NUMBER button clicked");
}//end handle
}//end EnterNumber
class CheckWinner implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
System.out.println("CHECK IF WINNER button clicked");
//eventLottery.main();
}//end handle
}//end CheckWinner
Thanks for the help!
It looks like you are running this in IntelliJ. While it is permissible for an Application subclass not to have a main(...) method, not all IDEs support this execution mode.
Note that, in any execution mode, your main class must be public.
If you want to run from inside the IDE, add a main method that simply calls launch():
public class ButtonEvent extends Application {
// existing code ...
public static void main(String[] args) {
launch(args);
}
}
(or just run it directly from the command line).
You did not define a public static main(String[] args) method. You need to define this method, and tell java which class this method is in.