1 |
/* |
2 |
* JSampler - a java front-end for LinuxSampler |
3 |
* |
4 |
* Copyright (C) 2005-2007 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.Desktop; |
25 |
import java.awt.Rectangle; |
26 |
|
27 |
import java.awt.event.ActionEvent; |
28 |
import java.awt.event.ActionListener; |
29 |
import java.awt.event.MouseAdapter; |
30 |
import java.awt.event.MouseEvent; |
31 |
|
32 |
import java.beans.PropertyChangeEvent; |
33 |
import java.beans.PropertyChangeListener; |
34 |
|
35 |
import java.net.URI; |
36 |
|
37 |
import java.text.NumberFormat; |
38 |
|
39 |
import java.util.Vector; |
40 |
import java.util.logging.Level; |
41 |
|
42 |
import javax.swing.JComboBox; |
43 |
import javax.swing.JSlider; |
44 |
import javax.swing.JToolTip; |
45 |
import javax.swing.Popup; |
46 |
import javax.swing.PopupFactory; |
47 |
|
48 |
import javax.swing.event.ChangeEvent; |
49 |
import javax.swing.event.ChangeListener; |
50 |
import org.jsampler.CC; |
51 |
import org.jsampler.HF; |
52 |
import org.jsampler.JSPrefs; |
53 |
|
54 |
import static org.jsampler.view.std.StdI18n.i18n; |
55 |
import static org.jsampler.view.std.StdPrefs.*; |
56 |
|
57 |
|
58 |
/** |
59 |
* |
60 |
* @author Grigor Iliev |
61 |
*/ |
62 |
public class StdUtils { |
63 |
|
64 |
/** Forbids the instantiation of this class */ |
65 |
private |
66 |
StdUtils() { } |
67 |
|
68 |
private static JSPrefs |
69 |
preferences() { return CC.getViewConfig().preferences(); } |
70 |
|
71 |
public static JComboBox |
72 |
createPathComboBox() { |
73 |
final JComboBox cb = new JComboBox(); |
74 |
cb.setEditable(true); |
75 |
cb.addActionListener(new ActionListener() { |
76 |
public void |
77 |
actionPerformed(ActionEvent e) { |
78 |
if(cb.getSelectedItem() == null) { |
79 |
cb.setToolTipText(null); |
80 |
return; |
81 |
} |
82 |
String s = cb.getSelectedItem().toString(); |
83 |
if(s.length() < 15) cb.setToolTipText(null); |
84 |
else cb.setToolTipText(s); |
85 |
} |
86 |
}); |
87 |
|
88 |
return cb; |
89 |
} |
90 |
|
91 |
/** |
92 |
* Updates the specified string list property by adding the specified |
93 |
* element on the top. Also restricts the maximum number of elements to 12. |
94 |
*/ |
95 |
public static void |
96 |
updateRecentElements(String property, String newElement) { |
97 |
String[] elements = preferences().getStringListProperty(property); |
98 |
Vector<String> v = new Vector<String>(); |
99 |
v.add(newElement); |
100 |
for(String s : elements) { |
101 |
if(!newElement.equals(s)) v.add(s); |
102 |
} |
103 |
if(v.size() > 12) v.setSize(12); |
104 |
|
105 |
elements = v.toArray(new String[v.size()]); |
106 |
preferences().setStringListProperty(property, elements); |
107 |
} |
108 |
|
109 |
public static boolean |
110 |
checkDesktopSupported() { |
111 |
if(Desktop.isDesktopSupported()) return true; |
112 |
|
113 |
String s = i18n.getError("StdUtils.DesktopApiNotSupported"); |
114 |
HF.showErrorMessage(s, CC.getMainFrame()); |
115 |
|
116 |
return false; |
117 |
} |
118 |
|
119 |
public static void |
120 |
browse(String uri) { |
121 |
if(!checkDesktopSupported()) return; |
122 |
|
123 |
try { Desktop.getDesktop().browse(new URI(uri)); } |
124 |
catch(Exception x) { x.printStackTrace(); } |
125 |
} |
126 |
|
127 |
public static void |
128 |
mail(String uri) { |
129 |
if(!StdUtils.checkDesktopSupported()) return; |
130 |
|
131 |
Desktop desktop = Desktop.getDesktop(); |
132 |
|
133 |
try { Desktop.getDesktop().mail(new URI(uri)); } |
134 |
catch(Exception x) { x.printStackTrace(); } |
135 |
} |
136 |
|
137 |
/** |
138 |
* Gets the windows bounds from the preferences for the specified window. |
139 |
* @return The windows bounds saved in the preferences for the specified window |
140 |
* or <code>null</code>. |
141 |
*/ |
142 |
public static Rectangle |
143 |
getWindowBounds(String windowName) { |
144 |
String s = windowName + ".windowSizeAndLocation"; |
145 |
s = CC.preferences().getStringProperty(s, null); |
146 |
if(s == null) return null; |
147 |
|
148 |
try { |
149 |
int i = s.indexOf(','); |
150 |
int x = Integer.parseInt(s.substring(0, i)); |
151 |
|
152 |
s = s.substring(i + 1); |
153 |
i = s.indexOf(','); |
154 |
int y = Integer.parseInt(s.substring(0, i)); |
155 |
|
156 |
s = s.substring(i + 1); |
157 |
i = s.indexOf(','); |
158 |
int width = Integer.parseInt(s.substring(0, i)); |
159 |
|
160 |
s = s.substring(i + 1); |
161 |
int height = Integer.parseInt(s); |
162 |
|
163 |
return new Rectangle(x, y, width, height); |
164 |
} catch(Exception x) { |
165 |
String msg = windowName; |
166 |
msg += ": Parsing of window size and location string failed"; |
167 |
CC.getLogger().log(Level.INFO, msg, x); |
168 |
return null; |
169 |
} |
170 |
} |
171 |
|
172 |
/** |
173 |
* Saves the windows bounds in the preferences for the specified window. |
174 |
*/ |
175 |
public static void |
176 |
saveWindowBounds(String windowName, Rectangle r) { |
177 |
if(r.width < 50 || r.height < 50 || r.x < r.width * -1 || r.y < 0) { |
178 |
CC.getLogger().warning("Invalid window size or location"); |
179 |
return; |
180 |
} |
181 |
|
182 |
StringBuffer sb = new StringBuffer(); |
183 |
sb.append(r.x).append(',').append(r.y).append(','); |
184 |
sb.append(r.width).append(',').append(r.height); |
185 |
String s = windowName + ".windowSizeAndLocation"; |
186 |
CC.preferences().setStringProperty(s, sb.toString()); |
187 |
} |
188 |
|
189 |
public static JSlider |
190 |
createVolumeSlider() { |
191 |
return new VolumeSlider(); |
192 |
} |
193 |
|
194 |
private static class VolumeSlider extends JSlider { |
195 |
private Popup popup = null; |
196 |
private final JToolTip tip = new JToolTip(); |
197 |
private static NumberFormat numberFormat = NumberFormat.getInstance(); |
198 |
|
199 |
VolumeSlider() { |
200 |
super(0, 100, 100); |
201 |
numberFormat.setMaximumFractionDigits(1); |
202 |
// Setting the tooltip size (workaround for preserving that size) |
203 |
boolean b = CC.getViewConfig().isMeasurementUnitDecibel(); |
204 |
if(b) tip.setTipText(i18n.getLabel("StdUtils.volumeDecibels", "-30.0")); |
205 |
else tip.setTipText(i18n.getLabel("StdUtils.volume", "100")); |
206 |
tip.setPreferredSize(tip.getPreferredSize()); |
207 |
tip.setMinimumSize(tip.getPreferredSize()); |
208 |
/////// |
209 |
tip.setComponent(this); |
210 |
tip.setTipText(i18n.getLabel("StdUtils.volume", 0)); |
211 |
|
212 |
updateVolumeInfo(); |
213 |
|
214 |
addMouseListener(new MouseAdapter() { |
215 |
public void |
216 |
mousePressed(MouseEvent e) { |
217 |
if(popup != null) { |
218 |
popup.hide(); |
219 |
popup = null; |
220 |
} |
221 |
|
222 |
if(!VolumeSlider.this.isEnabled()) return; |
223 |
|
224 |
java.awt.Point p = VolumeSlider.this.getLocationOnScreen(); |
225 |
PopupFactory pf = PopupFactory.getSharedInstance(); |
226 |
popup = pf.getPopup(VolumeSlider.this, tip, p.x, p.y - 22); |
227 |
popup.show(); |
228 |
} |
229 |
|
230 |
public void |
231 |
mouseReleased(MouseEvent e) { |
232 |
if(popup != null) { |
233 |
popup.hide(); |
234 |
popup = null; |
235 |
} |
236 |
} |
237 |
}); |
238 |
|
239 |
addChangeListener(new ChangeListener() { |
240 |
public void |
241 |
stateChanged(ChangeEvent e) { updateVolumeInfo(); } |
242 |
}); |
243 |
|
244 |
String s = VOL_MEASUREMENT_UNIT_DECIBEL; |
245 |
preferences().addPropertyChangeListener(s, new PropertyChangeListener() { |
246 |
public void |
247 |
propertyChange(PropertyChangeEvent e) { |
248 |
// We use this to set the size of the lVolume |
249 |
// to prevent the frequent resizing of lVolume component |
250 |
boolean b = CC.getViewConfig().isMeasurementUnitDecibel(); |
251 |
tip.setPreferredSize(null); |
252 |
String s; |
253 |
if(b) s = i18n.getLabel("StdUtils.volumeDecibels", "-30.0"); |
254 |
else s = i18n.getLabel("StdUtils.volume", "100"); |
255 |
tip.setTipText(s); |
256 |
tip.setPreferredSize(tip.getPreferredSize()); |
257 |
tip.setMinimumSize(tip.getPreferredSize()); |
258 |
/////// |
259 |
updateVolumeInfo(); |
260 |
} |
261 |
}); |
262 |
} |
263 |
|
264 |
private void |
265 |
updateVolumeInfo() { |
266 |
String s; |
267 |
if(CC.getViewConfig().isMeasurementUnitDecibel()) { |
268 |
double d = HF.percentsToDecibels(getValue()); |
269 |
s = i18n.getLabel("StdUtils.volumeDecibels", numberFormat.format(d)); |
270 |
} else { |
271 |
s = i18n.getLabel("StdUtils.volume", getValue()); |
272 |
} |
273 |
|
274 |
setToolTipText(s); |
275 |
tip.setTipText(s); |
276 |
tip.repaint(); |
277 |
} |
278 |
} |
279 |
} |