1 /* 2 * Copyright (c) 2016 Helmut Neemann 3 * Use of this source code is governed by the GPL v3 license 4 * that can be found in the LICENSE file. 5 */ 6 package de.neemann.gui; 7 8 import de.neemann.digital.lang.Lang; 9 10 import javax.swing.*; 11 import java.awt.*; 12 import java.awt.event.WindowAdapter; 13 import java.awt.event.WindowEvent; 14 15 /** 16 * Frame needs to be set to DO_NOTHING_ON_CLOSE to work. 17 * Closing should by done by the {@link GUICloser#closeGUI()}. 18 */ 19 public class ClosingWindowListener extends WindowAdapter { 20 private final static String SAVE_CHANGES_MESSAGE = Lang.get("win_saveChanges"); 21 private final static String CONFIRM_EXIT_MESSAGE = Lang.get("win_confirmExit"); 22 private final static String STATE_CHANGED_MESSAGE = Lang.get("win_stateChanged"); 23 private final static String NO_MESSAGE = Lang.get("btn_discard"); 24 private final static String YES_MESSAGE = Lang.get("btn_save"); 25 private final static String CANCEL_MESSAGE = Lang.get("btn_editFurther"); 26 private final Component parent; 27 private final GUICloser guiCloser; 28 29 /** 30 * Create a new Instance 31 * 32 * @param parent the parent component of the confirm dialog 33 * @param confirmSave the ConfirmSave interface 34 */ ClosingWindowListener(final JFrame parent, final ConfirmSave confirmSave)35 public ClosingWindowListener(final JFrame parent, final ConfirmSave confirmSave) { 36 this(parent, confirmSave, true); 37 } 38 39 /** 40 * Create a new Instance 41 * 42 * @param parent the parent component of the confirm dialog 43 * @param confirmSave the ConfirmSave interface 44 * @param doExit if true the parent JFrame is disposed by this listener 45 */ ClosingWindowListener(final JFrame parent, final ConfirmSave confirmSave, final boolean doExit)46 private ClosingWindowListener(final JFrame parent, final ConfirmSave confirmSave, final boolean doExit) { 47 this((Component) parent, new GUICloser() { 48 @Override 49 public void closeGUI() { 50 if (doExit) { 51 parent.dispose(); 52 } 53 } 54 55 @Override 56 public boolean isStateChanged() { 57 return confirmSave.isStateChanged(); 58 } 59 60 @Override 61 public void saveChanges() { 62 confirmSave.saveChanges(); 63 } 64 }); 65 } 66 67 /** 68 * Used to check for save! No Window closing is performed! 69 * 70 * @param parent the Parent frame 71 * @param confirmSave the confirmSafe interface 72 * @return true if to proceed 73 */ checkForSave(JFrame parent, ConfirmSave confirmSave)74 public static boolean checkForSave(JFrame parent, ConfirmSave confirmSave) { 75 if (confirmSave.isStateChanged()) { 76 int r = new ConfirmDialogBuilder(SAVE_CHANGES_MESSAGE) 77 .setTitle(STATE_CHANGED_MESSAGE) 78 .setNoOption(NO_MESSAGE) 79 .setYesOption(YES_MESSAGE) 80 .setCancleOption(CANCEL_MESSAGE) 81 .show(parent); 82 83 if (r == JOptionPane.YES_OPTION || r == JOptionPane.NO_OPTION) { 84 if (r == JOptionPane.YES_OPTION) { 85 confirmSave.saveChanges(); 86 return !confirmSave.isStateChanged(); 87 } else 88 return true; 89 } else 90 return false; 91 } 92 return true; 93 } 94 95 /** 96 * Create a new Instance 97 * 98 * @param parent the parent component of the confirm dialog 99 * @param guiCloser the guiCloser 100 */ ClosingWindowListener(Component parent, GUICloser guiCloser)101 private ClosingWindowListener(Component parent, GUICloser guiCloser) { 102 this.parent = parent; 103 this.guiCloser = guiCloser; 104 } 105 106 @Override windowClosing(WindowEvent e)107 public void windowClosing(WindowEvent e) { 108 if (guiCloser.isStateChanged()) { 109 int r = new ConfirmDialogBuilder(SAVE_CHANGES_MESSAGE) 110 .setTitle(CONFIRM_EXIT_MESSAGE) 111 .setNoOption(NO_MESSAGE) 112 .setYesOption(YES_MESSAGE) 113 .setCancleOption(CANCEL_MESSAGE) 114 .show(parent); 115 116 if (r == JOptionPane.YES_OPTION || r == JOptionPane.NO_OPTION) { 117 if (r == JOptionPane.YES_OPTION) { 118 guiCloser.saveChanges(); 119 if (!guiCloser.isStateChanged()) 120 guiCloser.closeGUI(); 121 } else 122 guiCloser.closeGUI(); 123 } 124 } else { 125 guiCloser.closeGUI(); 126 } 127 } 128 129 /** 130 * Interface to control the gui closing 131 */ 132 public interface ConfirmSave { 133 /** 134 * @return true is state is changed and there is something to save 135 */ isStateChanged()136 boolean isStateChanged(); 137 138 /** 139 * save changes 140 */ saveChanges()141 void saveChanges(); 142 143 } 144 145 /** 146 * Interface to control the gui closing 147 */ 148 public interface GUICloser extends ConfirmSave { 149 150 /** 151 * Close the GUI 152 */ closeGUI()153 void closeGUI(); 154 } 155 156 } 157