JavaFX app icon fails to show 9/10 times - java

I have an application which opens absolutely fine, but am having trouble setting an icon for it. The icon I give the path to is there, and changing to another imagine in that directory shows the icon 9/10 times, but this image never shows. There is always a question mark in it's place. So even on another file, which I know will work (ie. isn't corrupted), how come it only shows so rarely?
Below is the code of MyApplication.java
package MyApp;
import MyApp.Variables.Constants;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Forms/FormMain.fxml"));
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/img/appicon.png")));
primaryStage.setTitle("MyApp " + Constants.VERSION_NAME + " (" + Constants.RELEASE_ID + ")");
primaryStage.setScene(new Scene(root, 1000, 800));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Below is the project directory structure relating /img/ to Main.java:
I have tried all the solutions here but nothing fixed my issue.
Running on Ubuntu 16.04, intelliJ IDEA for the IDE, though the problem persists with an exported JAR file.

Loading Data from your disk is time consuming, so you be able to start loading the icon while the object is constructed. Place it in a constructor and save it in a instance member. Normally you need to add more than one icon, because each platform needs it own sizes (for links and so on).
package MyApp;
import MyApp.Variables.Constants;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Main extends Application {
private Image icon;
public Main() {
icon = new Image(Main.class.getResource("/img/appicon.png").toExternalForm());
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Forms/FormMain.fxml"));
primaryStage.getIcons().add(icon);
primaryStage.setTitle("MyApp " + Constants.VERSION_NAME + " (" + Constants.RELEASE_ID + ")");
primaryStage.setScene(new Scene(root, 1000, 800));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
My icon was this:
and the app structure in Netbeans looks like that:
and the running app look like that:

Related

javac not finding another compiled class in current folder

I'm using OpenJDK11.
I have two Java files in the current folder, that are supposed to run together to be a JavaFX application.
One of them is called Main.java and runs the main window. Another is Alert.java, and is supposed to run an alternate window which is an alert type.
Now, I ran the following command:
javac -cp "c:\projects\java\currentProject" --module-path "c:\Program Files\Java\javafx-sdk-11.0.1\lib" --add-modules=javafx.controls,javafx.fxml Alert.java Main.java
While Alert.java compiled just fine, Main.java could not import the Alert class and gave an error on "import Alert". I tried "import Alert.Alert" and "import currentProject.Alert" but still, it didn't work.
Also, I declared package "package currentProject" at the start of each file and it still gave an error.
What am I supposed to do to get it running? I already failed on installing JavaFX on all available IDEs, so I'm not going to use an IDE other than Atom. But how do I compile it properly?
more info -
file structure:
c->projects->java->economicManager->( Alert.java ,Main.java, financialManager.fxml, alert.fxml, Alert.class, Alert$Controller.class, Main.class [previously compiled version])
Alert.java:
package financialManager;
import javafx.stage.Stage;
import javafx.stage.Modality;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import java.util.Map;
public class Alert {
public Stage stage;
private Controler_Class controler;
public Alert(Parent root) {
Controler_Class clas = new Controler_Class(root);
this.controler = clas;
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("financial report");
stage.setScene(scene);
this.stage = stage;
stage.showAndWait();
}
private class Controler_Class{
Parent root;
public Controler_Class(Parent root){
}
}
}
Main.java:
package financialManager;
import Alert;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import java.util.Map;
public class Main extends Application{
#Override
public void start(Stage stage) throws Exception{
final int width = 300;
final int height = 450;
stage.setTitle("hello mofos");
FXMLLoader loader = new FXMLLoader(getClass().getResource("financialManager.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, width, height);
Map<String, Object> mapper = loader.getNamespace();
AnchorPane pane = (AnchorPane) mapper.get("splitpane1_anchorpane");
if(pane != null)
SplitPane.setResizableWithParent(pane, false);
else
System.out.println("it's null you idiot!");
Button btn = (Button) mapper.get("economicReport");
btn.setOnMouseClicked((event) -> {
FXMLLoader loader2 = new FXMLLoader(getClass().getResource("alert.fxml"));
Parent parent = loader2.load();
Alert alert = new Alert(parent);
});
/*
ChangeListener<Number> stageSizeListener = (observable, oldValue, newValue) ->
pane.setDividerPositions(0.20219435736677116);
stage.widthProperty().addListener(stageSizeListener);
stage.heightProperty().addListener(stageSizeListener);
*/
stage.setScene(scene);
stage.show();
}
public static void main(String[] args){
launch();
}
}
I see that you are importing the Alert class wrongly. Your package is financialManager, so you should use it in the import line like this:
import financialManager.Alert;
About your issues with IDEs, I made JavaFX work fine with Eclipse and IntelliJ on OpenJDK 11 without any issues a few days ago - For OpenJDK you will need OpenJFX, and if you are interesting in some reading, this is the link from Oracle's blog on their plans for JavaFX.
Good luck!

JavaFX ImageView gif keeps starting over too early

I am trying to display a gif but if the gif is "too long" it for some reason just starts over instead of displaying the whole animation.
I am currently just using this plain code (for testing without any other code interfering) and it won't work:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Group popup = new Group();
Image image = new Image("https://image.ibb.co/hUMzWU/1.gif");
ImageView view = new ImageView(image);
popup.getChildren().add(view);
Scene dialogScene = new Scene(popup);
primaryStage.setScene(dialogScene);
primaryStage.setTitle("Testing Gif Stuff");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
An example for such an image would be: https://img2.picload.org/image/dlldgogw/7.gif
For me it keeps "resetting" right when his arms enter the picture. Any help is appreciated. Using Java 10. Loading from disk or from internet makes no difference.
Some other gifs that won't work either:https://image.ibb.co/jhhsJ9/ae221412fcd5235a.gif (broken as hell)
https://image.ibb.co/fyhL5p/1664d3a95ec06cfd.gif
https://image.ibb.co/hH4NJ9/0beec1ba838fabd2.gif
File size does not seem to be the main issue because the last gif is relatively small (900kb).

Full-screen Overlay

Currently, I am trying to create a timer that displays in the corner of your screen. I want it to show even if there is currently a full-screened application running. Currently I've tried Stage#setAlwaysOnTop(true), however that only functions for normal applications, not when they are full-screened.
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
stage.setTitle("Timer");
stage.setScene(new Scene(root, 300, 275));
stage.setAlwaysOnTop(true);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This is the standard JavaFX example with IntelliJ, however with the one modification which was Stage#setAlwaysOnTop(true). How would I get this to function ontop of the full-screen, or at least stay omnipresent no matter the application.

Swap JavaFX scene when clicking a button

I am trying to create a program to teach people about GNU/Linux and the command line, I have my main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
Stage window;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
primaryStage.setTitle("Learnix");
primaryStage.setScene(new Scene(root, 800, 500));
primaryStage.show();
}
}
And the controller to go with it.
package sample;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import java.io.IOException;
public class loginController {
public Button loginBtn;
public void loginBtnClick() throws IOException {
System.out.println("You are logged in");
}
}
I have tried things such as:
FXMLLoader.load(getClass().getResource("lessons.fxml"));
But I can't figure out how to get it to swap scenes. I have seen many tutorials on YouTube and it Stack Overflow but many of them have all of the JavaFX on the main.java and not in separate files as I am using scenebuilder.
Thank you.
You can either call Stage.setScene() to change the whole scene or just substitute a root to the new one by Scene.setRoot():
Parent newRoot = FXMLLoader.load(getClass().getResource("lessons.fxml"));
primaryStage.getScene().setRoot(newRoot);

JavaFX ScrollPane doesn't fill it's parent pane

I'm trying to learn JavaFX. To do so I've been attempting to make a text editor that includes multiple line text box support, as well as the possibility of having syntax highlighting down the road.
Currently, the biggest problem I've been facing is that the ScrollPane I've been encapsulating all my FlowPanes in won't resize according to the size of the Pane it's in. I've been researching this problem for about half a week now and simply cannot get the ScrollPane to just fill the window it's in. The code below displays a JavaFX stage that has working keyboard input and the ScrollPane is always the same size no matter what. Thanks to all in advance!
Here's my Main:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Launcher extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(new DynamicTextBox(),500,500));
primaryStage.show();
}
}
TextBox class:
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
public class DynamicTextBox extends Pane {
//currentLinePane is made to handle all the direct user inputs
//multiLinePane, while not really used yet will create a new line when the enter key is struck.
private FlowPane currentLinePane, multiLinePane;
private ScrollPane editorScroller;
public DynamicTextBox() {
super();
currentLinePane = new FlowPane(Orientation.HORIZONTAL);
multiLinePane = new FlowPane(Orientation.VERTICAL);
multiLinePane.getChildren().add(currentLinePane);
editorScroller = new ScrollPane(multiLinePane);
editorScroller.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
editorScroller.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
editorScroller.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
configureInput(event);
}
});
super.getChildren().add(editorScroller);
editorScroller.requestFocus();
}
private void configureInput(KeyEvent event) {
currentLinePane.getChildren().add(new Text(event.getText()));
}
}
You're using
ScrollPane.ScrollBarPolicy.AS_NEEDED
which, according to the docs at Oracle, "Indicates that a scroll bar should be shown when required." Instead, use
ScrollPane.ScrollBarPolicy.ALWAYS
alternatively, recall these are constants. you can get the height of the parent using boundsInParent: https://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#boundsInParentProperty
alternatively, you can use getParent() to get the parent and then get its height using computeMinWidth() https://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#getParent()

Categories