/[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 38 - (show annotations)
Sun Apr 5 15:06:56 2009 UTC (15 years, 10 months ago) by alfonx
File size: 8581 byte(s)
* Further improved the TranslationAskJDialog
* Removed deprecated stuff from TranslationEditJPanel


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26