/[svn]/jsampler/trunk/src/org/jsampler/view/std/StdUtils.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/StdUtils.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2146 - (show annotations) (download)
Mon Oct 11 09:31:27 2010 UTC (13 years, 6 months ago) by iliev
File size: 12790 byte(s)
* Fantasia: Migrated to substance 6.1
* Fantasia: Some minor GUI enhancements

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2010 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22 package org.jsampler.view.std;
23
24 import java.awt.Graphics2D;
25 import java.awt.Image;
26 import java.awt.Color;
27 import java.awt.Desktop;
28 import java.awt.Dialog;
29 import java.awt.FileDialog;
30 import java.awt.Frame;
31 import java.awt.Rectangle;
32 import java.awt.Toolkit;
33 import java.awt.Window;
34
35 import java.awt.event.ActionEvent;
36 import java.awt.event.ActionListener;
37 import java.awt.event.MouseAdapter;
38 import java.awt.event.MouseEvent;
39
40 import java.awt.image.BufferedImage;
41
42 import java.beans.PropertyChangeEvent;
43 import java.beans.PropertyChangeListener;
44
45 import java.io.File;
46 import java.net.URI;
47
48 import java.text.NumberFormat;
49
50 import java.util.Vector;
51 import java.util.logging.Level;
52
53 import javax.swing.ImageIcon;
54 import javax.swing.JComboBox;
55 import javax.swing.JFileChooser;
56 import javax.swing.JSlider;
57 import javax.swing.JToolTip;
58 import javax.swing.Popup;
59 import javax.swing.PopupFactory;
60
61 import javax.swing.event.ChangeEvent;
62 import javax.swing.event.ChangeListener;
63 import org.jsampler.CC;
64 import org.jsampler.HF;
65 import org.jsampler.JSPrefs;
66
67 import org.jsampler.view.JSFileFilter;
68 import static org.jsampler.view.std.StdI18n.i18n;
69 import static org.jsampler.view.std.StdPrefs.*;
70
71
72 /**
73 *
74 * @author Grigor Iliev
75 */
76 public class StdUtils {
77
78 /** Forbids the instantiation of this class */
79 private
80 StdUtils() { }
81
82 private static JSPrefs
83 preferences() { return CC.getViewConfig().preferences(); }
84
85 public static JComboBox
86 createEnhancedComboBox() {
87 final JComboBox cb = new JComboBox();
88 cb.addActionListener(new ActionListener() {
89 public void
90 actionPerformed(ActionEvent e) {
91 if(cb.getSelectedItem() == null) {
92 cb.setToolTipText(null);
93 return;
94 }
95 String s = cb.getSelectedItem().toString();
96 if(s.length() < 15) cb.setToolTipText(null);
97 else cb.setToolTipText(s);
98 }
99 });
100
101 return cb;
102 }
103
104 public static JComboBox
105 createPathComboBox() {
106 JComboBox cb = createEnhancedComboBox();
107 cb.setEditable(true);
108 return cb;
109 }
110
111 /**
112 * Updates the specified string list property by adding the specified
113 * element on the top. Also restricts the maximum number of elements to 12.
114 */
115 public static void
116 updateRecentElements(String property, String newElement) {
117 String[] elements = preferences().getStringListProperty(property);
118 Vector<String> v = new Vector<String>();
119 v.add(newElement);
120 for(String s : elements) {
121 if(!newElement.equals(s)) v.add(s);
122 }
123 if(v.size() > 12) v.setSize(12);
124
125 elements = v.toArray(new String[v.size()]);
126 preferences().setStringListProperty(property, elements);
127 }
128
129 public static boolean
130 checkDesktopSupported() {
131 if(Desktop.isDesktopSupported()) return true;
132
133 String s = i18n.getError("StdUtils.DesktopApiNotSupported");
134 HF.showErrorMessage(s, CC.getMainFrame());
135
136 return false;
137 }
138
139 public static void
140 browse(String uri) {
141 if(!checkDesktopSupported()) return;
142
143 try { Desktop.getDesktop().browse(new URI(uri)); }
144 catch(Exception x) { x.printStackTrace(); }
145 }
146
147 public static void
148 mail(String uri) {
149 if(!StdUtils.checkDesktopSupported()) return;
150
151 Desktop desktop = Desktop.getDesktop();
152
153 try { Desktop.getDesktop().mail(new URI(uri)); }
154 catch(Exception x) { x.printStackTrace(); }
155 }
156
157 /**
158 * Gets the windows bounds from the preferences for the specified window.
159 * @return The windows bounds saved in the preferences for the specified window
160 * or <code>null</code>.
161 */
162 public static Rectangle
163 getWindowBounds(String windowName) {
164 String s = windowName + ".windowSizeAndLocation";
165 s = CC.preferences().getStringProperty(s, null);
166 if(s == null) return null;
167
168 try {
169 int i = s.indexOf(',');
170 int x = Integer.parseInt(s.substring(0, i));
171
172 s = s.substring(i + 1);
173 i = s.indexOf(',');
174 int y = Integer.parseInt(s.substring(0, i));
175
176 s = s.substring(i + 1);
177 i = s.indexOf(',');
178 int width = Integer.parseInt(s.substring(0, i));
179
180 s = s.substring(i + 1);
181 int height = Integer.parseInt(s);
182
183 return new Rectangle(x, y, width, height);
184 } catch(Exception x) {
185 String msg = windowName;
186 msg += ": Parsing of window size and location string failed";
187 CC.getLogger().log(Level.INFO, msg, x);
188 return null;
189 }
190 }
191
192 /**
193 * Saves the windows bounds in the preferences for the specified window.
194 */
195 public static void
196 saveWindowBounds(String windowName, Rectangle r) {
197 if(r.width < 50 || r.height < 50 || r.x < r.width * -1 || r.y < 0) {
198 CC.getLogger().warning("Invalid window size or location");
199 return;
200 }
201
202 StringBuffer sb = new StringBuffer();
203 sb.append(r.x).append(',').append(r.y).append(',');
204 sb.append(r.width).append(',').append(r.height);
205 String s = windowName + ".windowSizeAndLocation";
206 CC.preferences().setStringProperty(s, sb.toString());
207 }
208
209 public static File
210 showOpenLscpFileChooser() {
211 return showLscpFileChooser(true);
212 }
213
214 public static File
215 showOpenLscpFileChooser(Window owner) {
216 return showLscpFileChooser(true, owner);
217 }
218
219 public static File
220 showSaveLscpFileChooser() {
221 return showLscpFileChooser(false);
222 }
223
224 public static File
225 showSaveLscpFileChooser(Window owner) {
226 return showLscpFileChooser(false, owner);
227 }
228
229 private static File
230 showLscpFileChooser(boolean openDialog) {
231 return showLscpFileChooser(openDialog, CC.getMainFrame());
232 }
233
234 private static File
235 showLscpFileChooser(boolean openDialog, Window owner) {
236 return showFileChooser (
237 openDialog, owner, false, new JSFileFilter.Lscp(), "lastScriptLocation"
238 );
239 }
240
241 public static File
242 showSaveMidiMapsChooser() {
243 JSFileFilter filter = new JSFileFilter.MidiMaps();
244
245 JSFileFilter[] filters = {
246 new JSFileFilter.Lscp(), new JSFileFilter.Text(), new JSFileFilter.Html(),
247 new JSFileFilter.Rgd()
248 };
249
250 return showFileChooser (
251 false, CC.getMainFrame(), false, filter, filters, "lastScriptLocation"
252 );
253 }
254
255 public static File
256 showOpenInstrumentFileChooser(Window owner) {
257 return showFileChooser(true, owner, false, null, "lastInstrumentLocation");
258 }
259
260 public static File
261 showOpenDirectoryChooser(Window owner, String locationProperty) {
262 return showFileChooser(true, owner, true, null, locationProperty);
263 }
264
265 private static File
266 showFileChooser (
267 boolean openDialog,
268 Window owner,
269 boolean dirChooser,
270 JSFileFilter filter,
271 String locationProperty
272 ) {
273 JSFileFilter[] filters = (filter == null) ? new JSFileFilter[0] : new JSFileFilter[1];
274 if(filter != null) filters[0] = filter;
275
276 return showFileChooser(openDialog, owner, dirChooser, filter, filters, locationProperty);
277 }
278
279 private static File
280 showFileChooser (
281 boolean openDialog,
282 Window owner,
283 boolean dirChooser,
284 JSFileFilter filter,
285 JSFileFilter[] choosableFilters,
286 String locationProperty
287 ) {
288 boolean nativeFileChooser = preferences().getBoolProperty("nativeFileChoosers");
289 String oldPath = null;
290 if(locationProperty != null) {
291 oldPath = preferences().getStringProperty(locationProperty);
292 }
293 File f = null;
294 if(nativeFileChooser && CC.isMacOS()) {
295 if(dirChooser) {
296 System.setProperty("apple.awt.fileDialogForDirectories", "true");
297 }
298 FileDialog dlg;
299 if(owner instanceof Frame) dlg = new FileDialog((Frame)owner);
300 else if(owner instanceof Dialog) dlg = new FileDialog((Dialog)owner);
301 else dlg = new FileDialog(CC.getMainFrame());
302 dlg.setDirectory(oldPath);
303 dlg.setMode(openDialog ? FileDialog.LOAD : FileDialog.SAVE);
304 if(filter != null) dlg.setFilenameFilter(filter);
305 dlg.setVisible(true);
306 if(dirChooser) {
307 System.setProperty("apple.awt.fileDialogForDirectories", "false");
308 }
309 if(dlg.getFile() != null) {
310 f = new File(new File(dlg.getDirectory()), dlg.getFile());
311 }
312 } else {
313 JFileChooser fc = new JFileChooser(oldPath);
314 for(JSFileFilter ff : choosableFilters) {
315 fc.addChoosableFileFilter(ff);
316 }
317 if(choosableFilters.length > 0) fc.setFileFilter(choosableFilters[0]);
318
319 if(dirChooser) fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
320 int result;
321 if(openDialog) result = fc.showOpenDialog(owner);
322 else result = fc.showSaveDialog(owner);
323 if(result == JFileChooser.APPROVE_OPTION) {
324 f = fc.getSelectedFile();
325 }
326
327 if(result == JFileChooser.APPROVE_OPTION && !openDialog) {
328 Object o = fc.getFileFilter();
329 for(JSFileFilter ff : choosableFilters) {
330 if(ff == o) {
331 String fn = f.getName().toLowerCase();
332 String ext = ff.getExtension().toLowerCase();
333 if(fn.endsWith(ext)) break;
334
335 fn = f.getAbsolutePath() + ff.getExtension();
336 f = new File(fn);
337 break;
338 }
339 }
340 }
341 }
342
343 if(f == null) return null;
344 String path = f.getParent();
345 if(path != null && locationProperty != null) {
346 preferences().setStringProperty(locationProperty, path);
347 }
348 return f;
349 }
350
351 public static JSlider
352 createVolumeSlider() {
353 return new VolumeSlider();
354 }
355
356 private static class VolumeSlider extends JSlider {
357 private Popup popup = null;
358 private final JToolTip tip = new JToolTip();
359 private static NumberFormat numberFormat = NumberFormat.getInstance();
360
361 VolumeSlider() {
362 super(0, 100, 100);
363 numberFormat.setMaximumFractionDigits(1);
364 // Setting the tooltip size (workaround for preserving that size)
365 boolean b = CC.getViewConfig().isMeasurementUnitDecibel();
366 if(b) tip.setTipText(i18n.getLabel("StdUtils.volumeDecibels", "-30.0"));
367 else tip.setTipText(i18n.getLabel("StdUtils.volume", "100"));
368 tip.setPreferredSize(tip.getPreferredSize());
369 tip.setMinimumSize(tip.getPreferredSize());
370 ///////
371 tip.setComponent(this);
372 tip.setTipText(i18n.getLabel("StdUtils.volume", 0));
373
374 updateVolumeInfo();
375
376 addMouseListener(new MouseAdapter() {
377 public void
378 mousePressed(MouseEvent e) {
379 if(popup != null) {
380 popup.hide();
381 popup = null;
382 }
383
384 if(!VolumeSlider.this.isEnabled()) return;
385
386 java.awt.Point p = VolumeSlider.this.getLocationOnScreen();
387 PopupFactory pf = PopupFactory.getSharedInstance();
388 popup = pf.getPopup(VolumeSlider.this, tip, p.x, p.y - 22);
389 popup.show();
390 }
391
392 public void
393 mouseReleased(MouseEvent e) {
394 if(popup != null) {
395 popup.hide();
396 popup = null;
397 }
398 }
399 });
400
401 addChangeListener(new ChangeListener() {
402 public void
403 stateChanged(ChangeEvent e) { updateVolumeInfo(); }
404 });
405
406 String s = VOL_MEASUREMENT_UNIT_DECIBEL;
407 preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
408 public void
409 propertyChange(PropertyChangeEvent e) {
410 // We use this to set the size of the lVolume
411 // to prevent the frequent resizing of lVolume component
412 boolean b = CC.getViewConfig().isMeasurementUnitDecibel();
413 tip.setPreferredSize(null);
414 String s;
415 if(b) s = i18n.getLabel("StdUtils.volumeDecibels", "-30.0");
416 else s = i18n.getLabel("StdUtils.volume", "100");
417 tip.setTipText(s);
418 tip.setPreferredSize(tip.getPreferredSize());
419 tip.setMinimumSize(tip.getPreferredSize());
420 ///////
421 updateVolumeInfo();
422 }
423 });
424 }
425
426 private void
427 updateVolumeInfo() {
428 String s;
429 if(CC.getViewConfig().isMeasurementUnitDecibel()) {
430 double d = HF.percentsToDecibels(getValue());
431 s = i18n.getLabel("StdUtils.volumeDecibels", numberFormat.format(d));
432 } else {
433 s = i18n.getLabel("StdUtils.volume", getValue());
434 }
435
436 setToolTipText(s);
437 tip.setTipText(s);
438 tip.repaint();
439 }
440 }
441
442 /**
443 * Applies the specified color as background to
444 * the specified image and returns the newly created image.
445 */
446 public static ImageIcon
447 createImageIcon(Image img, Color bgColor) {
448 BufferedImage img2 = new BufferedImage (
449 img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB
450 );
451
452 Graphics2D g = img2.createGraphics();
453 g.drawImage(img, 0, 0, bgColor, null);
454 g.dispose();
455
456 return new ImageIcon(Toolkit.getDefaultToolkit().createImage(img2.getSource()));
457 }
458 }

  ViewVC Help
Powered by ViewVC