JavaFX ImageView gif keeps starting over too early - java

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).

Related

Image won't show up in JavaFX [duplicate]

This question already has an answer here:
How to load images from URL in JavaFx if recieving HTTP Error 403 [duplicate]
(1 answer)
Closed 5 years ago.
I've been trying for a while now, following various documentations but I just cannot get any images to show up on JavaFX.
Here is my code:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
//stage and stuff
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
//images
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class KingsGame extends Application {
public static ImageView iv = new ImageView();
Button btn = new Button();
public static Image test = new Image("http://puu.sh/vOk8i/754c8fee68.png");
#Override
public void start(Stage primaryStage) {
//stackpane
StackPane root = new StackPane();
root.getChildren().add(iv);
//scene
Scene scene = new Scene(root, 1280, 720);
primaryStage.setTitle("test program lol");
primaryStage.setScene(scene);
primaryStage.show();
//---actual game---
drawMainMenu();
}
public void helloTest() {
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
}
public static void drawMainMenu() {
iv.setImage(test);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Whenever I run the program, all I get is this: http://puu.sh/vOko6/b669cfc20b.png
The strange thing is, when I initially tested this, I used this (https://osu.ppy.sh/ss/8062698) image link as my test image and it somehow worked even though there wasn't even a .jpg or .png extension. It was a game screenshot and I simply just used the link the game gave me to test. When I switched it to another test link, it just broke.
How can I get ALL image links to work?
It looks like an access problem.
If you print the exception returned with this instruction :
System.err.println(test.getException());
you get this :
java.io.IOException: Server returned HTTP response code: 403 for URL: http://puu.sh/vOk8i/754c8fee68.png
The site probably authorizes only the browser clients

Listing all available system fonts in a Choice Box

I have a scene with a choice box. the aim is to get all available system fonts to display in the choice box, I kinda feel I'm on the right path as so far I have managed to get 1 to display in the choice box, but why just the 1?
here is the code -
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
public class ChoiceBoxFonts extends Application
{
ObservableList<String> fontType;
ChoiceBox<String> fonts;
public static void main(String [] args)
{
Application.launch(args);
}
public void start(Stage primaryStage)
{
Pane root = new Pane();
Font.getFamilies().stream().forEach(i ->{
fontType =
FXCollections.observableArrayList(i
);
});
// New choicebox with observable arraylist fontType
fonts = new ChoiceBox<String> (fontType);
//SingleSelectionModel<String> selMod = fonts.getSelectionModel();
root.getChildren().add(fonts);
Scene scene = new Scene(root,200,200);
primaryStage.setScene(scene);
primaryStage.show();
}
}
The goal of the experiment is to be able to select a font from the choice box and change the font of a text object with that selection.
Also, is there a better UI to be able to do such a thing? If there are a bucket load of fonts, that choice box is going to be very long!
You just need
fontType = FXCollections.observableArrayList(Font.getFamilies());
instead of the iteration you have.
If there are a bucket load of fonts, that choice box is going to be very long!
I would probably consider a ListView.

Smooth panning with JavaFX

I have a MacBook Pro with a touch enabled trackpad. When I open a large image with the Mac preview app I can let the image slide softly over the screen with a two finger swipe gesture. Now I would like to do the same inside a JavaFX app (see code below). In principle this seems to work but the movement is not smooth. The image jumps in roughly 10 pixel increments which just looks ugly. I experimented with the JavaFX gestures but I did not get it to move smoothly. Can anybody tell me whether this is possible with JavaFX at all and if yes how to do that?
package jfxfeatures.control.scrollpane;
import java.io.File;
import java.net.MalformedURLException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ScrollCanvas1 extends Application {
// Some large image in the order of 4000x3000 pixels.
private final static File file = new File("some large image file here");
ScrollPane scrollPane;
#Override
public void start(Stage primaryStage) {
try {
Image image = new Image(file.toURI().toURL().toExternalForm());
Canvas canvas = new Canvas(image.getWidth(), image.getHeight());
canvas.getGraphicsContext2D().drawImage(image, 0, 0);
scrollPane = new ScrollPane();
scrollPane.setPannable(true);
scrollPane.setContent(canvas);
BorderPane root = new BorderPane();
root.setPrefSize(1200, 800);
root.setCenter(scrollPane);
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

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()

50 MB increase in memory consumption on displaying an Image

I have a JavaFX application (Swing users input might also help) which is Image gallery basically. It watches a folder, and as soon as any Image is added, the Image is displayed on the screen.
Sooner as more Images got added, the application memory consumption only grew bigger. On profiling, I have observed that on adding an Image (size 1.3 MB), memory consumption increased by about 50 MB. The class that holds Image is a simple ImageView that holds an Image.
Does any one have similar experiences? The behavior is same on Windows & Mac
PS: I know any code here will help, but there is nothing much to be shown. As I said there is a List of ImageView which holds Image. List of ImageView is binded to another List say l1. On detecting an Image, image is added to l1 and so is added to the actual list which is displayed on screen
EDIT:
I just tried a sample code. I have observed that, on every Iamge it loads (2.3 MB in this case), there is a memory increase of 12 MB each:
package side;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Test extends Application {
public static void main(String... args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
ScrollBar bar = new ScrollBar();
bar.setOrientation(Orientation.VERTICAL);
final VBox box = new VBox();
Group root = new Group();
root.getChildren().addAll(box, bar);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Layout Sample");
primaryStage.show();
for (int ik = 0; ik < 6; ik++) {
System.out.println("1");
ImageView i = new ImageView();
InputStream is = new FileInputStream(new File("C:\\Users\\Jatin\\Documents\\BarcodeNew\\w.png"));
Image im = new Image(is);
i.setImage(im);
box.getChildren().add(i);
is.close();
}
//r.close();
}
}
Found two issues:
I wasn't closing my stream.
From this
Remember that the file size of a PNG image and the memory consumption of an uncompressed image in memory are very different.
On specifying the size of the Image it all works well.

Categories