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.
Related
I am currently making a program where you can add and delete items from a listview in Java, i want it to be able to automatically save when you add items to the list view and delete items. I am having a hard time figuring out how to do this any help would be greatly appreciated. i am still very new at programming and still trying to figure it all out here is my code i have so far.
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javafx.application.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
public class LendingLibraryGUI extends Application {
LendingLibrary LendingLibrary = new LendingLibrary(); //Creating an Object to access total numbers of items
MediaItems Media = new MediaItems(); // creating an array of object to access MediaItems class and allowing it to hold 100 items
private ListView<String> library = new ListView<String>();
ObservableList<String> libraryList = FXCollections.<String>observableArrayList("yes","no");
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane display = new BorderPane(); //Main display
GridPane buttons = new GridPane(); //location to display buttons
TextField outPut = new TextField(); //Text field to show inventory
Insets padding = new Insets(10); //creates Insets for padding
buttons.setPadding(padding); //padding around grid pane
buttons.setHgap(10); //Horizontal gap
library.setItems(libraryList);
for (int i =0; i !=4;i++) { //Loop to create Buttons
String[] actionButtons = {"Add","Check Out","Check In","Delete"};//String to store Button names
Button temp = new Button(actionButtons[i]);
temp.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
buttons.add(temp, i, 0); //add buttons to grid pane
GridPane.setHgrow(temp, Priority.ALWAYS);
GridPane.setVgrow(temp, Priority.ALWAYS);
if (temp.getText().equals("Add")) {
temp.setOnAction((e) -> add());
}
else if (temp.getText().equals("Delete")) {
temp.setOnAction((e) -> deleteLibrary());
}
}
outPut.setEditable(false); //no editing
outPut.setFont(Font.font("monospace", FontWeight.BOLD, 20));
outPut.setMinHeight(300);//sets minimum height
display.setTop(library); //sets output in display on top
display.setCenter(buttons); //sets buttons on center
Scene scene = new Scene(display); //creates new scene
primaryStage.setTitle("Lending Library"); //sets title of GUI
primaryStage.setScene(scene); //adds scene to GUI
primaryStage.setMinHeight(400); //Minimum height
primaryStage.setMinWidth(350);//Minimum Width
primaryStage.show();//Displays GUI to user
}
public static void main(String[] args) {
launch(args);
}
private void add() {
inputGUI("Title:");
}
private void inputGUI(String input) {
Stage secondaryStage = new Stage();
BorderPane border = new BorderPane();
VBox titlePane = new VBox(8);
HBox buttonLayout = new HBox(8);
Label lblTitle = new Label(input);
Button save = new Button("Save");
Button close = new Button("Close");
Insets padding = new Insets(10);
TextField txt = new TextField("");
close.setOnAction((e) -> secondaryStage.close());;
save.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
try {
LendingLibrary.save(library);
} catch (IOException e1) {
e1.printStackTrace();
}
if (txt.getText().trim().isEmpty()) {
}
else {
if (input.equals("Title:")) {
Media.setTitle(txt.getText());
secondaryStage.close();
inputGUI("Format:");
}
else if (input.equals("Format:")) {
Media.setFormat(txt.getText());
secondaryStage.close();
addToLibrary();
}
else if (input.equals("Who did you loan this to?")) {
}
else if (input.equals("When did you loan it(date)?")) {
}
}
}
});
buttonLayout.getChildren().addAll(close,save);
titlePane.setPadding(padding);
titlePane.getChildren().addAll(lblTitle,txt,buttonLayout);
border.setCenter(titlePane);
BorderPane.setAlignment(titlePane, Pos.CENTER);
Scene scene = new Scene(border); //creates new scene
secondaryStage.setTitle("Input"); //sets title of GUI
secondaryStage.setScene(scene); //adds scene to GUI
secondaryStage.setMinHeight(200); //Minimum height
secondaryStage.setMinWidth(350);//Minimum Width
secondaryStage.show();//Displays GUI to user
}
private void addToLibrary() {
String total;
total = Media.getTitle();
total = total + " ("+ Media.getFormat() +")";
libraryList.add(total);
library.setItems(libraryList);
}
private void deleteLibrary() {
int selectedItem = library.getSelectionModel().getSelectedIndex();
libraryList.remove(selectedItem);
}
private void checkOut() {
}
}
Any other pointers or advice would be greatly appreciated!
Thanks in advance
edit:
Again im very new just trying to learn basic stuff this isnt something i am going to keep just going through a book and this is something in it that its trying to teach me.
public void save(ListView<String> library) throws IOException {
File file = new File ("LendingLibrary.txt"); //creates text file
PrintWriter output = new PrintWriter(file);
if(file.exists()) { //if the file exists
output.println(library);
output.close();
}
if(!file.exists()) { //if file doesn't exist
System.out.println("Error creating file");
}
}
What you really are interested to save is the data that is presented by the list view, you don't need all the other layout information and stuff as they are statically defined in the application and loaded on each run automatically.
Now, although saving the data in a file and loading it each time you need it can work, it is not usually the best. A better approach is to use a database to store the data of your application in form of relation entities, in this way you have a safer and a more consistent approach to work with. To get yourself started in the topic, you can go on and consult the official reference.
If you want to first try using the file approach, the advice is to save the data in some structured format which is then easy to save and load, or in more proper words serialize/deserialize. For this purpose you can use the json format to store the data in a file, and you can use gson library for example:
Each row of the list view is an object that contains the data.
Reading: Serialize the list of data to json format using the gson and store each of them in a separate line.
Reading: Load the list of strings and deserialize them to the java class using gson.
My friend and I have been working on a Java project to create a simple media player using the Media, MediaPlayer, and MediaView classes. However, from the start we've had issues successfully opening the video that we're using as a test file. After many angry runtime exceptions, we finally figured out that the source of our problem was the String being passed into each object (Media needs a String that represents the File Path in a URI format). After some modifications, we found that the following URI worked on my computer to open the File:
Media m = new Media("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4");
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
However, we later tried to implement an Open method that would allow the user to choose which File (as a File object) they wanted to play. When we did this, we used the following to open the file:
File currentFile = new File(null);
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
Media m = new Media(currentFile.toURI().toString());
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
This started giving us runtime exceptions again and so we used a println into the console to find out what the problem was. The string being used was now two "/"s short of what it was supposed to be as:
"file:/C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4"
However, even after modifying the string, we still received the same runtime error as soon as the file was selected:
Exception in Application start method
java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
We then commented the whole Open method out and went back to our original code, but continue to receive the same errors.
Our full code is available here:
SmartPlay class
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;
public class SmartPlay extends Application {
File currentFile;
Scene scene;
#Override
public void start(Stage primary) {
primary.setTitle("SmartPlay");
selectCurrentFileToOpen();
//Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");
scene = new Scene(player, 720, 480, Color.BLACK);
player.setTop(makeMenus());
primary.setScene(scene);
primary.show();
}
private MenuBar makeMenus() {
MenuBar mb = new MenuBar();
Menu fileMenu = new Menu("File");
MenuItem openItem = new MenuItem("Open...");
openItem.setOnAction(e -> {
selectCurrentFileToOpen();
scene.setRoot(new Player(currentFile.toURI()));
});
MenuItem quitItem = new MenuItem("Quit");
quitItem.setOnAction(e -> Platform.exit());
fileMenu.getItems().addAll(openItem, quitItem);
return mb;
}
public boolean selectCurrentFileToOpen() {
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
return true;
}
public void stop() {
}
public static void main(String[] args) {
launch(args);
}
}
Player class
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;
public class Player extends BorderPane {
Media m;
MediaPlayer mp;
MediaView mv;
Pane p;
MediaBar bar;
public Player(String file) {
m = new Media(file);
mp = new MediaPlayer(m);
mv = new MediaView(mp);
p = new Pane();
p.getChildren().addAll(mv);
setCenter(p);
bar = new MediaBar(mp);
setBottom(bar);
setStyle("-fx-background-color:#cccccc");
mp.play();
}
}
MediaBar class
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;
public class MediaBar extends HBox {
Slider time = new Slider();
Slider vol = new Slider();
Button playButton = new Button("Pause");
Button halfSpeed = new Button("0.5x");
Button normalSpeed = new Button("1.0x");
Button doubleSpeed = new Button("2.0x");
Label volume = new Label("Volume: ");
Label nowTime;
MediaPlayer player;
public MediaBar(MediaPlayer play) {
player = play;
setAlignment(Pos.CENTER);
setPadding(new Insets(5,10,5,10));
vol.setPrefWidth(70);
vol.setMinWidth(30);
vol.setValue(100);
nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
HBox.setHgrow(time, Priority.ALWAYS);
playButton.setPrefWidth(30);
getChildren().addAll(playButton,time,nowTime,volume,vol);
}
public static String formatTime(Duration duration) { //StackOverflow: Jon Skeet
long seconds = (long) duration.toSeconds();
long absSeconds = Math.abs(seconds);
String positive = String.format(
"%d:%02d:%02d",
//absSeconds / 3600,
(absSeconds % 3600) / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
}
So I ran your code in command line and I was able to get a more specific debug error. So it seems like the time formatting you do in your MediaBar is causing the error. I don't know exactly what you are trying to do with that but the way you format the time is incorrect. If you comment it out as well as the other things you use to add the time formatting the URI path will be correct and your video should run fine. I know that for the formatting you are missing a '%02d'. As for what you are formatting I am not too sure so I cannot help you there.
This question already has answers here:
Standard concise way to copy a file in Java?
(16 answers)
Closed 6 years ago.
I am making program where user can choose image with FileChooser and display it in program. But i want to save all the images in my folder. I want to store all the images there. So is there any option if user choose image which is on desktop to make a copy of that image and paste it in my folder?
Well im not entirely sure about your implementation and how you are presenting the opened image in your program but taking oracles example from here : http://docs.oracle.com/javafx/2/ui_controls/file-chooser.htm
its fairly simple to make the program copy the selected files to a certain direction using javaNIO:
private void openFile(File file) {
try {
File dest = new File("C:\\Users\\yourProfile\\Desktop"); //any location
Files.copy(file.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(
FileChooserSample.class.getName()).log(
Level.SEVERE, null, ex
);
}
}
You can test this with the example application i linked earlier:
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public final class FileChooserSample extends Application {
private Desktop desktop = Desktop.getDesktop();
#Override
public void start(final Stage stage) {
stage.setTitle("File Chooser Sample");
final FileChooser fileChooser = new FileChooser();
final Button openButton = new Button("Open a Picture...");
final Button openMultipleButton = new Button("Open Pictures...");
openButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
File file = fileChooser.showOpenDialog(stage);
if (file != null) {
openFile(file);
}
}
});
openMultipleButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
List<File> list =
fileChooser.showOpenMultipleDialog(stage);
if (list != null) {
for (File file : list) {
openFile(file);
}
}
}
});
final GridPane inputGridPane = new GridPane();
GridPane.setConstraints(openButton, 0, 0);
GridPane.setConstraints(openMultipleButton, 1, 0);
inputGridPane.setHgap(6);
inputGridPane.setVgap(6);
inputGridPane.getChildren().addAll(openButton, openMultipleButton);
final Pane rootGroup = new VBox(12);
rootGroup.getChildren().addAll(inputGridPane);
rootGroup.setPadding(new Insets(12, 12, 12, 12));
stage.setScene(new Scene(rootGroup));
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
private void openFile(File file) {
try {
desktop.open(file);
File dest = new File("C:\\Users\\yourprofile\\Desktop");
Files.copy(file.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(
FileChooserSample.class.getName()).log(
Level.SEVERE, null, ex
);
}
}
}
You just have to modify the directory, note however there are many ways and implementations of copying files depending on which version of java you are using and whether or not you are using other libraries such as apache io.
Other links that may be useful if you are using a standard file method :
JavaPractices JavaCodeGeek StackOverflow
Hope that helps in anyway :) good luck with your program.
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 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);
}
}