1
2 package org.newdawn.slick.font.effects;
3
4 import java.awt.AlphaComposite;
5 import java.awt.Color;
6 import java.awt.Dimension;
7 import java.awt.EventQueue;
8 import java.awt.Graphics2D;
9 import java.awt.GridBagConstraints;
10 import java.awt.GridBagLayout;
11 import java.awt.Insets;
12 import java.awt.image.BufferedImage;
13
14 import javax.annotation.Nonnull;
15 import javax.annotation.Nullable;
16 import javax.swing.BorderFactory;
17 import javax.swing.DefaultComboBoxModel;
18 import javax.swing.JButton;
19 import javax.swing.JCheckBox;
20 import javax.swing.JColorChooser;
21 import javax.swing.JComboBox;
22 import javax.swing.JComponent;
23 import javax.swing.JDialog;
24 import javax.swing.JLabel;
25 import javax.swing.JPanel;
26 import javax.swing.JSpinner;
27 import javax.swing.JTextArea;
28 import javax.swing.SpinnerNumberModel;
29
30 import org.newdawn.slick.font.GlyphPage;
31 import org.newdawn.slick.font.effects.ConfigurableEffect.Value;
32
33
34
35
36
37
38 public class EffectUtil {
39
40 @Nonnull
41 static private final BufferedImage scratchImage = new BufferedImage(GlyphPage.MAX_GLYPH_SIZE, GlyphPage.MAX_GLYPH_SIZE,
42 BufferedImage.TYPE_INT_ARGB);
43
44
45
46
47
48
49 @Nonnull
50 static public BufferedImage getScratchImage() {
51 Graphics2D g = (Graphics2D)scratchImage.getGraphics();
52 g.setComposite(AlphaComposite.Clear);
53 g.fillRect(0, 0, GlyphPage.MAX_GLYPH_SIZE, GlyphPage.MAX_GLYPH_SIZE);
54 g.setComposite(AlphaComposite.SrcOver);
55 g.setColor(java.awt.Color.white);
56 return scratchImage;
57 }
58
59
60
61
62
63
64
65
66 @Nullable
67 static public Value colorValue(String name, @Nullable Color currentValue) {
68 return new DefaultValue(name, EffectUtil.toString(currentValue)) {
69 public void showDialog () {
70 Color newColor = JColorChooser.showDialog(null, "Choose a color", EffectUtil.fromString(value));
71 if (newColor != null) value = EffectUtil.toString(newColor);
72 }
73
74 public Object getObject () {
75 return EffectUtil.fromString(value);
76 }
77 };
78 }
79
80
81
82
83
84
85
86
87
88 @Nonnull
89 static public Value intValue (String name, final int currentValue, final String description) {
90 return new DefaultValue(name, String.valueOf(currentValue)) {
91 public void showDialog () {
92 JSpinner spinner = new JSpinner(new SpinnerNumberModel(currentValue, Short.MIN_VALUE, Short.MAX_VALUE, 1));
93 if (showValueDialog(spinner, description)) value = String.valueOf(spinner.getValue());
94 }
95
96 public Object getObject () {
97 return Integer.valueOf(value);
98 }
99 };
100 }
101
102
103
104
105
106
107
108
109
110
111
112 @Nonnull
113 static public Value floatValue (String name, final float currentValue, final float min, final float max,
114 final String description) {
115 return new DefaultValue(name, String.valueOf(currentValue)) {
116 public void showDialog () {
117 JSpinner spinner = new JSpinner(new SpinnerNumberModel(currentValue, min, max, 0.1f));
118 if (showValueDialog(spinner, description)) value = String.valueOf(((Double)spinner.getValue()).floatValue());
119 }
120
121 public Object getObject () {
122 return Float.valueOf(value);
123 }
124 };
125 }
126
127
128
129
130
131
132
133
134
135 @Nonnull
136 static public Value booleanValue (String name, final boolean currentValue, final String description) {
137 return new DefaultValue(name, String.valueOf(currentValue)) {
138 public void showDialog () {
139 JCheckBox checkBox = new JCheckBox();
140 checkBox.setSelected(currentValue);
141 if (showValueDialog(checkBox, description)) value = String.valueOf(checkBox.isSelected());
142 }
143
144 public Object getObject () {
145 return Boolean.valueOf(value);
146 }
147 };
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 @Nonnull
164 static public Value optionValue (String name, final String currentValue, @Nonnull final String[][] options, final String description) {
165 return new DefaultValue(name, currentValue) {
166 public void showDialog () {
167 int selectedIndex = -1;
168 DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
169 for (int i = 0; i < options.length; i++) {
170 model.addElement(options[i][0]);
171 if (getValue(i).equals(currentValue)) selectedIndex = i;
172 }
173 JComboBox<String> comboBox = new JComboBox<>(model);
174 comboBox.setSelectedIndex(selectedIndex);
175 if (showValueDialog(comboBox, description)) value = getValue(comboBox.getSelectedIndex());
176 }
177
178 private String getValue (int i) {
179 if (options[i].length == 1) return options[i][0];
180 return options[i][1];
181 }
182
183 public String toString () {
184 for (int i = 0; i < options.length; i++)
185 if (getValue(i).equals(value)) return options[i][0];
186 return "";
187 }
188
189 public Object getObject () {
190 return value;
191 }
192 };
193 }
194
195
196
197
198
199
200
201 @Nonnull
202 private static String toString(@Nullable Color color) {
203 if (color == null) throw new IllegalArgumentException("color cannot be null.");
204 String r = Integer.toHexString(color.getRed());
205 if (r.length() == 1) r = "0" + r;
206 String g = Integer.toHexString(color.getGreen());
207 if (g.length() == 1) g = "0" + g;
208 String b = Integer.toHexString(color.getBlue());
209 if (b.length() == 1) b = "0" + b;
210 return r + g + b;
211 }
212
213
214
215
216
217
218
219 private static Color fromString(@Nullable String rgb) {
220 if (rgb == null || rgb.length() != 6) return Color.white;
221 return new Color(Integer.parseInt(rgb.substring(0, 2), 16), Integer.parseInt(rgb.substring(2, 4), 16), Integer.parseInt(rgb
222 .substring(4, 6), 16));
223 }
224
225
226
227
228 static private abstract class DefaultValue implements Value {
229
230 String value;
231
232 final String name;
233
234
235
236
237
238
239
240 public DefaultValue(String name, String value) {
241 this.value = value;
242 this.name = name;
243 }
244
245
246
247
248 public void setString(String value) {
249 this.value = value;
250 }
251
252
253
254
255 public String getString() {
256 return value;
257 }
258
259
260
261
262 public String getName() {
263 return name;
264 }
265
266
267
268
269 public String toString() {
270 if (value == null) {
271 return "";
272 }
273 return value;
274 }
275
276
277
278
279
280
281
282
283 public boolean showValueDialog(@Nonnull final JComponent component, String description) {
284 ValueDialog dialog = new ValueDialog(component, name, description);
285 dialog.setTitle(name);
286 dialog.setLocationRelativeTo(null);
287 EventQueue.invokeLater(() -> {
288 JComponent focusComponent = component;
289 if (focusComponent instanceof JSpinner)
290 focusComponent = ((JSpinner.DefaultEditor)((JSpinner)component).getEditor()).getTextField();
291 focusComponent.requestFocusInWindow();
292 });
293 dialog.setVisible(true);
294 return dialog.okPressed;
295 }
296 }
297
298
299
300
301 static private class ValueDialog extends JDialog {
302
303
304
305 private static final long serialVersionUID = 1L;
306
307 public boolean okPressed = false;
308
309
310
311
312
313
314
315
316 public ValueDialog(JComponent component, String name, String description) {
317 setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
318 setLayout(new GridBagLayout());
319 setModal(true);
320
321 if (component instanceof JSpinner)
322 ((JSpinner.DefaultEditor)((JSpinner)component).getEditor()).getTextField().setColumns(4);
323
324 JPanel descriptionPanel = new JPanel();
325 descriptionPanel.setLayout(new GridBagLayout());
326 getContentPane().add(
327 descriptionPanel,
328 new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0,
329 0), 0, 0));
330 descriptionPanel.setBackground(Color.white);
331 descriptionPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black));
332 {
333 JTextArea descriptionText = new JTextArea(description);
334 descriptionPanel.add(descriptionText, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
335 GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
336 descriptionText.setWrapStyleWord(true);
337 descriptionText.setLineWrap(true);
338 descriptionText.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
339 descriptionText.setEditable(false);
340 }
341
342 JPanel panel = new JPanel();
343 getContentPane().add(
344 panel,
345 new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 0,
346 5), 0, 0));
347 panel.add(new JLabel(name + ":"));
348 panel.add(component);
349
350 JPanel buttonPanel = new JPanel();
351 getContentPane().add(
352 buttonPanel,
353 new GridBagConstraints(0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
354 new Insets(0, 0, 0, 0), 0, 0));
355 {
356 JButton okButton = new JButton("OK");
357 buttonPanel.add(okButton);
358 okButton.addActionListener(evt -> {
359 okPressed = true;
360 setVisible(false);
361 });
362 }
363 {
364 JButton cancelButton = new JButton("Cancel");
365 buttonPanel.add(cancelButton);
366 cancelButton.addActionListener(evt -> setVisible(false));
367 }
368
369 setSize(new Dimension(320, 175));
370 }
371 }
372 }