How does NetBeans' Splash Screen feature work? - java

New to NetBeans and just noticed that in the File >> Project Properties >> Application dialog there is a text field labeled Splash Screen that allows you to specify a path to an image that you would like displayed when your program is launching.
I want to customize the way my splash screen works (adding a progress bar, etc.) and would like to code it from the ground up but don't know where to start. What are the best practices for Java/Swing-based splash screens?
Thanks for any and all input!

The project properties -> Application -> Splash Screen allows you to add an image to an application. This property sets a value in the MANIFEST.MF called SplashScreen-Image: e.g. SplashScreen-Image: META-INF/GlassFish316x159.jpg This property will automatically cause the image to display as a splash screen. It does not work inside NetBeans, and must be run outside the IDE.
There is a tutorial Splash Screen Beginner Tutorial that details how to use it more detail. The tutorial was done for NetBeans 6.8, but will work on 7.2.1 which is the latest at the time of this post.

I'm not sure how NetBeans does it, but Splash Screens are supported by the JRE since version 6. See http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/splashscreen/

Splash screen is just a instance of java.awt.Window or undecorated javax.swing.JFrame.
To create window just say new Window(null), then set size and position (using tookit you can calculate where the screen center is) and then say window.setVisible(true)
Due to this is your own window you can do what you want: set layout, image, add process bar to the SOUTH etc.
You can also use JFrame: new JFrame().setUndecorated(true)`

There are a couple of ways to do this.
To do a simple splash screen (an image) you can specify this in the command line of you java application.
Here is a simple example
java -splash:<file name> <class name>
However, if you want a progress bar, you are going to have to do something a little more complicated, and write some code yourself. This is done in the following way.
Create a JWindow (or Window or undecorated JFrame) component with your splash screen elements
Set it to visible
Do the rest of your Swing GUI startup code
Set your JFrame to visible, then immediately follow with setting the JWindow to visible(false)
This should show the splash almost immediately, and then hide once the your application is fully loaded.
To see some splash screen code, take a look here. The implementation in the link only shows how to achieve what you can with the -splash command, but it will give you a good start to also include the progress bar that you requested.

I hope this helps you, it is a small example of how to create yourself a simple splash screen using a dummy Progress Bar:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SplashScreen extends JWindow
{
private static JProgressBar progressBar = new JProgressBar();
private static SplashScreen execute;
private static int count;
private static Timer timer1;
public SplashScreen()
{
Container container = getContentPane();
container.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new javax.swing.border.EtchedBorder());
panel.setBackground(new Color(255,255,255));
panel.setBounds(10,10,348,150);
panel.setLayout(null);
container.add(panel);
JLabel label = new JLabel("Hello World!");
label.setFont(new Font("Verdana",Font.BOLD,14));
label.setBounds(85,25,280,30);
panel.add(label);
progressBar.setMaximum(50);
progressBar.setBounds(55, 180, 250, 15);
container.add(progressBar);
loadProgressBar();
setSize(370,215);
setLocationRelativeTo(null);
setVisible(true);
}
public void loadProgressBar()
{
ActionListener al = new ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
count++;
progressBar.setValue(count);
if (count == 50){
timer1.stop();
execute.setVisible(false);
//load the rest of your application
}
}};
timer1 = new Timer(50, al);
timer1.start();
}
public static void main (String args[]){
execute = new SplashScreen();
}
}
Cheers!

Also consider to build your application on top of the NetBeans Platform (a Swing-based RCP). One of the many benefits: it comes with a customizable splash screen with progress bar.
Sample progress bar:
http://platform.netbeans.org/tutorials/nbm-paintapp.html#wrappingUp
Port a Swing application to the NetBeans Platform:
http://platform.netbeans.org/tutorials/60/nbm-porting-basic.html
Further links:
http://netbeans.org/features/platform/index.html
http://netbeans.org/features/platform/all-docs.html

If your application is build using NetBeans Platform, then here's a tutorial about splash screen customisation: http://wiki.netbeans.org/Splash_Screen_Beginner_Tutorial

There is a sample Javafx equivalent of Splash screen. However this splash screen is basically a java swing applet that is called from javafx to be displayed to the user and simulates more or less eclipse and netbeans splash screen using progress bar and titles for the loaded contents. This is the link.
You must be able to get the code and separate out the splash screen code written in java swings and use it for yourself.
This is a custom java swings splash screen. and hence to center the splash screen it uses the traditional
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = l.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2),
screenSize.height / 2 - (labelSize.height / 2));

Related

Windows disappearing behind a full screen undecorated JFrame

I have a JFrame which I am setting to be full screen like so:
JFrame frame = new JFrame();
frame.setSize(1920, 1080); // Resolution of the monitor
frame.setUndecorated(true);
frame.setVisible(true);
Problem is, any popups (e.g. JDialogs) spawned from this frame open up behind the frame and I can only access them by alt-tabbing to them.
Furthermore, I am running a two monitor setup with each monitor treated as a separate display. If any windows are opened on top of the JFrame, and I move my mouse cursor to the second monitor, the windows disappear behind the JFrame. This is on RHEL 6.4, so perhaps it's a Linux window management issue? It should also be noted that I am running without gnome-panel, so it's a completely bare Linux desktop (no menu bar, no task bar).
Things behave normally when my JFrame is decorated. That is, pop ups open on top of it and windows no longer disappear behind it when I move my mouse cursor to the second monitor.
It's only when I set the JFrame to be undecorated and full screen that windows start getting lost behind it. It's like Linux is "locking" the undecorated JFrame to the monitor. I can't alt-drag it in this state either.
If I set the JFrame to be slightly smaller than the monitor resolution (e.g. 1 pixel smaller), then it is no longer "locked". I can alt-drag it and windows no longer get lost behind it.
Is there any way to prevent windows from getting lost behind the full screen, undecorated JFrame?
I've tried all solutions listed here, but none of them work:
JFrame full screen focusing .
EDIT
The above problem happens when running under Java 7. Running under Java 8 fixes the dialog issue, but the screen crossing issue is still there.
Use the below code to solve the above mentioned issue
public static void setfullscreen(final JFrame frm)
{
frm.dispose();
/**`enter code here`
* Set the Frame as Undecorated
*/
frm.setUndecorated(true);
/**
* set the Frame's resize property as false
*/
frm.setResizable(false);
frm.requestFocus();
/**
* sets the frame as visible
*/
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
frm.setVisible(true);
}
}
);
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
frm.setBounds(0,0,screenSize.width, screenSize.height);
}
/**
* Close the Full Screen Mode
* #param frm
*/
public static void closeFullScreen(final JFrame frm)
{
frm.dispose();
frm.setUndecorated(false);
/**
* sets the frame as resize
*/
frm.setResizable(true);
/**
* sets the frame as visible
*/
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
frm.setVisible(true);
}
}
);
}
</i>

JFrame Icon Resolution

I'm quite new to working with java GUIs. To start me up, I had a look into JFrame. While playing around with it, I used the setIconImage() method to set the logo of my JFrame. However, when I run the file, the logo resolution gets reduced so much that I can barely recognise it. Here's my current code and the dimensions of my image is 1280 x 1280 (I have tried reducing it down to 100 x 100 but it still returned the same results.):
#SuppressWarnings("serial")
public class GUIManager extends JFrame{
public void openGUI(String value){
if(value.equalsIgnoreCase("startMenu")){
GUIManager manager = new GUIManager();
ImageIcon logo = new
ImageIcon(ResourcesLoader.class.getResource("Logo.png"));
manager.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
manager.setVisible(true);
manager.setResizable(false);
manager.setLocationRelativeTo(null);
manager.setSize(300, 500);
manager.setBackground(Color.WHITE);
manager.setTitle("FileLocker");
manager.setIconImage(logo.getImage());
} //value check
} //openGUI
} //GUIManager
The answer is given Before go to following link
Sizes of frame icons used in Swing
Which icon sizes to use with a JFrame's setIconImages() method?

Animated Splash Screen on Netbeans Platform app

Our maven/Netbeans platform application uses a custom image on startup, by replacing
Nbm-branding > core.jar > org.netbeans.core.startup > splash.gif
I tried making it an animated .gif, but only the first frame is displayed.
How would one possibly go about implementing an animated splash screen, maybe by running some JavaFX window animations?
I've seen another other SO question, but it wasn't really answered - please notice I'm asking about how to integrate a custom splash screen with my Netbeans Platform application, and not how to actually build it.
Surprisingly enough, I found out how to plug in a custom splash screen based on this post about user authentication and authorization.
Basically, one needs to write another start-up class, instead of the platform's default:
import java.lang.reflect.Method;
public class CustomStartup {
private static final String NB_MAIN_CLASS = "org.netbeans.core.startup.Main";
public static void main(String[] args) throws Exception {
// do whatever you need here (e.g. show a custom login form)
System.out.println("Hello world! I am a custom startup class");
JWindow splash = initSplash();
// once you're done with that, hand control back to NetBeans
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Class<?> mainClass = Class.forName(NB_MAIN_CLASS, true, classloader);
Object mainObject = mainClass.newInstance();
Method mainMethod = mainClass.getDeclaredMethod("main", new Class[]{String[].class});
mainMethod.invoke(mainObject, (Object) args);
splash.setVisible(false);
}
}
In that class, one can create a JavaFX stage, embed it into a JWindow, and show it:
public JWindow initSplash(){
JWindow window = new JWindow();
final JFXPanel fxPanel = new JFXPanel();
window.add(fxPanel);
window.setVisible(true);
window.setLocationRelativeTo(null);
Platform.runLater(new Runnable() {
#Override
public void run() {
Scene scene = new Scene(new CustomFxSplash(), 475, 300, true);
fxPanel.setScene(scene);
}
}
return window;
}
Other things to remember are:
Suppress the original NetBeans splash screen by running your app with the --nosplash parameter.
Call your custom initialization class by running your app with the -J-Dnetbeans.mainclass=com.package.splash.CustomStartup parameter
As the link suggests this custom class has to be on the platform's initialization classpath, meaning inside the platform/core folder.
The current version of the NetBeans class that is responsible for rendering the splash screen can be viewed online here: org.netbeans.core.startup.
The culprit code that prevents the gif from animating is this line (line 546)
graphics.drawImage(image, 0, 0, null);
In order for the gif to animate the ImageObserver will have to be specified instead of being set to null and then repaint must be called when imageUpdate() is called on the ImageObserver.
An example of displaying an animated gif can be viewed here: Relationship Between Animated Gif and Image Observer
So as far as I can see you will either have to change the above NetBeans platform code and rebuild it for your application or you will have to create your own splash screen from scratch to use instead of the NetBeans one.
Hope you find this useful!

I forget to stop a gui program and run it again. Now I can't close the first program without killing eclipse

I am working on a simple GUI app that just draws some graphics on a canvas. The environment is Vista 64. When I run the program, the Windows resize and minimize buttons work, but the close button doesn't. So I have to press the stop button in Eclipse to kill the program.
But sometimes I forget to press stop, and run the program again. The first instance gets stuck and I can't get rid of it without closing Eclipse. If I get careless I can end up with several java windows I can't close. Is there a way to get control of and close the windows? Also, why does the close button not work?
I doubt the code matters in this case but here it is:
import java.awt.*;
public class RobotFace extends Canvas{
/**
* #param args
*/
public static void main(String[] args) {
RobotFace c = new RobotFace();
c.setBackground(Color.white);
c.setSize(350, 350);
Frame f = new Frame();
f.add(c);
f.setLayout(new FlowLayout());
f.setSize(350,350);
f.setVisible(true);
}
public void paint(Graphics g){
g.setColor(Color.black);
int width = 150;
int height = 200;
g.drawRect((getWidth()-width)/2, (getHeight()-height)/2, width, height);
g.setColor(Color.gray);
g.fillRect((getWidth()-width)/2, (getHeight()-height)/2, width, height);
g.setColor(Color.white);
g.fillRect((getWidth()-80)/2, (getHeight()+50)/2, 80, 20);
g.setColor(Color.yellow);
g.fillOval((getWidth()-105)/2, (getHeight()-100)/2, 30, 30);
g.fillOval((getWidth()+45)/2, (getHeight()-100)/2, 30, 30);
}
}
You can also kill it using the console of eclips , there is a red button(right cornor) when you open console view in eclips.
To open console view
Window --> Show View --> Console
using this way you can close the Frame/window
//add window event adapter
f.addWindowListener(new MyWindowAdapter());
class MyWindowAdapter extends WindowAdapter{
MyWindowAdapter(){
}
//implement windowClosing method
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Your Eclipse console for the first application instance should still be available, just not visible. On the Console tab, you can click the toolbar button that looks like a little blue monitor to switch between application instances. To stop the first application instance, you would select that instance using the little blue monitor (it's called "Display Selected Console"), then click the "Stop" button.
One option is to change the behavior of your program so that it actually exits with the window is close (which is not the default behavior or Frames in Java.
The Frame javadoc specifies that it can generate WindowClosing events, which you can use to trigger your app to close (using a class like #Pratik does in their answer).
In my opinion, a better solution would be to replace your frame with a JFrame and use it's method f.setDefaultCloseOperation(EXIT_ON_CLOSE) so that you application with exit when the window is closed. JFrame is written such that it should be a drop in replacement for awt.Frame, but is part of the swing toolkit.

JInternalFrame acts weird when windows theme changed?

This is my sample code. I am trying to embed a JInternalFrame without titlebar display into a JFrame.
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameUI;
class A{
public void doThis(){
JFrame fr = new JFrame();
fr.setSize(300,300);
JInternalFrame f = new JInternalFrame();
f.setSize(200,200);
BasicInternalFrameUI ui = (BasicInternalFrameUI) f.getUI();
ui.setNorthPane(null);
f.setVisible(true);
fr.add(f);
fr.setVisible(true);
}
}
class MainA{
public static void main(String a[]){
A obj = new A();
obj.doThis();
}
}
The code works fine and displays a JInternalFrame within a JFrame without titlebar as per the requirement as shown below.
I still have this UI running and at the same time when I try to change my XP theme (via Properties>>Appearance>>Theme), the UI automatically repaints itself to show the JInternalFrame with a titlebar again as shown below.
I just can't understand this bizarre behavior. I have no clue if this is an issue with Java Swing or if it is something related to the OS. Please help me with this!
Why is the UI repainting upon theme change with an enabled titlebar when I explicitly code for the titleBar to be set as null?
PS: OS used is Windows XP and I am not sure if the same behavior is observed in Linux or other versions of Windows
'do' is a keyword in Java, so that code does not compile for me. This code does.
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameUI;
class A{
public void doIt(){
JFrame fr = new JFrame();
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setSize(300,300);
JInternalFrame f = new JInternalFrame();
f.setSize(200,200);
fr.add(f);
BasicInternalFrameUI ui = (BasicInternalFrameUI) f.getUI();
ui.setNorthPane(null);
f.setVisible(true);
fr.setVisible(true);
}
public static void main(String a[]){
A obj = new A();
obj.doIt();
}
}
Some notes/questions:
Swing GUIs should be constructed & altered on the EDT.
Why does the code add a JInternalFrame directly to anything other than a JDesktopPane?
There are slight issues with sizing of the JInternalFrame when changing themes. I suspect it has to do with the lack of validate()/pack() in the code. Since that was not the question, I could not be bothered investigating it further.
Results
I got a 'null result' here using Windows 7. The title bar of the JInternalFrame did not re-appear at any time when changing through (in order):
Forbidden Planet (a custom, simple theme)
Windows 7 (Aero)
Architecture (Aero)
Windows 7 Basic (Basic & High Contrast)
Windows Classic (Basic & High Contrast)
Forbidden Planet

Categories

Resources