Set application icon for FileChooser in javaFX - java

After I start a FileChooser window in my javaFX application in windows the application icon in the taskbar shows a java icon and not the icon of the main window. Is there a possibility to select an application icon for a FileChooser instance?
Thanks for your answeres!

It is possible to do so, but apparently only when you have a visible parent stage.
Provided that stage in the following example is visible, you can do this:
stage.getIcons().add(new Image("http://i.imgur.com/1M3UaZy.png"));
FileChooser fileChooser = new FileChooser();
File result = fileChooser.showSaveDialog(stage);
This opens the file chooser as a child of the given stage, which has the given icon.
I stepped through the JavaFX source code with a debugger (Oracle Java 8u72 on Windows x64), and there is not single point in the Java code where the icon could be set. The parent window handle is passed into a native method, where it then the icon probably gets resolved somewhere in the Win32 windowing code.

This is an ugly hack based on RAnders00 answer. It calls show before the showSaveDialog call, plus it calls stage.initStyle(StageStyle.UNDECORATED) so we don't get an unwanted window.
In addition, it only worked using resource icons, and not the url example icon.
// For me it only worked with resource icons, nor url example icon
stage.getIcons().add(new Image(getClass().getClassLoader().getResourceAsStream("icon.png")));
FileChooser fileChooser = new FileChooser();
// App icon show hack
stage.initStyle(StageStyle.UNDECORATED); // Remove unwanted window (no buttons no window)
stage.show();
File result = fileChooser.showSaveDialog(stage);
// Close app icon
stage.hide();
Only tested on windows 10.

The issue with the above solution is, that it won't work out of the box when you are using FXML-controllers. That troubled me for a while, but finally I found a solution for that, which I'd like to share with you.
First you need to assign you topmost pane wihtin your fxml-file an id, for instance:
<AnchorPane prefHeight="563.0" prefWidth="442.0" scaleShape="false" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:id="primaryStageAnchorPane" fx:controller="application.MyController">
Now you can use this id in your controller to create the link:
#FXML
private AnchorPane primaryStageAnchorPane;
That whas the hard part. All you need to do now is to get the window-attributes of the linked pane (which are the ones from the primary stage of your application-file):
Stage stage = (Stage) primaryStageAnchorPane.getScene().getWindow();
FileChooser fileChooser = new FileChooser();
File tempFolder = fileChooser.showOpenDialog(stage);
This will overtake the main application's icon for your filechooser-window. As a side-effect your file-chooser won't appear as a seperate item in the task-bar anymore.
Worked for me, hopes it helps somebody out there :)

Related

How can I make a full screen java application?

I have an image viewer appplication. It works perfectly, but I'd like to make a full screen mode for it. It's an FXML project in Netbeans so, the main java is a separated file, therefore I cannot use this:
stage.setFullScreen(true);
because I can't reach the stage from my main .java file.
So I have a file, its name is imageViewer.java, it has this:
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("image_view.fxml"));
Scene scene = new Scene(root);
String css = this.getClass().getResource("style.css").toExternalForm();
scene.getStylesheets().add(css);
stage.setMinHeight(640);
stage.setMinWidth(960);
stage.setScene(scene);
stage.show();
}
and I have another file, it has fxml implements, and the ActionEvent void methods, you know, click the button, next picture etc...
The mentioned method (start method above) it's a method, therefore I can't return the stage. I have to reach the stage from image_viewController.java (the main java), what includes the other methods, functions and FXML implements etc...
I'd like to do this:
public void fullScreen(ActionEvent e) {
stage.setFullScreen(true);
}
But I can't reach the stage from another .java file. This is the first problem. And the second problem.
How can I make position absolute my panes, Vboxes etc like in html??? If my ImageView (what contains my image) get the full width and height, pulls down my HBox (what includes the buttons). If HBox were in absolute position, it wouldn't happened this, would it?
And the final problem, how can I make that, my HBox doesn't appear, just triggered by a hover effect. Is it possible with a separated css file? As I know, it is possible to make with FXML files.
Thanks for the answers!

Windows native File chooser in java

Apparently, there are (at least?) two different native File choosers on Windows (10). There is this one, which is used by JFileChooser and other programs:
And there is that one, for example used by Chrome:
I like it much more than the first one because:
You can directly enter your file path at the top
Your can search the folder
The direct access on the left contains the whole file tree
How do I get it in Java?
Use the JavaFX library
FileChooser fileChooser = new FileChooser();
fileChoose.showOpenDialog(null);
To run it in a swing context, have a look at those two answers.
PlatformImpl.startup(() -> {
FileChooserd = new FileChooser();
d.showOpenDialog(null);
});
new JFXPanel();
Platform.runLater(() -> {
FileChooser d = new FileChooser();
d.showOpenDialog(null);
});
Note that other things like modality won't work when mixing JavaFX and Swing. Also, you will have to build some code that waits until the Runnable has finished to be able to fetch the results.
Use a special library
native file dialogs provides native file dialogs, and LWJGL 3 provides Java bindings for this library.

Setting the background of a GridPane (with or without JavaFx Scene Builder)

I'm new to javafx and I am trying to set the background of a GridPane to an image(, or behind the GridPane). Setting the image in the fxml-file itself did not work. I tried to do this with the JavaFx Scene builder provided by oracle first and then later by manually adding this to the code with: <GridPane style="-fx-background-image: url('board.jpg' ); ..., but this resulted to nothing being changed when running the application.
I then resorted to setting the background image in the main-method and not the fxml-file. When I try to access the GridPane object (with getNamespace().get()) I get null back, so my problem here is that I can't seem to access the object to then set it's background to the image I want.
This what I tried most recently:
sample.fxml
<GridPane id="pain"...
main.java
FXMLLoader fxmlloader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = fxmlloader.load();
GridPane pane = (GridPane)fxmlloader.getNamespace().get("pain");
pane.setStyle("-fx-background-image: url('image.jpg');");
I already tried to find how to do this without success here:
JavaFX 2.0 + FXML - strange lookup behaviour
JavaFX How to set scene background image

Netbeans ImageIcon not displaying

I am using the NetBeans GUIBuilder to make a JPanel Form. I added a JLabel and used NetBeans' interface to give it an icon from an external image (.png). The path is verified and the image shows up on the GUIBuilder screen. It even shows up when I click the "Preview Design" button. It DOES NOT show up when I RUN the project. The rest of the GUI appears as it should. Do any of you know why this happening and/or how to fix it?
A lot of you have been asking for an SSCCE. Since the code is generated by the NetBeans Form Builder, I have instead included the steps I took to make the JLabel. The areas of focus are circled in red.
Drag and drop a JLabel into the Form Builder.
Open up the JLabel's properties menu. Enter the empty string ("") for the text field. Click the ellipsis next to icon.
Select External Image and click the ellipsis.
Select the image of choice. In my case it's a .png.
Notice that the image appears in the icon preview.
Close the icon menu and the properties menu, and notice that the image appears as the JLabel's icon on the Form Builder.
Thank you for accepting an unorthodox SSCCE and thank you in advance for your help.
I found out the hard way that relying on Netbeans GUI builder to do everything for you is a mistake.
Just create an icon fetching class like the one below, put the icons in it's package, and use "Custom code" instead of "Image chooser". Sure the icons will not be visible inside NB. But if they show up when the app is running, who cares about that.
package com.example.resource.icons;
import javax.swing.ImageIcon;
public class IconFetch {
private static IconFetch instance;
private IconFetch(){
}
public static IconFetch getInstance() {
if (instance == null)
instance = new IconFetch();
return instance;
}
public ImageIcon getIcon(String iconName) {
java.net.URL imgUrl = getClass().getResource(iconName);
if (imgUrl != null) {
return new ImageIcon(imgUrl);
} else {
throw new IllegalArgumentException("This icon file does not exist");
}
}
public static final String MINESWEEPER_ONE = "one.png";
}
Usage:
IconFetch.getInstance().getIcon(IconFetch.MINESWEEPER_ONE);
If the icon still doesn't show up after trying this, then something might be wrong with the way you layed out components in your form (the label is there but you can't see it).
Hope this helps even though it's a long shot.
I had the same problem, and predi's solution wasn't working either. Then I created a package instead of a folder, and added the images there, and it works now.
I do have a same problem also. But I found the solution.
I create the package in project and put the images inside there.
When I build the project, Netbeans will create 'target' folder and build .class files.
I found that the images that I copied to the package, did not transfer to the 'target' folder.
Interim solution.
4. I copy all image to target folder with the same structure. Then I can run the project directly from Netbeans.
5. Incase you clean the project. Do no.4 again.

JavaFX Application Icon

Is it possible to change the application icon using JavaFX, or does it have to be done using Swing?
Assuming your stage is "stage" and the file is on the filesystem:
stage.getIcons().add(new Image("file:icon.png"));
As per the comment below, if it's wrapped in a containing jar you'll need to use the following approach instead:
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("icon.png")));
Full program for starters :) This program sets icon for StackOverflowIcon.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class StackoverflowIcon extends Application {
#Override
public void start(Stage stage) {
StackPane root = new StackPane();
// set icon
stage.getIcons().add(new Image("/path/to/stackoverflow.jpg"));
stage.setTitle("Wow!! Stackoverflow Icon");
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Output Screnshot
Updated for JavaFX 8
No need to change the code. It still works fine. Tested and verified in Java 1.8(1.8.0_45). Path can be set to local or remote both are supported.
stage.getIcons().add(new Image("/path/to/javaicon.png"));
OR
stage.getIcons().add(new Image("https://example.com/javaicon.png"));
Hope it helps. Thanks!!
I tried this and it totally works. The code is:
stage.getIcons().add(
new Image(
<yourclassname>.class.getResourceAsStream( "icon.png" )));
icon.png is under the same folder as the source files.
If you have have a images folder and the icon is saved in that use this
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("/images/comparison.png")));
and if you are directly using it from your package which is not a good practice use this
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("comparison.png")));
and if you have a folder structure and you have your icon inside that use
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("../images/comparison.png")));
you can add it in fxml. Stage level
<icons>
<Image url="#../../../my_icon.png"/>
</icons>
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("/icon.png")));
If your icon.png is in resources dir and remember to put a '/' before otherwise it will not work
What do you think about creating new package i.e image.icons in your src directory and moving there you .png images? Than you just need to write:
Image image = new Image("/image/icons/nameOfImage.png");
primaryStage.getIcons().add(image);
This solution works for me perfectly, but still I'm not sure if it's correct (beginner here).
stage.getIcons().add(new Image(ClassLoader.getSystemResourceAsStream("images/icon.png")));
images folder need to be in Resource folder.
stage.getIcons().add(new Image(<yourclassname>.class.getResourceAsStream("/icon.png" )));
You can add more than one icon with different sizes using this method.The images should be different sizes of the same image and the best size will be chosen.
eg. 16x16, 32,32
You can easily put icon to your application using this code line
stage.getIcons().add(new Image("image path") );
stage.getIcons().add(new Image("/images/logo_only.png"));
It is good habit to make images folder in your src folder and get images from it.
I used this in my application
Image icon = new Image(getClass().getResourceAsStream("icon.png"));
window.getIcons().add(icon);
Here window is the stage.
If you run the jar file, the code specified by Michael Berry will change the icon in the title bar and in the taskbar. Shortcut icon cannot be changed.
If you run a native program compiled with com.zenjava, You must add a link to the program icon:
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
...
<bundleArguments>
<icon>${project.basedir}/src/main/resources/images/filename.ico</icon>
</bundleArguments>
</configuration>
</plugin>
This will add an icon to the shortcut and taskbar.
Toggle icons in runtime:
In addition to the responses here, I found that once you have assigned an Icon to your application by the first time you cannot toggle it by just adding a new icon to your stage (this would be helpful if you need to toggle the icon of your app from on/off enabled/disabled).
To set a new icon during run time use the getIcons().remove(0) before trying to add a new icon, where 0 is the index of the icon you want to override like is shown here:
//Setting icon by first time (You can do this on your start method).
stage.getIcons().add(new Image(getClass().getResourceAsStream("enabled.png")));
//Overriding app icon with a new status (This can be in another method)
stage.getIcons().remove(0);
stage.getIcons().add(new Image(getClass().getResourceAsStream("disabled.png")));
To access the stage from other methods or classes you can create a new static field for stage in you main class so can access it from out of the start() method by encapsulating in on a static method that you can access from anywhere in your app.
public class MainApp extends Application {
private static Stage stage;
public static Stage getStage() { return stage; }
#Override public void start(Stage primaryStage) {
stage = primaryStage
stage.getIcons().add(new Image(getClass().getResourceAsStream("enabled.png")));
}
}
public class AnotherClass {
public void setStageTitle(String newTitle) {
MainApp.getStage().setTitle(newTitle);
MainApp.getStage().getIcons().remove(0);
MainApp.getStage().getIcons().add(new Image(getClass().getResourceAsStream("disabled.png")));
}
}
If you got Invalid URL or resource not found put your icon.png in the "bin" folder in your workspace.
Another easy way to insert your own icon on the title bar in JavaFX is to add the image to your primary stage using the following method:
Image ico = new Image("resources/images/iconLogo.png");
stage.getIcons().add(ico);
Make sure your import javafx.scene.image.Image (if using an ide like netbeans this should be automatically done for you).
I tried this and it works:
stage.getIcons().add(new Image(getClass().getResourceAsStream("../images/icon.png")));

Categories

Resources