JavaFX Splash sceen with GIF - javafx

Recently I have developed a personal software to help me with my daily schedule. I have tried to have a splash screen of Homer Simpson eating, as a cool startup splash screen, But unfortunately the GIF won't play.
here is the whole code
public class Homer extends Application
{
public static final String SPLASH_GIF =
"https://media.giphy.com/media/JRQ1PegFVKXBu/giphy.gif";
private static final int SPLASH_WIDTH = 400;
private static final int SPLASH_HEIGHT = 224;
private Pane splashLayout;
public static void main(String[] args) throws Exception
{ launch(args); }
#Override
public void start(final Stage initStage) throws Exception {
ImageView splash = new ImageView(new Image(
SPLASH_GIF
));
splashLayout = new Pane();
splashLayout.getChildren().add(splash);
Scene scene = new Scene(splashLayout, SPLASH_WIDTH, SPLASH_HEIGHT);
scene.setFill(Color.TRANSPARENT);
initStage.initStyle(StageStyle.TRANSPARENT);
initStage.setWidth(SPLASH_WIDTH);
initStage.setHeight(SPLASH_HEIGHT);
initStage.setScene(scene);
initStage.show();
System.out.println("finished");
}
}
Having the picture format to be switched to PNG as following will work
public static final String SPLASH_GIF =
"http://www.dashboardwidgets.com/showcase/data/43/homerQuotes-1p2f.png";
It will result in just a simple picture of Homer, not eating a banana. I would like to have it with a GIF.
How can it be possible?

When trying your example, I can put it down to a
com.sun.javafx.iio.ImageStorageException: No loader for image data
If I use a different URL with an animated gif that is loaded by http and not by https (http://www.picgifs.com/music-graphics/music-graphics/beatles/music-graphics-beatles-186070.gif) and there the ImageView is working.
I also downloaded Homer with the banana and saved it and loaded it with
final ImageView imageView = new ImageView(new Image("file:JRQ1PegFVKXBu.gif"));
The ImageView works al right with that.
I found no hint in the JavaFX API that https is not supported, but it would be better anyway to not do a download in you startup splashscreen, as this might take to long.

Failure is because the source link is to an html file not a gif file
The issue is that the link in some Folk's question is not actually an image (even though the url ends in .gif), it is instead a HTML page or a redirect to a HTML page (you can see this by loading the link in a browser).
If you replace the html link:
https://media.giphy.com/media/JRQ1PegFVKXBu/giphy.gif
with the actual GIF link:
https://i.giphy.com/JRQ1PegFVKXBu.gif
then the GIF image loading and display works as expected.
Aside on protocol support for image loading
Actually the issue isn't https related. The JavaFX API does implement loading images via https correctly. According to the Image javadoc:
All URLs supported by URL can be passed to the constructor. If the passed string is not a valid URL, but a path instead, the Image is searched on the classpath in that case.
The underlying JavaFX image implementation just opens a stream from the URL class (which can be determined by searching the JavaFX source code). So any protocol supported by the underlying JRE implementation will work with the JavaFX image class. This includes http:, https:, file: and jar: protocols; and may include others depending upon the JRE implementation. You can even add custom protocol handlers if you wish.

Related

Issue creating button in which opens a window/stage

Im having issues with understanding what should be the model in my ViewLoader statement while making a JavaFXML MVC project
I have a button on the main menu in which when the user clicks it will take me to another window called known as the build menu.
Ive tried a multitude of possible models that I think would work including getBuild etc.
https://imgur.com/Ubz43CI
Here is a screenshot of my Controller and View file
https://imgur.com/0C3FUG3
Here is a screenshot of my Model file
The expected result based off a similar project ive found online is that when the button is clicked a new window pops up. Im assuming the reason this doesnt work is because the getBuild method/statement needs to be initialised in the Controller class however I am unsure as of how to do that as getBuild is a method in my Model class
If you are only Navigating from one scene (window) to another the code is as listed below. Why do you think you need to have a MVC pattern to do this is is confusing.
Here is the code to go from one scene to another we name all our Anchor Pane's somenamePane so we know where we are and where we are going.
public void goTO() throws IOException, SQLException{
stage = (Stage)paneStart.getScene().getWindow();// pane you are ON
ckbookPane = FXMLLoader.load(getClass().getResource("manager.fxml"));// pane you are GOING TO
Scene scene = new Scene(ckbookPane);// pane you are GOING TO
scene.getStylesheets().add(getClass().getResource("checkbook.css").toExternalForm());
stage.setScene(scene);
stage.setTitle("Check Book Manager");
stage.show();
stage.sizeToScene();
stage.centerOnScreen();
}

Run logic after window is shown

I have a small program which gets called by another program, downloads/renames some files and closes itself afterwards. I want to show the user the progress with some simple text. My problem is, that the logic of the code runs before the view is completely shown. The window is visible but the content (in this case the sample text) is not.
I have already tried setOnShown() (as seen in my example) or setOnShowning(). I also tried not using a fxml file for the layout. But nothing seems to work.
public void start(Stage primaryStage) throws Exception {
HBox root = new HBox();
Text t = new Text();
t.setText("sample Text");
root.getChildren().add(t);
Scene scene = new Scene(root, 300, 275);
primaryStage.setTitle("FXML Welcome");
primaryStage.setScene(scene);
primaryStage.setOnShown(e -> {
updaterLogic(); //do some work
});
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void updaterLogic(){
try {
Thread.sleep(10 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
I want the view to be completed before running the actual logic. How can i archieve this?
To execute something after a window has been shown you can:
Listen for a WindowEvent.WINDOW_SHOWN event.
See Window.onShown and Window.addEventHandler
Listen to the Window.showing property and react when it changes to true.
Put the code after the call to show().
But not showAndWait() as that method doesn't return until the window is closed (and is illegal to call on the primary stage).
However, how to do this is not your problem (you're already using onShown). Your problem is caused by how you execute the "updater logic". Inside your updaterLogic() method you are calling Thread.sleep (simulating work). Since event handlers are executed on the JavaFX Application Thread that causes said thread to block. While the FX thread is blocked it can't do anything related to the GUI (e.g. layout passes, trigger rendering pulses, process user events, etc...)—thus the frozen window with no content rendered.
Move the "updater logic" onto a background thread so that the FX thread remains free to do its work. For general information about concurrency in Java, see Lesson: Concurrency and the java.util.concurrent package. For JavaFX specifics, see Concurrency in JavaFX, the javafx.concurrent package, and Platform.runLater(Runnable).
Here are two golden rules of JavaFX:
You must never block, nor execute long running work on, the JavaFX Application Thread.
You must always access and modify a live scene graph on the JavaFX Application Thread.
This is documented by Node:
Node objects may be constructed and modified on any thread as long they are not yet attached to a Scene in a Window that is showing. An application must attach nodes to such a Scene or modify them on the JavaFX Application Thread.
Note: Some nodes, such as WebView, must be created on the FX thread; this will be documented as appropriate.

Avoid back button using vaadin

I develop RIA application using Vaadin CDI addon.
About the app : it has two views(viewA and viewB) which maintained by Navigator.
User story is pretty simple:
User enters viewA
Perform some business stuff
Redirects to viewB
Using address bar to go some external website(ex. google.com)
Press back and it goes to he lastest page what he saw(viewB), instead of viewA
Any suggestions/tips-n-tricks how to avoid redirecting to viewB, but redirect to viewA?
Vaadin Forum quiet about this thing.
Thank you
I had same problem but resolved using following code:
getUI().getNavigator().addViewChangeListener(new ViewChangeListener() {
public boolean beforeViewChange(ViewChangeEvent event) {
return changeView;
}
#Override
public void afterViewChange(ViewChangeEvent event) {
// TODO Auto-generated method stub
}});
Set changeView = true only through proper navigation's (eg: On button clicks).
This how you can avoid navigation's using browser back button. In this case if user uses any of browser buttons the view does not changes and it remains on same page.
You could override View.enter(...) in your ViewB, and, according to your application state, update your view URI using Page.getCurrent().setUriFragment(recentUrl, false);

GWT: Open link from with an iFrame in the parent window (not a new tab)

I've an iframe embedded in an webpage. The iFrame is a GWT webapp and I would like to open a link from within the iFrame on the parent window, i.e. the page that embeds the iframe, and neither in a new tab nor in a new window.
Therefore, I searched the net and found for instance this suggestion: GWT-Button acting as hyperlink
So, therfore I modified my code the following way:
#Override
public void onClick(ClickEvent event) {
if(event.getSource() == myButton)
getURL("http://www.example.com");
}
public static native String getURL(String url)/*-{
return $wnd.open(url, 'target="_top"')
}-*/;
I also tried target="_top", target="_parent", target=_top and target=_parent (the two latter cases are without a surrounding ") since this was suggested in the different sources I found. However, each suggestions continues to open a new tab rather than opening the page in the same window.
So, what do I have to do in order to open the link in the same window?
UPDATE: I've noticed that a new tab gets opened everytime I click on the link even if i open the iframes content in it's own window, i.e. even if I do not use an iframe at all.
Okay, I solved it differently:
String url = "http://www.example.com";
HTML link = new HTML("Bla bla");
This works fine.

Can you have a loader without fragments

Very basic loader question.
My WIMMOne watch uses Android 2.1 (version 7).
There are no orientation changes, etc. with a watch. The small screen does not have room for any layout changes. So no need to deal with any kind of layout change.
The app I am working on now simply reads from a cursor, and displays an open ended scrolling list. My first app had a fragment and that was a pain. So I decided since I don't need fragments I will do away with the complexities of fragments.
I START WITH:
public class PhoneListActivity extends Activity
implements LoaderManager.LoaderCallbacks <Cursor>;
THEN:
protected void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
setContentView(R.layout.phone_list_activity);
FINALLY:
getLoaderManager().initLoader(0, null, this);
BUT:
Because it is 2.1 I need to use:
getSupportLoaderManager().initLoader(0, null, this);
BUT: -
That generates compile errors, so I need to use:
public class PhoneListActivity extends FragmentActivity . . . (not just Activity)
BUT: -
It immediately crashes on load in the ContentProvider.
Postings in various sites refer to "Activities and ActivityFragments".
SO: QUESTION 1: Can my main class use "extends FragmentActivity" without setting up a separate fragment (ie: leave it just as an Activity).
QUESTION 2: If not, does that mean that to use a loader I must set up a separate fragment and deal with the issues of fragments?
Many thanks,
Clark
The answer is YES.
I redid part of the program and it now works without using fragments. It has the open ended scrolling being loaded from a cursor and basically the same structure above
I think something in handling my cursor was causing it to crash.
Clark

Resources