Java: Custom Confirm Dialog and Splash Screen

Posted on

Java’s swing components library is loaded with many useful base components, especially when you need to create something quick. Although there usually comes a time when you want to do something so simple and yet it has to be complex to do so. This is a negative point on Java’s side in my expert opinion.

All I wanted to do was to create a JOptionPane with a specified width and height, that’s it. Nothing more and nothing less. I know that JOptionPane takes the preferred size of its sub-components, but I don’t want it to. I may have a component that is very big (like a text area or something similar) and I want to show it with scroll bars (no way!!) inside the JOptionPane and I do not want the JOptionPane to take up a quarter of the screen. So to do so I needed a good look at the Java 1.6.x source code for JOptionPane, Cocacola and some Acetaminophen or Paracetamol (for European readers.) The result was the code below all with complete Javadoc.

/**
 * <p>This is a wrapped method taken from the Java 1.6.x source code and modified to suite my
 * needs of a JOptionPane type functionality with the ability to specify dialog size instead
 * of it taking preferred sizes of components.</p>
 * <hr/>
 * 
 * <p>Brings up a dialog with a specified icon, where the initial choice is determined by the
 * <code>initialValue</code> parameter and the number of choices is determined by the
 * <code>optionType</code> parameter.</p>
 * 
 * <p>If <code>optionType</code> is <code>YES_NO_OPTION</code>, or
 * <code>YES_NO_CANCEL_OPTION</code> and the <code>options</code> parameter is
 * <code>null</code>, then the options are supplied by the look and feel.</p>
 * 
 * <p>The <code>messageType</code> parameter is primarily used to supply a default icon from
 * the look and feel.</p>
 * 
 * @param parentComponent
 *                determines the <code>Frame</code> in which the dialog is displayed; if
 *                <code>null</code>, or if the <code>parentComponent</code> has no
 *                <code>Frame</code>, a default <code>Frame</code> is used
 * @param message
 *                the <code>Object</code> to display
 * @param title
 *                the title string for the dialog
 * @param optionType
 *                an integer designating the options available on the dialog:
 *                <code>DEFAULT_OPTION</code>, <code>YES_NO_OPTION</code>,
 *                <code>YES_NO_CANCEL_OPTION</code>, or <code>OK_CANCEL_OPTION</code>
 * @param messageType
 *                an integer designating the kind of message this is, primarily used to
 *                determine the icon from the pluggable Look and Feel:
 *                <code>ERROR_MESSAGE</code>, <code>INFORMATION_MESSAGE</code>,
 *                <code>WARNING_MESSAGE</code>, <code>QUESTION_MESSAGE</code>, or
 *                <code>PLAIN_MESSAGE</code>
 * 
 * @return an integer indicating the option chosen by the user, or
 *         <code>CLOSED_OPTION</code> if the user closed the dialog
 * @exception HeadlessException
 *                    if <code>GraphicsEnvironment.isHeadless</code> returns
 *                    <code>true</code>
 * @see java.awt.GraphicsEnvironment#isHeadless
 */
public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, int width, int height) throws HeadlessException
{
	JOptionPane pane = new JOptionPane(message, messageType, optionType, null, null, null);
	pane.setInitialValue(null);
	if(parentComponent == null) {
		pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
	}
	else {
		pane.setComponentOrientation(parentComponent.getComponentOrientation());
	}

	JDialog dialog = pane.createDialog(parentComponent, title);
	dialog.setSize(width, height);
	dialog.setResizable(true);
	dialog.setVisible(true);
	dialog.dispose();

	Object selectedValue = pane.getValue();

	if(selectedValue == null) {
		return JOptionPane.CLOSED_OPTION;
	}
	else  if(selectedValue instanceof Integer) {
		return ((Integer) selectedValue).intValue();
	}
	else {
		return JOptionPane.CLOSED_OPTION;
	}
}

The next swing component I wish was made was a JSplashScreen. We see it all the time when we run applications and we always do everything we can to disable it after running the program more than once. And damn it, I want users to do the same with my applications 😀 With some more time and more Cocacola a component was created. Check it out below and hope it might be useful.

/**
 * <p>Displays a splash window with a message and for a specific amount of time.
 * The window size can be specified. Note that using this method implies some
 * default parameters such as using Sans Serif font, Bold, size 32.</p>
 * 
 * @see #showSplashWindow(String, Font, int, Dimension, Window)
 * @param message
 * 	- the text to display
 * @param duration
 * 	- how long to show the window
 * @param windowSize
 * 	- the size of the window
 */
public static void showSplashWindow(String message, int duration, Dimension windowSize) {
	showSplashWindow(message, new Font(Font.SANS_SERIF, Font.BOLD, 32), duration, windowSize, null);
}

/**
 * <p>Displays a splash window for a specific amount of time with a set of rendering parameters
 * for the message, font type, window size and frame owner.</p>
 * 
 * @param message
 * 	- the text to display
 * @param messageFont
 * 	- the font of text
 * @param duration
 * 	- how long to show the window
 * @param windowSize
 * 	- the size of the window
 * @param frameOwner
 * 	- the parent window or owner, null if none
 */
public static void showSplashWindow(String message, Font messageFont, int duration, Dimension windowSize, Window frameOwner) {
	JLabel saved = new JLabel(message);
	saved.setHorizontalAlignment(JLabel.CENTER);
	saved.setOpaque(true);
	saved.setFont(messageFont);

	final JWindow window = new JWindow(frameOwner);
	window.add(saved, BorderLayout.CENTER);
	window.setSize(windowSize);
	saved.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
	UITool.center(window);
	window.setVisible(true);

	Timer timer = new Timer(duration, new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent e) {
			window.setVisible(false);
			window.dispose();
		}
	});

	timer.setRepeats(false);
	timer.start();
}
Advertisements

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s