/[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 2288 - (show annotations) (download)
Wed Nov 23 21:19:44 2011 UTC (12 years, 5 months ago) by iliev
File size: 12807 byte(s)
* Added option to select a sampler engine in Add/Edit Instrument dialog
* Moved all Swing dependent code outside the JSampler core

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

  ViewVC Help
Powered by ViewVC