/[svn]/jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1318 - (show annotations) (download)
Sat Sep 1 13:46:04 2007 UTC (16 years, 7 months ago) by iliev
File size: 12755 byte(s)
* Fantasia: Added scrollbar to the channels pane
* Implemented automatic scrolling when new channel is
  created to ensure that it is visible on the screen

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
23 package org.jsampler.view.fantasia;
24
25 import java.awt.BorderLayout;
26 import java.awt.Dialog;
27 import java.awt.Dimension;
28 import java.awt.Frame;
29 import java.awt.Graphics;
30 import java.awt.GridBagConstraints;
31 import java.awt.GridBagLayout;
32 import java.awt.Insets;
33 import java.awt.Point;
34
35 import java.awt.event.ActionEvent;
36 import java.awt.event.ActionListener;
37 import java.awt.event.KeyEvent;
38 import java.awt.event.MouseAdapter;
39 import java.awt.event.MouseEvent;
40
41 import java.io.BufferedReader;
42 import java.io.File;
43 import java.io.FileNotFoundException;
44 import java.io.FileReader;
45
46 import java.util.Vector;
47 import java.util.logging.Level;
48
49 import javax.swing.BorderFactory;
50 import javax.swing.Box;
51 import javax.swing.BoxLayout;
52 import javax.swing.JCheckBoxMenuItem;
53 import javax.swing.JDialog;
54 import javax.swing.JFileChooser;
55 import javax.swing.JFrame;
56 import javax.swing.JMenu;
57 import javax.swing.JMenuBar;
58 import javax.swing.JMenuItem;
59 import javax.swing.JPanel;
60 import javax.swing.JPopupMenu;
61 import javax.swing.JScrollPane;
62 import javax.swing.JSplitPane;
63 import javax.swing.JToggleButton;
64 import javax.swing.KeyStroke;
65 import javax.swing.SwingUtilities;
66 import javax.swing.UIManager;
67
68 import net.sf.juife.TitleBar;
69
70 import org.jsampler.CC;
71 import org.jsampler.HF;
72 import org.jsampler.LSConsoleModel;
73
74 import org.jsampler.view.JSChannel;
75 import org.jsampler.view.JSChannelsPane;
76 import org.jsampler.view.JSMainFrame;
77 import org.jsampler.view.LscpFileFilter;
78
79 import org.jsampler.view.std.JSamplerHomeChooser;
80
81 import static org.jsampler.view.fantasia.A4n.a4n;
82 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
83 import static org.jsampler.view.fantasia.FantasiaPrefs.preferences;
84 import static org.jsampler.view.std.StdPrefs.*;
85
86
87 /**
88 *
89 * @author Grigor Iliev
90 */
91 public class MainFrame extends JSMainFrame {
92 private final FantasiaMenuBar menuBar = new FantasiaMenuBar();
93 private final StandardBar standardBar = new StandardBar();
94 private final MainPane mainPane = new MainPane();
95 private final DevicesPane devicesPane = new DevicesPane();
96
97 private final JMenu recentScriptsMenu =
98 new JMenu(i18n.getMenuLabel("actions.recentScripts"));
99
100 private final JSplitPane hSplitPane;
101
102 private final SidePane sidePane = new SidePane();
103
104 private final LSConsoleFrame lsConsoleFrame = new LSConsoleFrame();
105 private final Vector<String> recentScripts = new Vector<String>();
106
107
108 /** Creates a new instance of <code>MainFrame</code> */
109 public
110 MainFrame() {
111 setTitle(i18n.getLabel("MainFrame.title"));
112
113 if(Res.iconAppIcon != null) setIconImage(Res.iconAppIcon.getImage());
114
115 getContentPane().add(standardBar, BorderLayout.NORTH);
116
117 addMenu();
118
119 addChannelsPane(mainPane.getChannelsPane());
120
121 JPanel rp = createRightPane();
122
123 hSplitPane = new JSplitPane (
124 JSplitPane.HORIZONTAL_SPLIT,
125 true, // continuousLayout
126 sidePane, rp
127 );
128
129 getContentPane().add(hSplitPane);
130
131 int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
132 hSplitPane.setDividerLocation(i);
133
134 setSavedSize();
135 }
136
137 private JPanel
138 createRightPane() {
139 JPanel p = new JPanel();
140 GridBagLayout gridbag = new GridBagLayout();
141 GridBagConstraints c = new GridBagConstraints();
142
143 p.setLayout(gridbag);
144
145 c.fill = GridBagConstraints.BOTH;
146
147 JScrollPane sp = new JScrollPane(devicesPane);
148 sp.setBorder(BorderFactory.createEmptyBorder());
149
150 c.gridx = 1;
151 c.gridy = 0;
152 c.weightx = 1.0;
153 c.weighty = 1.0;
154 c.insets = new Insets(0, 3, 3, 0);
155 gridbag.setConstraints(sp, c);
156 p.add(sp);
157
158 c.gridx = 0;
159 c.gridy = 0;
160 c.weightx = 0.0;
161 c.weighty = 1.0;
162 c.insets = new Insets(0, 3, 3, 3);
163 c.fill = GridBagConstraints.VERTICAL;
164 gridbag.setConstraints(mainPane, c);
165 p.add(mainPane);
166
167 return p;
168 }
169
170 private void
171 setSavedSize() {
172 String s = preferences().getStringProperty("MainFrame.sizeAndLocation");
173 if(s == null) {
174 setDefaultSizeAndLocation();
175 return;
176 }
177 pack();
178 try {
179 int i = s.indexOf(',');
180 int x = Integer.parseInt(s.substring(0, i));
181
182 s = s.substring(i + 1);
183 i = s.indexOf(',');
184 int y = Integer.parseInt(s.substring(0, i));
185
186 s = s.substring(i + 1);
187 i = s.indexOf(',');
188 int width = Integer.parseInt(s.substring(0, i));
189
190 s = s.substring(i + 1);
191 int height = Integer.parseInt(s);
192
193 setBounds(x, y, width, height);
194 } catch(Exception x) {
195 String msg = "Parsing of window size and location string failed";
196 CC.getLogger().log(Level.INFO, msg, x);
197 setDefaultSizeAndLocation();
198 }
199
200 if(preferences().getBoolProperty("MainFrame.windowMaximized")) {
201 setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
202 }
203 }
204
205 private void
206 setDefaultSizeAndLocation() {
207 setPreferredSize(new Dimension(900, 600));
208 pack();
209 setLocationRelativeTo(null);
210 }
211
212
213 /** Invoked when this window is about to close. */
214 protected void
215 onWindowClose() {
216 sidePane.savePreferences();
217
218 int i = hSplitPane.getDividerLocation();
219 preferences().setIntProperty("MainFrame.hSplitDividerLocation", i);
220
221 preferences().setBoolProperty (
222 "MainFrame.windowMaximized",
223 (getExtendedState() & MAXIMIZED_BOTH) == MAXIMIZED_BOTH
224 );
225
226 if(preferences().getBoolProperty("MainFrame.windowMaximized")) {
227 super.onWindowClose();
228 return;
229 }
230
231 java.awt.Point p = getLocation();
232 Dimension d = getSize();
233 StringBuffer sb = new StringBuffer();
234 sb.append(p.x).append(',').append(p.y).append(',');
235 sb.append(d.width).append(',').append(d.height);
236 preferences().setStringProperty("MainFrame.sizeAndLocation", sb.toString());
237
238 String[] list = recentScripts.toArray(new String[recentScripts.size()]);
239 preferences().setStringListProperty(RECENT_LSCP_SCRIPTS, list);
240
241 if(preferences().getBoolProperty(SAVE_LS_CONSOLE_HISTORY)) {
242 if(lsConsoleFrame != null) getLSConsolePane().saveConsoleHistory();
243 }
244
245 super.onWindowClose();
246 }
247
248 private void
249 addMenu() {
250 JMenu m;
251 JMenuItem mi;
252
253 setJMenuBar(menuBar);
254
255 // Actions
256 m = new FantasiaMenu(i18n.getMenuLabel("actions"));
257
258 mi = new JMenuItem(a4n.connect);
259 mi.setIcon(null);
260 //mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK));
261 m.add(mi);
262
263 mi = new JMenuItem(a4n.samplerInfo);
264 mi.setIcon(null);
265 m.add(mi);
266
267 m.addSeparator();
268
269 JMenu exportMenu = new JMenu(i18n.getMenuLabel("actions.export"));
270 m.add(exportMenu);
271
272 mi = new JMenuItem(a4n.exportSamplerConfig);
273 mi.setIcon(null);
274 mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
275 exportMenu.add(mi);
276
277 mi = new JMenuItem(a4n.exportMidiInstrumentMaps);
278 mi.setIcon(null);
279 exportMenu.add(mi);
280
281 m.addSeparator();
282
283 mi = new JMenuItem(a4n.loadScript);
284 mi.setIcon(null);
285 m.add(mi);
286
287 String[] list = preferences().getStringListProperty(RECENT_LSCP_SCRIPTS);
288 for(String s : list) recentScripts.add(s);
289
290 updateRecentScriptsMenu();
291
292 m.add(recentScriptsMenu);
293
294 m.addSeparator();
295
296 mi = new JMenuItem(i18n.getMenuLabel("actions.exit"));
297 m.add(mi);
298 mi.addActionListener(new ActionListener() {
299 public void
300 actionPerformed(ActionEvent e) { onWindowClose(); }
301 });
302
303 menuBar.add(m);
304
305
306 // Edit
307 m = new FantasiaMenu(i18n.getMenuLabel("edit"));
308 menuBar.add(m);
309
310 mi = new JMenuItem(a4n.editPreferences);
311 mi.setIcon(null);
312 mi.setAccelerator(KeyStroke.getKeyStroke (
313 KeyEvent.VK_P, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
314 ));
315 m.add(mi);
316
317
318 // Window
319 m = new FantasiaMenu(i18n.getMenuLabel("window"));
320 menuBar.add(m);
321
322 mi = new JMenuItem(a4n.windowLSConsole);
323 mi.setIcon(null);
324 m.add(mi);
325
326 mi = new JMenuItem(a4n.windowInstrumentsDb);
327 mi.setIcon(null);
328 m.add(mi);
329
330
331 // Help
332 m = new FantasiaMenu(i18n.getMenuLabel("help"));
333
334 mi = new JMenuItem(a4n.helpAbout);
335 mi.setIcon(null);
336 m.add(mi);
337
338 menuBar.add(m);
339 }
340
341 /**
342 * This method does nothing, because <b>Fantasia</b> has exactly
343 * one pane containing sampler channels, which can not be changed.
344 */
345 public void
346 insertChannelsPane(JSChannelsPane pane, int idx) {
347
348 }
349
350 /**
351 * This method always returns the <code>JSChannelsPane</code> at index 0,
352 * because the <b>Fantasia</b> view has exactly one pane containing sampler channels.
353 * @return The <code>JSChannelsPane</code> at index 0.
354 */
355 public JSChannelsPane
356 getSelectedChannelsPane() { return getChannelsPane(0); }
357
358 /**
359 * This method does nothing because the <b>Fantasia</b> view has
360 * exactly one pane containing sampler channels which is always shown.
361 */
362 public void
363 setSelectedChannelsPane(JSChannelsPane pane) { }
364
365 public void
366 installJSamplerHome() {
367 JSamplerHomeChooser chooser = new JSamplerHomeChooser(this);
368 chooser.setVisible(true);
369 if(chooser.isCancelled()) return;
370
371 CC.changeJSamplerHome(chooser.getJSamplerHome());
372 }
373
374 public void
375 showDetailedErrorMessage(Frame owner, String err, String details) {
376 // TODO:
377 }
378
379 public void
380 showDetailedErrorMessage(Dialog owner, String err, String details) {
381 // TODO:
382 }
383
384 protected LSConsoleModel
385 getLSConsoleModel() { return getLSConsolePane().getModel(); }
386
387 protected LSConsolePane
388 getLSConsolePane() {
389 return getLSConsoleFrame().getLSConsolePane();
390 }
391
392 protected LSConsoleFrame
393 getLSConsoleFrame() { return lsConsoleFrame; }
394
395 protected void
396 runScript() {
397 String s = preferences().getStringProperty("lastScriptLocation");
398 JFileChooser fc = new JFileChooser(s);
399 fc.setFileFilter(new LscpFileFilter());
400 int result = fc.showOpenDialog(this);
401 if(result != JFileChooser.APPROVE_OPTION) return;
402
403 String path = fc.getCurrentDirectory().getAbsolutePath();
404 preferences().setStringProperty("lastScriptLocation", path);
405
406 runScript(fc.getSelectedFile());
407 }
408
409 private void
410 runScript(String script) { runScript(new File(script)); }
411
412 private void
413 runScript(File script) {
414 FileReader fr;
415 try { fr = new FileReader(script); }
416 catch(FileNotFoundException e) {
417 HF.showErrorMessage(i18n.getMessage("FileNotFound!"));
418 return;
419 }
420
421 BufferedReader br = new BufferedReader(fr);
422
423 try {
424 String s = br.readLine();
425 while(s != null) {
426 getLSConsoleModel().setCommandLineText(s);
427 getLSConsoleModel().execCommand();
428 s = br.readLine();
429 }
430 } catch(Exception e) {
431 HF.showErrorMessage(e);
432 return;
433 }
434
435 String s = script.getAbsolutePath();
436 recentScripts.remove(s);
437 recentScripts.insertElementAt(s, 0);
438
439 updateRecentScriptsMenu();
440 }
441
442 protected void
443 clearRecentScripts() {
444 recentScripts.removeAllElements();
445 updateRecentScriptsMenu();
446 }
447
448 protected void
449 updateRecentScriptsMenu() {
450 int size = preferences().getIntProperty(RECENT_LSCP_SCRIPTS_SIZE);
451 while(recentScripts.size() > size) {
452 recentScripts.removeElementAt(recentScripts.size() - 1);
453 }
454
455 recentScriptsMenu.removeAll();
456
457 for(String script : recentScripts) {
458 JMenuItem mi = new JMenuItem(script);
459 recentScriptsMenu.add(mi);
460 mi.addActionListener(new RecentScriptHandler(script));
461 }
462
463 recentScriptsMenu.setEnabled(recentScripts.size() != 0);
464 }
465
466 private class RecentScriptHandler implements ActionListener {
467 private String script;
468
469 RecentScriptHandler(String script) { this.script = script; }
470
471 public void
472 actionPerformed(ActionEvent e) {
473 runScript(script);
474 if(preferences().getBoolProperty(SHOW_LS_CONSOLE_WHEN_RUN_SCRIPT)) {
475 a4n.windowLSConsole.actionPerformed(null);
476 }
477 }
478 }
479
480 private static class FantasiaMenu extends JMenu {
481 FantasiaMenu(String s) {
482 super(s);
483 setFont(getFont().deriveFont(java.awt.Font.BOLD));
484 setOpaque(false);
485 }
486 }
487
488 private static class FantasiaMenuBar extends JMenuBar {
489 private static Insets pixmapInsets = new Insets(6, 6, 0, 6);
490
491 FantasiaMenuBar() {
492 setOpaque(false);
493 }
494
495 protected void
496 paintComponent(Graphics g) {
497 super.paintComponent(g);
498
499 PixmapPane.paintComponent(this, g, Res.gfxMenuBarBg, pixmapInsets);
500 }
501 }
502 }

  ViewVC Help
Powered by ViewVC