/* * Created on 21 Dec 2006 by Josef Garvi (www.edenfoundation.org) * Updated on 8 Dec 2009. */ package org.edenfoundation.swing; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.Dialog.ModalityType; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.border.EmptyBorder; public class MsgDlg { public static void main(String args[]) { ArrayList messages = new ArrayList(); messages .add("An updated version of this game named Railroad Tycoon Deluxe (RDX) was created and released in 1993. Despite a host of new features and graphics, RDX sold very poorly in stores, due to some bugs and slow gameplay (most notoriously the F4 map screen, which brings the game to a crawl).\r\n" + "

" + "RDX is essentially the same game as Railroad Tycoon, with improved hi-resolution graphics, new sound effects, and several additions. The additions are: new maps (South America and Africa) with region-specific cargo types (e.g. troops for Africa), new time ranges and locomotives, bandits who can hijack trains, and sheriffs who will arrest them.\r\n" + "

" + "Although the game is called Sid Meier's Railroad Tycoon Deluxe, Sid Meier himself had nothing to do with the development of this version."); messages .add("The original version allowed the player to start companies in several settings:
the U.S. West and Midwest or the Northeast, England, and (on a smaller scale including southern England) Europe."); messages.add("Quick & Dirty."); messages.add("Two lines,\nno html."); messages .add("A sequel featuring improved graphics and more complex gameplay, Railroad Tycoon II, was published by Gathering of Developers in 1998 after PopTop Software acquired rights to the name.\r\n" + ""); int x = 0; for (String m : messages) { MsgDlg.question(null, m, JOptionPane.YES_NO_CANCEL_OPTION); } JOptionPane.showMessageDialog(null, "This message is very long, and the fact that it doesn't wrap by itself can probably make a user slighly frustrated. I mean, not everyone uses wide screens. Some people work on netbooks, and well, they are spared reading quite some boring stuff. :-) So perhaps it's a feature, not a bug?", "Message fit for Big Screens", JOptionPane.INFORMATION_MESSAGE); } private static JComponent wrap(String s) { return wrap(s, null); } private static int getContentHeight(String content, int width) { JEditorPane dummyEditorPane = new JEditorPane(); dummyEditorPane.setSize(width, Short.MAX_VALUE); dummyEditorPane.setContentType("text/html"); dummyEditorPane.setText(content); return dummyEditorPane.getPreferredSize().height; } private static JComponent wrap(String message, String shortTitle) { int maxWidth = 400; int maxHeight = Toolkit.getDefaultToolkit().getScreenSize().height * 2 / 3; String htmlizedMessage = null; if (message.contains("

") || message.contains("

") || message.contains("
") || message.contains("
") || message.contains("
")) htmlizedMessage = message; else htmlizedMessage = message.replace("\n", "
"); int h = getContentHeight(htmlizedMessage, maxWidth); JPanel pnl = new JPanel(); pnl.setLayout(new BorderLayout()); JEditorPane text = new JEditorPane("text/html", htmlizedMessage); text.setBorder(null); text.setBackground(null); text.setEditable(false); int titleHeight = 0; if (shortTitle != null) { JLabel lblTitle = new JLabel(shortTitle); lblTitle.setFont(lblTitle.getFont().deriveFont( lblTitle.getFont().getSize() * 1.5f)); lblTitle.setBorder(new EmptyBorder(0, 0, 10, 0)); lblTitle.setMaximumSize(lblTitle.getPreferredSize()); titleHeight = lblTitle.getPreferredSize().height; pnl.add(lblTitle, BorderLayout.PAGE_START); } JScrollPane scroll = new JScrollPane(text); scroll.setBorder(null); scroll.setMaximumSize(new Dimension(maxWidth, maxHeight)); scroll.setPreferredSize(new Dimension(Math.min(maxWidth, text .getPreferredSize().width), Math.min(maxHeight, getContentHeight( htmlizedMessage, maxWidth)))); pnl.add(scroll, BorderLayout.CENTER); return pnl; } public static void error(Component owner, Throwable ex) { error(owner, ex, null); } public static void error(Component owner, Throwable ex, String title) { System.out.println("Error: " + ex.getMessage()); ex.printStackTrace(); if (ex.getMessage() == null) error(owner, ex.getClass().getName().substring( ex.getClass().getName().lastIndexOf('.') + 1), title); else error(owner, ex.getMessage(), title); } public static void error(Component owner, String message) { error(owner, message, null); } public static void error(Component owner, String message, String title) { JOptionPane.showMessageDialog(owner, wrap(message, "Error Encountered:"), title == null ? "Error" : title, JOptionPane.ERROR_MESSAGE); } public static void alert(Component owner, String message) { alert(owner, message, null); } public static void alert(Component owner, String message, String title) { JOptionPane.showMessageDialog(owner, wrap(message), title == null ? "Warning" : title, JOptionPane.WARNING_MESSAGE); } public static void information(Component owner, String message) { information(owner, message, null); } public static void information(Component owner, String message, String title) { JOptionPane.showMessageDialog(owner, wrap(message), title == null ? "Information" : title, JOptionPane.INFORMATION_MESSAGE); } public static void information(Component owner, Object[] messages) { generic(owner, JOptionPane.INFORMATION_MESSAGE, "Information", true, messages); } public static int question(Component owner, String message, int answerOptions) { return question(owner, message, null, answerOptions); } public static int question(Component owner, String message, String title, int answerOptions) { return JOptionPane.showConfirmDialog(owner, wrap(message), title == null ? "Question" : title, answerOptions, JOptionPane.QUESTION_MESSAGE); } public static void generic(Component owner, int messageType, String title, boolean modal, Object... messages) { JOptionPane optionPane = getNarrowOptionPane(50); Object[] msgParam = new Object[messages.length]; for (int i = 0; i < messages.length; i++) { if (messages[i] instanceof String) { msgParam[i] = wrap((String) messages[i]); } else msgParam[i] = messages[i]; } optionPane.setMessage(msgParam); optionPane.setMessageType(messageType); JDialog dialog = optionPane.createDialog(owner, title); dialog.setResizable(true); dialog.setTitle(title); if (!modal) { dialog.setModalityType(ModalityType.MODELESS); dialog.setAlwaysOnTop(true); } FrameExtra.centerOnWindow(FrameExtra.ancestorOfComponent(owner), dialog); dialog.setVisible(true); } private static JOptionPane getNarrowOptionPane(int maxCharactersPerLineCount) { // Our inner class definition class NarrowOptionPane extends JOptionPane { int maxCharactersPerLineCount; NarrowOptionPane(int maxCharactersPerLineCount) { this.maxCharactersPerLineCount = maxCharactersPerLineCount; } @Override public int getMaxCharactersPerLineCount() { return maxCharactersPerLineCount; } } return new NarrowOptionPane(maxCharactersPerLineCount); } public static void registerDefaultExceptionHandler() { Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { error(null, e); } }); } }