Reputation:
I see this question asked a lot but I have not seen a very general way of doing it. I am working on a Desktop app in Java Eclipse Oxygen using JavaFX and I have a loader that I want to show whenever and image is loading via http. An image has to be loaded via http when a user clicks on different rows. So I have my loader on top of the image and I just use; productPreviewLoader.setVisible(true)
to show it or hide it. The loader ImageView in fxml looks like this in GridPane.
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" valignment="TOP" vgrow="ALWAYS" />
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ImageView fx:id="productPreview" fitHeight="282.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
<!-- This is the loader-->
<ImageView fx:id="productPreviewLoader" fitHeight="112.0" fitWidth="136.0" pickOnBounds="true" preserveRatio="true" />
<TextFlow fx:id="productPreviewTextFlow" GridPane.rowIndex="1">
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin>
<padding>
<Insets bottom="30.0" left="10.0" right="10.0" top="30.0" />
</padding></TextFlow>
And the code that sets up the loader image looks like this;
//Set up the product preview image loader
BufferedImage bufferedImage;
File file = new File("resources\\images\\loaders\\img-loader-icon.gif");
try {
bufferedImage = ImageIO.read(file);
productPreviewLoader.setImage(SwingFXUtils.toFXImage(bufferedImage, null));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
productPreviewLoader.setVisible(false);
The image does not play in the ImageView. If it is not possible please show me another way of doing it. Also I am having a problem to get the ImageView to center the ImageView horizontally in the GridPane row. The GridPane resizes to match the height of it's parent whenever the window is resized. I know this is 2 questions but I would probably have ended up creating 2 questions.
Upvotes: 3
Views: 23264
Reputation: 2917
Well you haven't provide a complete example that I can use in order to show the use cases of how you can load an gif image to an ImageView so I will give you a full example :
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class GifViewerTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
VBox box = new VBox();
ImageView imageView = new ImageView();
box.getChildren().add(imageView);
Button localLoadButton = new Button("Local load");
Button externalLoadButton = new Button("URL Load");
localLoadButton.setOnAction(e -> {
imageView.setImage(new Image(this.getClass().getResource("java.gif").toExternalForm()));
});
externalLoadButton.setOnAction(e -> {
String imageSource = "https://cdn.dribbble.com/users/550761/screenshots/1773241/untitled-5.gif";
try {
imageView.setImage(createImage(imageSource));
} catch (IOException e1) {
e1.printStackTrace();
}
});
FlowPane buttonPane = new FlowPane();
buttonPane.setAlignment(Pos.CENTER);
buttonPane.getChildren().addAll(localLoadButton, externalLoadButton);
box.getChildren().add(buttonPane);
stage.setScene(new Scene(box, 500, 400));
stage.show();
}
private Image createImage(String url) throws IOException {
// You have to set an User-Agent in case you get HTTP Error 403
// respond while you trying to get the Image from URL.
URLConnection conn = new URL(url).openConnection();
conn.setRequestProperty("User-Agent", "Wget/1.13.4 (linux-gnu)");
try (InputStream stream = conn.getInputStream()) {
return new Image(stream);
}
}
}
If all your Images are loaded through URLs then why don't you just use a WebViewer and load the URL instead of using an ImageView? If the gif size is not small that will cause a GUI lag until the gif image is loaded from InputStream in that case you should create the loading process to a background thread but as I said you can avoid all that if you just use a WebViewer.
Upvotes: 2