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.
Related
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 desktop app with side menu bar. Main window is BorderPane with InsertLeft containing VBox. I set Hbox buttons and their behaviour then I add them one by one to the VBox. InsertCenter has just Pane with alot of elements.
I've created 3 fxml files for each GUI layout.
sample.fxml - BorderPane: InsertLeft->Menu(VBox), InsertCenter->Empty Pane
tab1_content.fxml - Pane filled with ProgressBar, Labels and Buttons
tab2_content.fxml - Not yet implemented (Empty Pane)
Each of these fxml files has their controllers.
I would like to switch content of borderPane.center() inside sample.fxml on menu button click.
I've managed to fix some issues, but main problem is with loading data into .fxml views.
As I run my App it works perfectly, each fxml file has his FXMLLoader which will load content into borderPane right inside main Controller.
Problem occurs while I click on Buttons. It will switch panes, but actual content will reset to default state and Main.class initialization is completely ignored. Button listeners and label values are not initialized. It's just empty fxml layout. Every variable inside Main.class, what I want to access from Tab1Controller is returning NullPointerException - even methods.
Each controller extends AbstractController, which contains Main.class instance which is initialized inside start() method. So i should be able to have access to every Main.class method/variable at any time.
Issue Gif:
Some code samples:
My Main.class start() method:
public Controller myController;
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/sample.fxml"));
myController = new Controller();
myController.setMainApp(this);
loader.setController(myController);
Parent root = loader.load();
primaryStage.setTitle("Simple App");
primaryStage.setScene(new Scene(root));
primaryStage.show();
<other stuff>
}
public void setDefaultViewProperties(){
currentScanningFileProperty = new SimpleStringProperty();
myController.tab1Controller.actualPath.textProperty().bind(currentScanningFileProperty); //NullPointerException while called from Controller
fileCounterProperty = new SimpleLongProperty();
myController.tab1Controller.numOfScanned.textProperty().bind(fileCounterProperty.asString());
maliciousFilesCounterProperty = new SimpleIntegerProperty();
myController.tab1Controller.numOfMaliciousFiles.textProperty().bind(maliciousFilesCounterProperty.asString());
myController.tab1Controller.fileChoiceBtn.setOnMouseClicked(event -> chooseFile());
myController.tab1Controller.runScanBtn.setOnMouseClicked(event -> new Thread(() -> {
try {
resetValues();
startFileWalking(chosenFile);
} catch (IOException e) {
e.printStackTrace();
}
}).start());
}
MainController:
package sample;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller extends AbstractController implements Initializable{
public HBox sideMenu;
public VBox mainMenu;
public BorderPane borderPane;
public Boolean isButton1Pressed = false;
public Boolean isButton2Pressed = false;
public static final String TAB_1 = "TAB-1";
public static final String TAB_2 = "TAB-2";
public Button malwareButton;
public Button webShieldButton;
public Tab1Controller tab1Controller;
public Tab2Controller tab2Controller;
#Override
public void initialize(URL location, ResourceBundle resources) {
createMenuButtons();
setSideMenu();
setMenuButtonsListeners();
}
private void setSideMenu(){
mainMenu.getChildren().add(item(malwareButton));
mainMenu.getChildren().add(item(webShieldButton));
mainMenu.setStyle("-fx-background-color:#004D40");
}
private HBox item(Button menuButton){
menuButton.setPrefSize(200, 50);
menuButton.setStyle("-fx-background-color: transparent;");
menuButton.setTextFill(Color.web("#E0F2F1"));
menuButton.setPadding(Insets.EMPTY);
sideMenu = new HBox(menuButton);
return sideMenu;
}
public void setMenuButtonsListeners(){
malwareButton.setOnMousePressed(event -> {
setButtonStylePressed(malwareButton);
setButtonStyleUnpressed(webShieldButton);
isButton1Pressed = true;
isButton2Pressed = false;
loadTab1Content();
main.setDefaultViewProperties();
});
webShieldButton.setOnMousePressed(event -> {
setButtonStylePressed(webShieldButton);
setButtonStyleUnpressed(malwareButton);
isButton1Pressed = false;
isButton2Pressed = true;
loadTab2Content();
});
malwareButton.setOnMouseExited(event -> {
if(!isButton1Pressed){
setButtonStyleUnpressed(malwareButton);
}
});
webShieldButton.setOnMouseExited(event -> {
if(!isButton2Pressed){
setButtonStyleUnpressed(webShieldButton);
}
});
malwareButton.setOnMouseEntered(event -> setButtonStylePressed(malwareButton));
webShieldButton.setOnMouseEntered(event -> setButtonStylePressed(webShieldButton));
}
public void setButtonStylePressed(Button btn){
btn.setStyle("-fx-background-color: #E0F2F1");
btn.setTextFill(Color.web("#004D40"));
}
public void setButtonStyleUnpressed(Button btn){
btn.setStyle("-fx-background-color: transparent");
btn.setTextFill(Color.web("#E0F2F1"));
}
private void loadTab1Content(){
FXMLLoader tab1loader = new FXMLLoader();
tab1loader.setLocation(getClass().getResource("/tab_1_content.fxml"));
try {
if (tab1Controller == null){
tab1Controller = new Tab1Controller();
}
tab1loader.setController(tab1Controller);
borderPane.setCenter(tab1loader.load());
} catch (IOException e) {
e.printStackTrace();
}
}
private void loadTab2Content(){
FXMLLoader tab2loader = new FXMLLoader();
tab2loader.setLocation(getClass().getResource("/tab_2_content.fxml"));
try {
if (tab2Controller == null){
tab2Controller = new Tab2Controller();
}
tab2loader.setController(tab2Controller);
borderPane.setCenter(tab2loader.load());
} catch (IOException e) {
e.printStackTrace();
}
}
private void createMenuButtons(){
malwareButton = new Button();
malwareButton.setText(TAB_1);
webShieldButton = new Button();
webShieldButton.setText(TAB_2);
}
}
Tab1Controller:
package sample;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
/**
* Created by admin on 5. 5. 2018.
*/
public class Tab1Controller extends AbstractController implements Initializable {
public ProgressBar progressBar;
public Button runScanBtn;
public Button fileChoiceBtn;
public Label chosenPath;
public Label actualPath;
public Label numOfMaliciousFiles;
public Label hashValue;
public Label scanFinishedMsg;
public Label numOfScanned;
public Button showFoundMalwareButton;
#Override
public void initialize(URL location, ResourceBundle resources) {
runScanBtn.setDisable(true);
scanFinishedMsg.setVisible(false);
showFoundMalwareButton.setVisible(false);
showFoundMalwareButton.setOnAction(event -> showPopupWindow());
}
Update#1 - Updating fxml values through Main.class after button click
I've finally managed to run app without exception. I had to create next Controller for pane fxml layout itself called Tab1Controller. When I initialized Controller, it instantly initialized Tab1Controller inside. So when I want to change Center BorderPane label i had to call myController.tab1Controller.tabLabel.setText()
I don't know if it's good approach to this problem.
But now I'm back to my old problem. When I click on TAB-1 it will load content, but values are not initialized to default state.
For example I have couple of labels updated in real time. I binded some SimpleProperties into it with default values. It worked before, but as I have three controllers it will load data for a first time, but when I click TAB-1 button it will load just fxml content, but it will not set those labels.
So i made public method inside Main.class which I will call everytime I switch to TAB-1 from Controller.
public void setDefaultViewProperties(){
myController.tab1Controller.actualPath.textProperty().bind(currentScanningFileProperty);
myController.tab1Controller.numOfScanned.textProperty().bind(fileCounterProperty.asString());
myController.tab1Controller.numOfMaliciousFiles.textProperty().bind(maliciousFilesCounterProperty.asString());
}
But now everytime I click on TAB-1 I've got
java.lang.NullPointerException: Cannot bind to null
You can make two pane and switch between them using setVisible() method
example:
void btn1Clicked() {
pane1.setVisible(true);
pane2.setVisible(false);
}
void btn2Clicked() {
pane1.setVisible(false);
pane2.setVisible(true);
}
You could use a TabPane to achieve this behaviour:
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TabPane.html
Solved. I'm not sure how, but setDefaultViewProperties() are not throwing NullPointerException at the moment. I did not change anything inside the code:
malwareButton.setOnMousePressed(event -> {
setButtonStylePressed(malwareButton);
setButtonStyleUnpressed(webShieldButton);
isButton1Pressed = true;
isButton2Pressed = false;
loadTab1Content();
main.setDefaultViewProperties();
});
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.
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.
Is there a way of opening a full web page using Java, I have to check the time taken in opening full web page in a Java user end application, I have tried this code:
URL ur = new URL("http://www.google.com/");
HttpURLConnection yc =(HttpURLConnection) ur.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
but this gives me the source code of the url... that's useless for me!
as I need to record the time taken by a webpage to load on my desktop by making a Java application.
Everything is on client site!
Here is a JavaFX based sample:
import java.util.Date;
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.concurrent.Worker.State;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.*;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
/** times the loading of a page in a WebEngine */
public class PageLoadTiming extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) {
final Label instructions = new Label(
"Loads a web page into a JavaFX WebEngine. " +
"The first page loaded will take a bit longer than subsequent page loads due to WebEngine intialization.\n" +
"Once a given url has been loaded, subsequent loads of the same url will be quick as url resources have been cached on the client."
);
instructions.setWrapText(true);
instructions.setStyle("-fx-font-size: 14px");
// configure some controls.
final WebEngine engine = new WebEngine();
final TextField location = new TextField("http://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm");
final Button go = new Button("Go");
final Date start = new Date();
go.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent arg0) {
engine.load(location.getText());
start.setTime(new Date().getTime());
}
});
go.setDefaultButton(true);
final Label timeTaken = new Label();
// configure help tooltips.
go.setTooltip(new Tooltip("Start timing the load of a page at the entered location."));
location.setTooltip(new Tooltip("Enter the location whose page loading is to be timed."));
timeTaken.setTooltip(new Tooltip("Current loading state and time taken to load the last page."));
// monitor the page load status and update the time taken appropriately.
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
#Override public void changed(ObservableValue<? extends State> state, State oldState, State newState) {
switch (newState) {
case SUCCEEDED: timeTaken.setText(((new Date().getTime()) - start.getTime()) + "ms"); break;
default: timeTaken.setText(newState.toString());
}
}
});
// layout the controls.
HBox controls = HBoxBuilder.create().spacing(10).children(new Label("Location"), location, go, timeTaken).build();
HBox.setHgrow(location, Priority.ALWAYS);
timeTaken.setMinWidth(120);
// layout the scene.
VBox layout = new VBox(10);
layout.setStyle("-fx-padding: 10; -fx-background-color: cornsilk; -fx-font-size: 20px;");
layout.getChildren().addAll(controls, instructions);
stage.setTitle("Page load timing");
stage.getIcons().add(new Image("http://icons.iconarchive.com/icons/aha-soft/perfect-time/48/Hourglass-icon.png"));
stage.setScene(new Scene(layout, 1000, 110));
stage.show();
// trigger loading the default page.
go.fire();
}
}
Yeah home is right that should do the trick. But this way is much more simpler... Although a bit erroneous it should serve fine for benchmark purposes.
JEditorPane editorPane = new JEditorPane();
editorPane.setPage(new URL("http://www.google.com"));
The scripts are still rendered on the screen if you just use this snippet, although it can be worked around I don't think you will need to bother with that since you need to just benchmark loading time... However the results may be varying very slightly since it doesn't take time to run the JavaScript.
You can use Cobra
You can use plain Swing also
You can also use JavaFX to do it like this:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.web.WebView;
public class MyWebView extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) {
final WebView wv = new WebView();
wv.getEngine().load("http://www.google.com");
primaryStage.setScene(new Scene(wv));
primaryStage.show();
}
}
To open a web page using java , try the following code :
import java.io.*;
public class b {
public static void main(String args[])throws IOException
{
String downloadURL="<url>";
java.awt.Desktop myNewBrowserDesktop = java.awt.Desktop.getDesktop();
try
{
java.net.URI myNewLocation = new java.net.URI(downloadURL);
myNewBrowserDesktop.browse(myNewLocation);
}
catch(Exception e)
{
}
}
}
This will open the web page in your default browser . As for the time taken to load part , have a look here . There are a lot of suggestions there .