I wanted to know how should I set icons on javaFX stage.
I have found this method, but it did not work properly.
stage.getIcons().add(new Image(iconImagePath));
stage is an instance of javafx.stage.Stage, and I have imported javafx.scene.image.Image.
This is the exception which we receive:
Invalid URL: Invalid URL or resource not found
Also, there is nothing wrong with the iconImagePath, its value is "G:/test.jpg"
and there is a jpg file in the G drive named test. In addition, when we use ImageIO to read the same URL we can do it easily.
stage.getIcons().add(new Image(getClass().getResourceAsStream("bal.png")));
This example works. I placed an icon in the same folder/package as the source .java file.
Directory structure
The constructors of javafx.scene.image.Image expect a URI, not a (full) path. This URI can either be relative (e.g. /images/flower.png) or absolute (e.g. file:flower.png).
Strings like G:/test.jpg are no valid URLs and hence illegal.
Try file:g:/test.jpg instead.
Usually, the icons should be bundled with your application, so simply put the image file into your classpath (e.g. if you're using eclipse, put it into your 'src' directory) and use it like that:
stage.getIcons().add(new Image("/logo.jpg"));
use
stage.getIcons().add(new Image(("file:logo.png")));
and put the image logo.png in root of your project ( at same directory where src )
Best Way:
stage.getIcons().add(new Image(getClass().getResource(IconImagePath).toExternalForm()));
don't forget that your icon must be in 32x32 or 16x16 resolution, if not, it doesn't work.
// Set the icon
stage.getIcons().add(new Image(getClass().getResourceAsStream("penguin.png")));
I faced the same problem. I used Netbeans. I'm not sure if the folder structure is different for other IDEs, but I had to put the picture in /build/classes/(package that contains the JavaFX class file). This means it doesn't go into the src folder.
Here is the working code, which is exactly what you neened:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* #author Manikant gautam
* This is a beginner's sample application
* using JAVAFX
*
*/
public class Helloworld extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
// Set Icon From Here.
primaryStage.getIcons().add(
new Image("/resource/graphics/app_logo.png"));
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Set Icon by statement:
primaryStage.getIcons().add(new Image("/resource/graphics/app_logo.png"));
If you're using eclipse make sure you add the folder that has the image to the build path. this way you can refer to the image with its name with no problems.
This is what I've done and it work. The image is located in the root of my resource folder.
stage.getIcons().add(new Image("/ubuntu-mini.png"));
I am using JavaFX 8
I use netbeans 8.2, if I use :
stage.getIcons().addAll(new Image(getClass().getResourceAsStream("home-icon32.png")));
I have to put the image in src directory. Don't know why, but works only this way. I've tried putting it in build/classes, but negative.
The solution is:
File f = new File("image.png");
Image ix = new Image(f.toURI().toString());
stage.getIcons().add(ix);
public class Main extends Application
{
private static final Logger LOGGER = Logger.getLogger(Main.class);
#Override
public void start(Stage primaryStage)
{
try
{
// BorderPane root = new BorderPane();
BorderPane root = (BorderPane) FXMLLoader
.load(getClass().getResource("/org/geeksynergy/view/layout/FrontPageBorder.fxml"));
root.setAccessibleText("good");
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass()
.getResource("/org/geeksynergy/view/cssstyle/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("AiRJuke");
primaryStage.getIcons().add(new Image("/org/geeksymergy/resource/images/download.png"));
primaryStage.show();
AnchorPane personOverview = (AnchorPane) FXMLLoader
.load(getClass().getResource("/org/geeksynergy/view/layout/Ui.fxml"));
root.setCenter(personOverview);
// added this line to save the playlist , when we close
// application window
Platform.setImplicitExit(false);
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
public void handle(WindowEvent event)
{
M3UPlayList.defaultSavePlaylist();
Platform.setImplicitExit(true);
primaryStage.hide();
}
});
} catch (Exception e)
{
LOGGER.error("Exception while loding application", e);
}
}
public static void main(String[] args)
{
launch(args);
}
}
Related
I am completly lost atm. I have been working with scenebuilder and javaFX in the past but I am stuck like 5 hours now and I didnt get a step further. Let me explain:
I have a working java Eclipse Project, using maven dependencies
The Main is where I want to use JavaFX or load a fxml into
The programm takes many many VCC Files and extracts the data to put it all together in an excel
The programm works but I cant load a FXML file into the main or even show a pane in there
Now does my Java Main class has to extend Application? I tried both ways - doenst work.
Some example code:
public void start(Stage primaryStage) {
try {
bpmain = new BorderPane(FXMLLoader.load(new File("src\\fxml\\UserInterface.fxml").toURI().toURL()));
primaryStage.setScene(new Scene(bpmain));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
or this (from original Docs)
public void start(Stage stage) {
Circle circ = new Circle(40, 40, 30);
Group root = new Group(circ);
Scene scene = new Scene(root, 400, 300);
stage.setTitle("My JavaFX Application");
stage.setScene(scene);
stage.show();
}
but this start method is just not getting called... where do I put that?
What my Programm should look like is pretty simple actually. I want a small UI Windows that lets you pick a Folder where the VCC data lives in and a OK Button that basically should run the Main method.
So a TextField that when its picked a Path in the Main gets replaced (filepath) and just a simple OK Button that says: yeah run the main - because the main works perfectly it is just that I cant show that ui and I dont know how to really connect it to the Main.java
Any help is appreciated - Ty
Option 1
public class Launch extends Application {
public static Stage stage = null;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Option 2:
public class SidebarController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void btnHome_OnMouseClicked(MouseEvent event) throws IOException {
BorderPane borderPane = (BorderPane) ((Node) event.getSource()).getScene().getRoot();
Parent sidebar = FXMLLoader.load(getClass().getResource("/fxml/ContentArea.fxml"));
borderPane.setCenter(sidebar);
}
}
I have a problem with javaFX jar application.
When I compile my project in IDEA it looks like this:
enter image description here
But when I build jar application, after pressing AUTHORIZATION in first window,
it doesn't open next window. I use FXML scenes.
First window is calling from start() method in Main class, others from controllers classes.
Method in main class.
public void start(Stage primaryStage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("Interface.fxml"));
Scene scene = new Scene(parent);
primaryStage.setScene(scene);
primaryStage.setTitle("Hello Client");
primaryStage.show();
}
And one of the controllers class:
#FXML
public void Autentification(ActionEvent actionEvent) throws Exception {
UserInform.AccauntName = name;
UserInform.UserName = name;
int intPort = Integer.parseInt(port);
messages.PrintMessage("Authentication started\n", Out);
ConnectionForUI.session.tryConnect(name, pass, host, intPort);
//Run next window
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../ClientField.fxml"));
Parent root = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setTitle("Client");
stage.setScene(new Scene(root));
stage.show();
}
Autentification method runs when I press Authorization button, and here runs next window.
I'm new in Java FX so if you know how to repaid this problem, I will be very grateful.
Exception:
enter image description here
Problem was in the way to me FXML files. You have to set absolute way to files, like"/file_name.fxml". It helped to me.
This question already has answers here:
Get relative path of a File path? [duplicate]
(2 answers)
Closed 4 years ago.
in this program, im trying to select a file and read the relative path to the project of this file
FileChooser photo = new FileChooser();
Stage stage = new Stage();stage.setTitle("File Chooser Sample");
openButton.setOnAction((final ActionEvent t) -> {
File file = photo.showOpenDialog(stage);
if (file != null) {
System.out.println(file.getPath());;
}
});
the path of my project is
C:\Users\151\eclipse-workspace\FlexiRentGui\
and i'm running the program in eclipse ide
when i select
C:\Users\151\eclipse-workspace\FlexiRentGui\res\1.jpg
instead of printing the relative path "/res/1.jpg"
it still prints the absolute path
C:\Users\151\eclipse-workspace\FlexiRentGui\res\1.jpg
You need to get URI of your current directory/project's root directory and then use java.net.URI.relativize() method to find the relative path of the chosen file w.r.t your project's root. Something like this: new File(cwd).toURI().relativize(file.toURI()).getPath().
Here is the psuedo code:
package org.test;
import java.io.File;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class FileChooserDemo extends Application {
public FileChooserDemo() {};
public static void main(String[] args) throws ClassNotFoundException {
FileChooserDemo.launch(FileChooserDemo.class);
}
public void chooseFileAndPrintRelativePath() {
FileChooser photo = new FileChooser();
Stage stage = new Stage();
stage.setTitle("File Chooser Sample");
Button openButton = new Button("Choose file");
openButton.setOnAction((t) -> {
File file = photo.showOpenDialog(stage);
if (file != null) {
String cwd = System. getProperty("user.dir");
System.out.println(new File(cwd).toURI().relativize(file.toURI()).getPath());
}
});
//Creating a Grid Pane
GridPane gridPane = new GridPane();
//Setting size for the pane
gridPane.setMinSize(400, 200);
gridPane.add(openButton, 0, 0);
Scene scene = new Scene(gridPane);
stage.setScene(scene);
stage.show();
}
#Override
public void start(Stage primaryStage) throws Exception {
chooseFileAndPrintRelativePath();
}
}
You can avoid using the old java.io package and use java.nio instead. Your code will look a bit better and will be much shorter (also using the new library).
To do so just get the current working directory:
var pwd = Paths.get("").toAbsolutePath();
var relative = pwd.relativize(Paths.get("someOtherPath"));
I hope this helps.
I have a JavaFX application that uses a preloader. What I'd like to do is package it up as a native bundle (Mac app or Windows exe file that contains a copy of the Java JDK) so users who don't have the right version of Java on their computers can still run the app. I've followed Oracles instructions for creating native bundles and for adding preloaders. What I get is exactly what you'd expect—a native bundle that runs my program.
The problem is that the bundle completely ignores my preloader. It just runs the main program (after a long load time). I know the preloader is included because, when I run the jar file alone, it shows up.
Has anyone successfully bundled a JavaFX app with a preloader? Can you guide me through how to do so? I'm using Netbeans.
EDIT:
Here is the Preloader:
import javafx.application.Preloader;
import javafx.application.Preloader.ProgressNotification;
import javafx.application.Preloader.StateChangeNotification;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Splash extends Preloader {
ProgressIndicator bar;
ImageView Background;
Stage stage;
private Scene createPreloaderScene() {
bar = new ProgressIndicator();
bar.setLayoutX(380);
bar.setLayoutY(250);
bar.setPrefSize(60, 60);
Background = new ImageView("Images/Splash.png");
Background.setEffect(null);
Pane p = new Pane();
p.setStyle("-fx-background-color: transparent;");
p.getChildren().addAll(Background, bar);
Scene scene = new Scene(p, 794, 587);
scene.setFill(null);
scene.getStylesheets().add(Scrap2.class.getResource("CSS/Progress.css").toExternalForm());
bar.setId("myprogress");
return scene;
}
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
stage.setScene(createPreloaderScene());
stage.initStyle(StageStyle.TRANSPARENT);
stage.show();
}
#Override
public void handleStateChangeNotification(StateChangeNotification scn) {
if (scn.getType() == StateChangeNotification.Type.BEFORE_START) {
stage.hide();
}
}
#Override
public void handleProgressNotification(ProgressNotification pn) {
bar.setProgress(pn.getProgress());
}
#Override
public void handleApplicationNotification(PreloaderNotification arg0) {
if (arg0 instanceof ProgressNotification) {
ProgressNotification pn= (ProgressNotification) arg0;
bar.setProgress(pn.getProgress());
}
}
}
And here is the first part of my main program:
#Override
public void init(){
/*Root*/
root = new Pane();
root.setStyle("-fx-background-color: transparent;");
root.setLayoutX(150);
notifyPreloader(new Preloader.ProgressNotification(0.1));
/*Create Background*/
createBinding(stage);
createContents();
createSaveMessages();
createFlipBook();
notifyPreloader(new Preloader.ProgressNotification(0.2));
/*Add Pages*/
createOverview();
createAccounts();
notifyPreloader(new Preloader.ProgressNotification(0.3));
createCounselors();
createInsurance();
notifyPreloader(new Preloader.ProgressNotification(0.4));
createAssets();
createPapers();
notifyPreloader(new Preloader.ProgressNotification(0.5));
createLoans();
createFuneral();
notifyPreloader(new Preloader.ProgressNotification(0.6));
createWills();
addAllPages();
notifyPreloader(new Preloader.ProgressNotification(0.7));
/*Add Toolbar on top*/
createToolBar();
notifyPreloader(new Preloader.ProgressNotification(0.9));
/*Create Opening Instructions*/
opening();
/*Load Saved Data*/
load();
notifyPreloader(new Preloader.ProgressNotification(1.0));
}
#Override
public void start(Stage stage) {
/*Scene*/
scene = new Scene(root, 1200, 700);
stage.setScene(scene);
scene.setFill(null);
/*Stage*/
this.stage = stage;
stage.initStyle(StageStyle.TRANSPARENT);
stage.centerOnScreen();
stage.show();
}
This example will work with installers exe/msi/image only (have no Mac to test dmg). This step by step assumes, that you already installed the needed tools like InnoSetup, Wix Toolset, etc. It also assumes, that you have configured the tools to run with netbeans (setting paths, edit config files, etc.).
Prerequirements:
Inno Setup for .exe package, download the unicode version: http://www.jrsoftware.org/isdl.php
Wix Toolset for .msi package: http://wixtoolset.org/
Set Windows Paths for Inno Setup and Wix Toolset
Step 1:
I've made a new JavaFX Application Project in Netbeans like this:
Step 2:
Then I gave the project a name and said, that the wizard should create a preloader project with the given name too. Additionally it should create an application class in given package name.
Step 3:
After that I right clicked on the application project and select under deployment "Enable Native Packaging".
Step 4:
In step 4 I've created the code for the application. The preloader will be updated in the init() method and only there. All your work for initialization the application should go here.
JavaFXPreloaderApp.java
import javafx.application.Application;
import javafx.application.Preloader;
import javafx.event.ActionEvent;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class JavaFXPreloaderApp extends Application {
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(createContent(), 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public Parent createContent() {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction((ActionEvent event) -> {
System.out.println("Hello World!");
});
StackPane root = new StackPane();
root.getChildren().add(btn);
return root;
}
#Override
public void init() throws Exception {
// A time consuming task simulation
final int max = 10;
for (int i = 1; i <= max; i++) {
notifyPreloader(new Preloader.ProgressNotification(((double) i) / max));
Thread.sleep(500);
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Step 5:
The only missing part was the preloader code. Look for the only needed method handleApplicationNotification, all the other methods, like handleProgressNotification or handleStateChangeNotification, you can safely delete, or make them empty stubs.
JavaFXPreloader.java
import javafx.application.Preloader;
import javafx.application.Preloader.ProgressNotification;
import javafx.application.Preloader.StateChangeNotification;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
/**
* Simple Preloader Using the ProgressBar Control
*/
public class JavaFXPreloader extends Preloader {
ProgressBar bar;
Stage stage;
private Scene createPreloaderScene() {
bar = new ProgressBar();
BorderPane p = new BorderPane();
p.setCenter(bar);
return new Scene(p, 300, 150);
}
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
stage.setScene(createPreloaderScene());
stage.show();
}
#Override
public void handleApplicationNotification(PreloaderNotification info) {
// Check if info is ProgressNotification
if (info instanceof ProgressNotification) {
// if yes, get the info and cast it
ProgressNotification pn = (ProgressNotification) info;
// update progress
bar.setProgress(pn.getProgress());
// if this was the last progress (progress reached 1), hide preloader
// this is really important, if preloader isn't hide until app loader
// reaches the start method of application and tries to open the stage of
// the main app with the show() method, it will not work.
if (pn.getProgress() == 1.0) {
stage.hide();
}
}
}
}
Step 6:
Now it was time to bundle the application to native packages (image only/exe/msi). I right clicked on the applicaton project and selected the packages to create one by one.
Step 7:
After choosen to package as image only your directory should look like this:
Step 8:
After digging deeper in your directory you should find the image:
Step 9:
A double click on the .exe file should start your application:
Remarks:
The biggest mistake you could do is, to call things in your application start methods. Normaly all have to be done in the application init method, there you load the huge files, there you will connect to the db, or there you load a huge custom layout with a lot of css or fxml files. And there is the place to say good bye to the preloader (progress = 1). Try not to do things at the preloader in your application start method. Don't think in Thread's, the preloader is there to do things before the main stage is shown, so load all in sequence.
I was trying to display a picture in a box with JavaFX. I followed methods documented on Oracle, but it still did not work, though it was extremely similar to the example shown on Oracle. My code is here:
public class TesterJavaFX extends Application {
#Override
public void start(Stage primaryStage) {
Image img = new Image("character.png");
ImageView imgview = new ImageView();
imgview.setImage(img);
imgview.setFitWidth(100);
imgview.setPreserveRatio(true);
imgview.setSmooth(true);
imgview.setCache(true);
HBox box = new HBox();
box.getChildren().add(imgview);
StackPane root = new StackPane();
root.getChildren().add(box);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I have a file called rocket.png in the "src" directory. It even shows up on the IDE. But Java causes a illegal argument exception, and i don't know why. Can anybody help me? Thanks.
Note: The imports are all present.
The string passed to the Image constructor is a URL. If the image file is in the root of your classpath, the following should work:
Image img = new Image(getClass().getResource("/character.png").toExternalForm());