/[schmitzm]/trunk/src/skrueger/swing/TranslationAskJDialog.java
ViewVC logotype

Contents of /trunk/src/skrueger/swing/TranslationAskJDialog.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 120 - (show annotations)
Sat May 16 21:25:44 2009 UTC (15 years, 9 months ago) by alfonx
File size: 9209 byte(s)
* Possibility to ass more buttons to the button panel by #setButtons(JButton... )
1 package skrueger.swing;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.FlowLayout;
6 import java.awt.Window;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.awt.event.KeyEvent;
10 import java.awt.event.WindowAdapter;
11 import java.awt.event.WindowEvent;
12 import java.util.Locale;
13
14 import javax.swing.AbstractAction;
15 import javax.swing.Action;
16 import javax.swing.Box;
17 import javax.swing.JButton;
18 import javax.swing.JComponent;
19 import javax.swing.JDialog;
20 import javax.swing.JOptionPane;
21 import javax.swing.JPanel;
22 import javax.swing.JRootPane;
23 import javax.swing.KeyStroke;
24
25 import schmitzm.lang.LangUtil;
26 import schmitzm.lang.ResourceProvider;
27 import schmitzm.swing.SwingUtil;
28 import skrueger.i8n.Translation;
29
30 public class TranslationAskJDialog extends JDialog {
31
32 /**
33 * {@link ResourceProvider}, der die Lokalisation fuer GUI-Komponenten des
34 * Package {@code skrueger.swing} zur Verfuegung stellt. Diese sind in
35 * properties-Datein unter {@code skrueger.swing.resource.locales}
36 * hinterlegt.
37 */
38 public static ResourceProvider RESOURCE = new ResourceProvider(LangUtil
39 .extendPackagePath(TranslationAskJDialog.class,
40 "resource.locales.SwingResourceBundle"), Locale.ENGLISH);
41
42 private String[] backup = new String[50]; // Maximum 50 languages ;-)
43 private OkButton okButton;
44 private CancelButton cancelButton;
45
46 public static final String PROPERTY_CANCEL_AND_CLOSE = "CANCEL";
47 public static final String PROPERTY_APPLY_AND_CLOSE = "APPLY";
48
49 private JComponent[] translationEditJPanelsOrJustComponents;
50
51 private boolean hasBeenCanceled;
52
53 private JButton[] optionalButtons;
54
55 /**
56 * Since the registerKeyboardAction() method is part of the JComponent class
57 * definition, you must define the Escape keystroke and register the
58 * keyboard action with a JComponent, not with a JDialog. The JRootPane for
59 * the JDialog serves as an excellent choice to associate the registration,
60 * as this will always be visible. If you override the protected
61 * createRootPane() method of JDialog, you can return your custom JRootPane
62 * with the keystroke enabled:
63 */
64 @Override
65 protected JRootPane createRootPane() {
66 KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
67 JRootPane rootPane = new JRootPane();
68 rootPane.registerKeyboardAction(new ActionListener() {
69
70 public void actionPerformed(ActionEvent e) {
71 cancel();
72 }
73
74 }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
75
76 return rootPane;
77 }
78
79 /**
80 * The {@link TranslationAskJDialog} fills its content pane with an
81 * arbitrary number of components. If these {@link Component}s are
82 * {@link TranslationEditJPanel}s, the {@link JDialog} manages to backup the
83 * values and restore them if the dialog is canceled. Other
84 * {@link JComponent}s are just displayed.<br/>
85 * This class handles the cancel button itself. You may still want to listen
86 * to PROPERTY_APPLY_AND_CLOSE events. This dialog is modal. The dialog has
87 * to be set visible afterwards.<br/>
88 *
89 * @param owner
90 * A component of the GUI that this dialog is related to. If no
91 * {@link Window} is passed, SwingUtil.getParentWindow(owner) is
92 * called.
93 */
94 public TranslationAskJDialog(Component owner,
95 final JComponent... translationEditJPanels) {
96 super(owner instanceof Window ? (Window) owner : SwingUtil
97 .getParentWindow(owner));
98 setComponents(translationEditJPanels);
99 }
100
101 /**
102 * The {@link TranslationAskJDialog} fills its content pane with an
103 * arbitrary number of components. If these {@link Component}s are
104 * {@link TranslationEditJPanel}s, the {@link JDialog} manages to backup the
105 * values and restore them if the dialog is canceled. Other
106 * {@link JComponent}s are just displayed.<br/>
107 * This class handles the cancel button itself. You may still want to listen
108 * to PROPERTY_APPLY_AND_CLOSE events. This dialog is modal. The dialog has
109 * to be set visible afterwards.<br/>
110 * Using this constructor, you have to call setComponents afterwards.
111 */
112 public TranslationAskJDialog(Window owner) {
113 this(owner, new JComponent[] {});
114 }
115
116 /**
117 * The {@link TranslationAskJDialog} fills its content pane with an
118 * arbitrary number of components. If these {@link Component}s are
119 * {@link TranslationEditJPanel}s, the {@link JDialog} manages to backup the
120 * values and restore them if the dialog is canceled. Other
121 * {@link JComponent}s are just displayed.
122 *
123 * @param translationEditJPanels
124 * Arbitrary list of {@link JComponent}s and
125 * {@link TranslationEditJPanel}s.
126 */
127 public void setComponents(final JComponent... translationEditJPanels) {
128 this.translationEditJPanelsOrJustComponents = translationEditJPanels;
129
130 // Remember backups for all the TranslationEditJPanel
131 int count = 0;
132 for (JComponent component : translationEditJPanelsOrJustComponents) {
133 if (component instanceof TranslationEditJPanel) {
134 TranslationEditJPanel tep = (TranslationEditJPanel) component;
135 Translation orig = tep.getTranslation();
136
137 // We don't want to overwrite the Translation object on
138 // restore(). We just want to change its value.
139 backup[count++] = orig.toOneLine();
140 }
141 }
142
143 init();
144 }
145
146 private void init() {
147 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
148 addWindowListener(new WindowAdapter() {
149
150 public void windowClosing(WindowEvent e) {
151 cancel();
152 }
153
154 });
155 SwingUtil.centerFrameOnScreen(this);
156 Box box = Box.createVerticalBox();
157 for (JComponent panel : translationEditJPanelsOrJustComponents) {
158 box.add(panel);
159 }
160 JPanel cp = new JPanel(new BorderLayout());
161 cp.add(box, BorderLayout.CENTER);
162 cp.add(getButtons(), BorderLayout.SOUTH);
163 setContentPane(cp);
164
165 setTitle(RESOURCE.getString("translation_dialog_title")); // i8n
166 setModal(true);
167 pack();
168 }
169
170 public void setButtons(JButton... optionalButtons) {
171 this.optionalButtons = optionalButtons;
172 init();
173 }
174
175 protected void cancel() {
176 firePropertyChange(PROPERTY_CANCEL_AND_CLOSE, null, null);
177 restore();
178 setVisible(false);
179 dispose();
180 }
181
182 protected void restore() {
183 int count = 0;
184 for (JComponent component : translationEditJPanelsOrJustComponents) {
185 if (component instanceof TranslationEditJPanel) {
186 TranslationEditJPanel tep = (TranslationEditJPanel) component;
187 tep.getTranslation().fromOneLine(backup[count++]);
188 }
189 }
190 }
191
192 private JComponent getButtons() {
193 JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
194
195 if (optionalButtons != null)
196 for (JButton b : optionalButtons) {
197 jPanel.add(b);
198 }
199
200 if (okButton == null) {
201 okButton = new OkButton(new AbstractAction() {
202 {
203 // Set a mnemonic character. In most look and feels, this
204 // causes the
205 // specified character to be underlined This indicates that
206 // if the component
207 // using this action has the focus and In some look and
208 // feels, this causes
209 // the specified character in the label to be underlined and
210 putValue(Action.MNEMONIC_KEY, new Integer(
211 java.awt.event.KeyEvent.VK_E));
212
213 // Set tool tip text
214 putValue(Action.SHORT_DESCRIPTION,
215 "Accept the changes made to the translation.");
216
217 }
218
219 public void actionPerformed(ActionEvent evt) {
220 TranslationAskJDialog.this.firePropertyChange(
221 PROPERTY_APPLY_AND_CLOSE, null, null);
222
223 if (!checkValidInputs())
224 return;
225
226 setVisible(false);
227 dispose();
228 }
229
230 });
231
232 }
233 jPanel.add(okButton);
234
235 if (cancelButton == null) {
236 cancelButton = new CancelButton(new AbstractAction("") {
237 public void actionPerformed(ActionEvent evt) {
238 restore();
239 TranslationAskJDialog.this.firePropertyChange(
240 PROPERTY_CANCEL_AND_CLOSE, null, null);
241 setVisible(false);
242 setCancelled(true);
243 dispose();
244 }
245 });
246 }
247 jPanel.add(cancelButton);
248
249 return jPanel;
250 }
251
252 /**
253 * @return <code>true</code> if none of the translations contains illegal
254 * characters.
255 */
256 protected boolean checkValidInputs() {
257
258 for (JComponent component : translationEditJPanelsOrJustComponents) {
259 if (component instanceof TranslationEditJPanel) {
260 TranslationEditJPanel tep = (TranslationEditJPanel) component;
261
262 for (String l : tep.getTranslation().values()) {
263 if (l.contains("{") || l.contains("}")) {
264 JOptionPane
265 .showMessageDialog(
266 this,
267 RESOURCE
268 .getString("ErrorMsg.InvalidCharacterInTranslation"));
269 return false;
270 }
271 }
272
273 }
274 }
275
276 return true;
277 }
278
279 private void setCancelled(boolean hasBeenCanceled) {
280 this.hasBeenCanceled = hasBeenCanceled;
281 }
282
283 /**
284 * After the modal dialog has been closed, this allows to find out, whether
285 * the dialog has been canceled.
286 *
287 * @return <code>true</code> if the {@link JDialog} has been canceled.
288 */
289 public boolean isCancelled() {
290 return hasBeenCanceled;
291 }
292
293 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26