// MessageDialogs.java package net.sf.gogui.gui; import java.awt.Component; import java.util.TreeSet; import java.util.Set; import java.util.prefs.Preferences; import javax.swing.Box; import javax.swing.JComponent; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import static net.sf.gogui.gui.I18n.i18n; import static net.sf.gogui.gui.GuiUtil.insertLineBreaks; import net.sf.gogui.util.Platform; import net.sf.gogui.util.PrefUtil; import net.sf.gogui.util.StringUtil; /** Simple message dialogs. */ public final class MessageDialogs { public MessageDialogs() { } public void showError(Component frame, String mainMessage, String optionalMessage) { showError(frame, mainMessage, optionalMessage, true); } public void showError(Component frame, String mainMessage, String optionalMessage, boolean isCritical) { int type; if (isCritical) type = JOptionPane.ERROR_MESSAGE; else type = JOptionPane.PLAIN_MESSAGE; Object[] options = { i18n("LB_CLOSE") }; Object defaultOption = options[0]; show(null, frame, "", mainMessage, optionalMessage, type, JOptionPane.DEFAULT_OPTION, options, defaultOption, -1); } public void showError(Component frame, String message, Exception e) { showError(frame, message, e, true); } public void showError(Component frame, String message, Exception e, boolean isCritical) { showError(frame, message, StringUtil.getErrorMessage(e), isCritical); } public void showInfo(Component frame, String mainMessage, String optionalMessage, boolean isCritical) { showInfo(null, frame, mainMessage, optionalMessage, isCritical); } public void showInfo(String disableKey, Component frame, String mainMessage, String optionalMessage, boolean isCritical) { if (checkDisabled(disableKey)) return; int type; if (isCritical) type = JOptionPane.INFORMATION_MESSAGE; else type = JOptionPane.PLAIN_MESSAGE; Object[] options = { i18n("LB_CLOSE") }; Object defaultOption = options[0]; show(disableKey, frame, "", mainMessage, optionalMessage, type, JOptionPane.DEFAULT_OPTION, options, defaultOption, -1); } public int showYesNoCancelQuestion(Component parent, String mainMessage, String optionalMessage, String destructiveOption, String nonDestructiveOption) { return showYesNoCancelQuestion(null, parent, mainMessage, optionalMessage, destructiveOption, nonDestructiveOption); } /** Show a question with two options and cancel. @return 0 for the destructive option; 1 for the non-destructive option; 2 for cancel */ public int showYesNoCancelQuestion(String disableKey, Component parent, String mainMessage, String optionalMessage, String destructiveOption, String nonDestructiveOption) { if (checkDisabled(disableKey)) return 0; Object[] options = new Object[3]; int destructiveIndex; if (Platform.isMac()) { options[0] = nonDestructiveOption; options[1] = i18n("LB_CANCEL"); options[2] = destructiveOption; destructiveIndex = 2; } else { options[0] = nonDestructiveOption; options[1] = destructiveOption; options[2] = i18n("LB_CANCEL"); destructiveIndex = -1; } Object defaultOption = options[0]; int type = JOptionPane.QUESTION_MESSAGE; Object value = show(disableKey, parent, "", mainMessage, optionalMessage, type, JOptionPane.YES_NO_CANCEL_OPTION, options, defaultOption, destructiveIndex); int result; if (value == destructiveOption) result = 0; else if (value == nonDestructiveOption) result = 1; else result = 2; return result; } public void showWarning(Component parent, String mainMessage, String optionalMessage, boolean isCritical) { showWarning(null, parent, mainMessage, optionalMessage, isCritical); } public void showWarning(String disableKey, Component parent, String mainMessage, String optionalMessage, boolean isCritical) { if (checkDisabled(disableKey)) return; int type; if (isCritical) type = JOptionPane.WARNING_MESSAGE; else type = JOptionPane.PLAIN_MESSAGE; Object[] options = { i18n("LB_CLOSE") }; Object defaultOption = options[0]; show(disableKey, parent, "", mainMessage, optionalMessage, type, JOptionPane.DEFAULT_OPTION, options, defaultOption, -1); } public boolean showQuestion(Component parent, String mainMessage, String optionalMessage, String destructiveOption, boolean isCritical) { return showQuestion(null, parent, mainMessage, optionalMessage, destructiveOption, isCritical); } public boolean showQuestion(String disableKey, Component parent, String mainMessage, String optionalMessage, String destructiveOption, boolean isCritical) { return showQuestion(disableKey, parent, mainMessage, optionalMessage, destructiveOption, i18n("LB_CANCEL"), isCritical); } /** Show warning message to confirm destructive actions. @return true, if destructive was chosen; false if cancel was chosen. */ public boolean showQuestion(String disableKey, Component parent, String mainMessage, String optionalMessage, String affirmativeOption, String cancelOption, boolean isCritical) { if (checkDisabled(disableKey)) return true; Object[] options = new Object[2]; if (Platform.isMac()) { options[0] = cancelOption; options[1] = affirmativeOption; } else { options[0] = affirmativeOption; options[1] = cancelOption; } Object defaultOption = affirmativeOption; int type; if (isCritical) // No reason to show a warning icon for confirmation dialogs // of frequent actions type = JOptionPane.QUESTION_MESSAGE; else type = JOptionPane.PLAIN_MESSAGE; Object result = show(disableKey, parent, "", mainMessage, optionalMessage, type, JOptionPane.YES_NO_OPTION, options, defaultOption, -1); return (result == affirmativeOption); } public boolean showWarningQuestion(Component parent, String mainMessage, String optionalMessage, String destructiveOption, boolean isCritical) { return showWarningQuestion(null, parent, mainMessage, optionalMessage, destructiveOption, isCritical); } public boolean showWarningQuestion(String disableKey, Component parent, String mainMessage, String optionalMessage, String destructiveOption, boolean isCritical) { return showWarningQuestion(disableKey, parent, mainMessage, optionalMessage, destructiveOption, i18n("LB_CANCEL"), isCritical); } /** Show warning message to confirm destructive actions. @return true, if destructive was chosen; false if cancel was chosen. */ public boolean showWarningQuestion(String disableKey, Component parent, String mainMessage, String optionalMessage, String destructiveOption, String nonDestructiveOption, boolean isCritical) { if (checkDisabled(disableKey)) return true; Object[] options = new Object[2]; if (Platform.isMac()) { options[0] = nonDestructiveOption; options[1] = destructiveOption; } else { options[0] = destructiveOption; options[1] = nonDestructiveOption; } Object defaultOption = nonDestructiveOption; int type; if (isCritical) type = JOptionPane.WARNING_MESSAGE; else type = JOptionPane.PLAIN_MESSAGE; Object result = show(disableKey, parent, "", mainMessage, optionalMessage, type, JOptionPane.YES_NO_OPTION, options, defaultOption, -1); return (result == destructiveOption); } private final Set<String> m_disabled = new TreeSet<String>(); private static void addFiller(JComponent component) { Box.Filler filler = GuiUtil.createFiller(); filler.setAlignmentX(Component.LEFT_ALIGNMENT); component.add(filler); } private boolean checkDisabled(String disableKey) { if (disableKey == null) return false; Preferences prefs = PrefUtil.createNode("net/sf/gogui/gui/messagedialogs/disabled"); boolean permanentlyDisabled = prefs.getBoolean(disableKey, false); if (permanentlyDisabled) return true; // Make sure this entry exists (right now these settings can only // be directly edited in the backing store) prefs.putBoolean(disableKey, permanentlyDisabled); return m_disabled.contains(disableKey); } private Object show(String disableKey, Component parent, String title, String mainMessage, String optionalMessage, int messageType, int optionType, Object[] options, Object defaultOption, int destructiveIndex) { if (optionalMessage == null) optionalMessage = ""; boolean isMac = Platform.isMac(); Box box = Box.createVerticalBox(); String css = GuiUtil.getMessageCss(); JLabel label = new JLabel("<html>" + css + "<b>" + insertLineBreaks(mainMessage) + "</b><p>" + insertLineBreaks(optionalMessage) + "</p>"); label.setAlignmentX(Component.LEFT_ALIGNMENT); box.add(label); addFiller(box); addFiller(box); JCheckBox disableCheckBox = null; if (disableKey != null) { if (messageType == JOptionPane.QUESTION_MESSAGE) disableCheckBox = new JCheckBox(i18n("LB_DO_NOT_ASK_AGAIN")); else if (messageType == JOptionPane.WARNING_MESSAGE) disableCheckBox = new JCheckBox(i18n("LB_DO_NOT_WARN_AGAIN")); else disableCheckBox = new JCheckBox(i18n("LB_DO_NOT_SHOW_AGAIN")); disableCheckBox.setToolTipText(i18n("TT_DO_NOT_SHOW_AGAIN")); disableCheckBox.setAlignmentX(Component.LEFT_ALIGNMENT); box.add(disableCheckBox); } if (isMac) // Don't show icons on Mac, problem with icon generation in // Quaqua 3.7.2 messageType = JOptionPane.PLAIN_MESSAGE; JOptionPane optionPane = new JOptionPane(box, messageType, optionType, null, options, defaultOption); if (destructiveIndex >= 0) { String key = "Quaqua.OptionPane.destructiveOption"; optionPane.putClientProperty(key, Integer.valueOf(destructiveIndex)); } if (isMac && parent.isVisible()) // Dialogs don't have titles on the Mac title = null; JDialog dialog = optionPane.createDialog(parent, title); dialog.setVisible(true); dialog.dispose(); if (disableKey != null && disableCheckBox.isSelected()) m_disabled.add(disableKey); return optionPane.getValue(); } }