Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/virtuosotechnologies/asaph/standardgui/KeySignatureListEditor.java


1   /*
2   ================================================================================
3   
4     FILE:  KeySignatureListEditor.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Editor swing components for the key signature section of the
13      chord set editor
14    
15    PROGRAMMERS:
16    
17      Daniel Azuma (DA)  <dazuma@kagi.com>
18    
19    COPYRIGHT:
20    
21      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
22      
23      This program is free software; you can redistribute it and/or
24      modify it under the terms of the GNU General Public License as
25      published by the Free Software Foundation; either version 2
26      of the License, or (at your option) any later version.
27      
28      This program is distributed in the hope that it will be useful,
29      but WITHOUT ANY WARRANTY; without even the implied warranty of
30      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31      GNU General Public License for more details.
32      
33      You should have received a copy of the GNU General Public
34      License along with this program; if not, write to
35        Free Software Foundation, Inc.
36        59 Temple Place, Suite 330
37        Boston, MA 02111-1307 USA
38  
39  ================================================================================
40  */
41  
42  
43  package com.virtuosotechnologies.asaph.standardgui;
44  
45  
46  import java.awt.GridBagConstraints;
47  import java.awt.GridBagLayout;
48  import java.awt.Insets;
49  import java.awt.event.ActionListener;
50  import java.awt.event.ActionEvent;
51  import java.util.Collection;
52  import java.util.ArrayList;
53  import java.util.Iterator;
54  import javax.swing.JPanel;
55  import javax.swing.JLabel;
56  import javax.swing.JSeparator;
57  import javax.swing.JComboBox;
58  import javax.swing.JTextField;
59  import javax.swing.JButton;
60  import javax.swing.SwingUtilities;
61  import javax.swing.undo.UndoableEdit;
62  import javax.swing.undo.AbstractUndoableEdit;
63  import javax.swing.undo.CannotUndoException;
64  import javax.swing.undo.CannotRedoException;
65  import javax.swing.event.UndoableEditListener;
66  import javax.swing.event.UndoableEditEvent;
67  
68  import com.virtuosotechnologies.asaph.model.ChordSet;
69  import com.virtuosotechnologies.asaph.model.ChordSetKey;
70  import com.virtuosotechnologies.asaph.model.notation.Note;
71  import com.virtuosotechnologies.asaph.model.notation.NoteModifier;
72  import com.virtuosotechnologies.asaph.model.notation.NotationFactory;
73  
74  
75  /**
76   * Editor swing components for the key signature section of the chord set editor
77   */
78  /*package*/ class KeySignatureListEditor
79  extends JPanel
80  {
81    private static final String STR_KeySignatureListEditor_DefaultKeyLabel =
82      ResourceAccess.Strings.buildString("KeySignatureListEditor_DefaultKeyLabel");
83    private static final String STR_KeySignatureListEditor_InfoLabel =
84      ResourceAccess.Strings.buildString("KeySignatureListEditor_InfoLabel");
85    private static final String STR_KeySignatureListEditor_AltKeysLabel =
86      ResourceAccess.Strings.buildString("KeySignatureListEditor_AltKeysLabel");
87    private static final String STR_KeySignatureListEditor_AddButton =
88      ResourceAccess.Strings.buildString("KeySignatureListEditor_AddButton");
89    private static final String STR_KeySignatureListEditor_DeleteButton =
90      ResourceAccess.Strings.buildString("KeySignatureListEditor_DeleteButton");
91    private static final String STR_KeySignatureListEditor_OpenParen =
92      ResourceAccess.Strings.buildString("KeySignatureListEditor_OpenParen");
93    private static final String STR_KeySignatureListEditor_CloseParen =
94      ResourceAccess.Strings.buildString("KeySignatureListEditor_CloseParen");
95    
96    private static final String[] noteChoices_ =
97      new String[] {"A", "B", "C", "D", "E", "F", "G"};
98    private static final String[] accidentalChoices_ =
99      new String[] {"", "#", "b"};
100   
101   private ChordSet chordSet_;
102   private SongEditor editor_;
103   private NotationFactory notationFactory_;
104   private UndoableEditListener undoListener_;
105   
106   private JPanel contentPanel_;
107   private GridBagConstraints contentGbc_;
108   private Collection sigTypeLabels_;
109   
110   
111   /**
112    * Constructor
113    */
114   /*package*/ KeySignatureListEditor(
115     final ChordSet chordSet,
116     SongEditor editor,
117     UndoableEditListener undoListener,
118     NotationFactory notationFactory)
119   {
120     super(new GridBagLayout());
121     
122     chordSet_ = chordSet;
123     editor_ = editor;
124     undoListener_ = undoListener;
125     notationFactory_ = notationFactory;
126     
127     JLabel label;
128     
129     // Toplevel layout
130     GridBagConstraints gbc = new GridBagConstraints();
131     gbc.gridx = 0;
132     gbc.weightx = 1;
133     gbc.weighty = 1;
134     gbc.fill = GridBagConstraints.HORIZONTAL;
135     
136     JPanel defaultKeyPanel = new JPanel(new GridBagLayout());
137     add(defaultKeyPanel, gbc);
138     
139     gbc.insets = new Insets(5, 0, 5, 0);
140     add(new JSeparator(), gbc);
141     gbc.insets = new Insets(0, 0, 0, 0);
142     
143     JPanel altKeysPanel = new JPanel(new GridBagLayout());
144     add(altKeysPanel, gbc);
145     
146     contentPanel_ = new JPanel(new GridBagLayout());
147     add(contentPanel_, gbc);
148     
149     // DefaultKeyPanel layout
150     gbc = new GridBagConstraints();
151     gbc.weighty = 1;
152     gbc.anchor = GridBagConstraints.EAST;
153     gbc.fill = GridBagConstraints.NONE;
154     
155     label = new JLabel(STR_KeySignatureListEditor_DefaultKeyLabel);
156     gbc.gridx = 0;
157     gbc.gridy = 0;
158     gbc.weightx = 0;
159     gbc.insets = new Insets(0, 0, 3, 5);
160     defaultKeyPanel.add(label, gbc);
161     
162     label = new JLabel(STR_KeySignatureListEditor_InfoLabel);
163     gbc.gridx = 0;
164     gbc.gridy = 1;
165     gbc.weightx = 0;
166     gbc.insets = new Insets(0, 0, 0, 5);
167     defaultKeyPanel.add(label, gbc);
168     
169     gbc.anchor = GridBagConstraints.WEST;
170     gbc.fill = GridBagConstraints.HORIZONTAL;
171     final ChordSetKey defaultNativeKey = chordSet_.getNativeKey();
172     Note defaultKeyNote = defaultNativeKey.getKeyNote();
173     
174     final JComboBox defaultNoteCombo = new JComboBox(notationFactory_.getBaseNotes());
175     defaultNoteCombo.setSelectedItem(defaultKeyNote.getBaseNote());
176     gbc.gridx = 1;
177     gbc.gridy = 0;
178     gbc.weightx = 0;
179     gbc.insets = new Insets(0, 0, 3, 3);
180     defaultKeyPanel.add(defaultNoteCombo, gbc);
181     
182     final JComboBox defaultAccidentalCombo = new JComboBox(
183       notationFactory_.getCommonModifiersForNote(defaultKeyNote));
184     defaultAccidentalCombo.setSelectedItem(defaultKeyNote.getNoteModifier());
185     gbc.gridx = 2;
186     gbc.gridy = 0;
187     gbc.weightx = 0;
188     gbc.insets = new Insets(0, 0, 3, 3);
189     defaultKeyPanel.add(defaultAccidentalCombo, gbc);
190     
191     ComboListener comboListener = new ComboListener(defaultNativeKey,
192       defaultNoteCombo, defaultAccidentalCombo);
193     defaultNoteCombo.addActionListener(comboListener);
194     defaultAccidentalCombo.addActionListener(comboListener);
195     
196     final JTextField defaultSigTypeField = new JTextField(
197       chordSet_.getKeySignatureType().getString());
198     gbc.gridx = 3;
199     gbc.gridy = 0;
200     gbc.weightx = 1;
201     gbc.insets = new Insets(0, 0, 3, 0);
202     defaultKeyPanel.add(defaultSigTypeField, gbc);
203     StringUpdater.install(defaultSigTypeField, chordSet.getKeySignatureType(),
204       editor_, new KeySigTextListener());
205     
206     final JTextField defaultInfoField = new JTextField(
207       defaultNativeKey.getInfoString().getString());
208     gbc.gridx = 1;
209     gbc.gridwidth = 3;
210     gbc.gridy = 1;
211     gbc.weightx = 0;
212     gbc.insets = new Insets(0, 0, 0, 0);
213     defaultKeyPanel.add(defaultInfoField, gbc);
214     StringUpdater.install(defaultInfoField, defaultNativeKey.getInfoString(),
215       editor_, undoListener_);
216     
217     // AltKeysPanel layout
218     gbc = new GridBagConstraints();
219     gbc.gridy = 0;
220     gbc.anchor = GridBagConstraints.WEST;
221     gbc.weighty = 1;
222     
223     label = new JLabel(STR_KeySignatureListEditor_AltKeysLabel);
224     gbc.weightx = 0;
225     gbc.insets = new Insets(0, 0, 3, 0);
226     altKeysPanel.add(label, gbc);
227     
228     JButton button = new JButton(STR_KeySignatureListEditor_AddButton);
229     final AddListener addListener = new AddListener();
230     button.addActionListener(
231       new ActionListener()
232       {
233         public void actionPerformed(
234           ActionEvent ev)
235         {
236           chordSet_.addAlternateKey(notationFactory_.getDefaultNote(), addListener);
237         }
238       });
239     button.setMargin(new Insets(0, 3, 0, 3));
240     gbc.weightx = 1;
241     gbc.insets = new Insets(0, 10, 3, 0);
242     altKeysPanel.add(button, gbc);
243     
244     // Populate contentPanel_.
245     sigTypeLabels_ = new ArrayList();
246     contentGbc_ = new GridBagConstraints();
247     contentGbc_.fill = GridBagConstraints.HORIZONTAL;
248     contentGbc_.anchor = GridBagConstraints.WEST;
249     contentGbc_.gridx = 0;
250     contentGbc_.weightx = 1;
251     contentGbc_.insets = new Insets(1, 15, 1, 0);
252     
253     for (ChordSetKey csk = chordSet_.getNextAlternateKey(null);
254       csk != null; csk = chordSet_.getNextAlternateKey(csk))
255     {
256       addAltKeyGui(csk);
257     }
258   }
259   
260   
261   private void addAltKeyGui(
262     final ChordSetKey csk)
263   {
264     JPanel cskPanel = new JPanel(new GridBagLayout());
265     contentPanel_.add(cskPanel, contentGbc_);
266     
267     GridBagConstraints gbc = new GridBagConstraints();
268     gbc.gridy = 0;
269     gbc.weighty = 1;
270     gbc.weightx = 0;
271     gbc.fill = GridBagConstraints.HORIZONTAL;
272     
273     Note initialNote = csk.getKeyNote();
274     final JComboBox noteCombo = new JComboBox(notationFactory_.getBaseNotes());
275     noteCombo.setSelectedItem(initialNote.getBaseNote());
276     gbc.insets = new Insets(0, 0, 0, 0);
277     cskPanel.add(noteCombo, gbc);
278     
279     final JComboBox accidentalCombo = new JComboBox(
280       notationFactory_.getCommonModifiersForNote(initialNote));
281     accidentalCombo.setSelectedItem(initialNote.getNoteModifier());
282     gbc.insets = new Insets(0, 3, 0, 0);
283     cskPanel.add(accidentalCombo, gbc);
284     
285     ComboListener comboListener = new ComboListener(csk, noteCombo, accidentalCombo);
286     noteCombo.addActionListener(comboListener);
287     accidentalCombo.addActionListener(comboListener);
288     
289     JLabel sigTypeLabel = new JLabel(chordSet_.getKeySignatureType().getString());
290     gbc.insets = new Insets(0, 2, 0, 0);
291     cskPanel.add(sigTypeLabel, gbc);
292     sigTypeLabels_.add(sigTypeLabel);
293     
294     gbc.insets = new Insets(0, 5, 0, 2);
295     cskPanel.add(new JLabel(STR_KeySignatureListEditor_OpenParen), gbc);
296     
297     final JTextField field = new JTextField(csk.getInfoString().getString());
298     StringUpdater.install(field, csk.getInfoString(), editor_, undoListener_);
299     gbc.weightx = 1;
300     gbc.insets = new Insets(0, 0, 0, 0);
301     cskPanel.add(field, gbc);
302     
303     gbc.insets = new Insets(0, 2, 0, 0);
304     gbc.weightx = 0;
305     cskPanel.add(new JLabel(STR_KeySignatureListEditor_CloseParen), gbc);
306     
307     JButton button = new JButton(STR_KeySignatureListEditor_DeleteButton);
308     button.addActionListener(
309       new ActionListener()
310       {
311         public void actionPerformed(
312           ActionEvent ev)
313         {
314           int deleteIndex = 0;
315           for (ChordSetKey k = chordSet_.getNextAlternateKey(null);
316             k != null; k = chordSet_.getNextAlternateKey(k))
317           {
318             if (csk.equals(k))
319             {
320               break;
321             }
322             ++deleteIndex;
323           }
324           chordSet_.removeAlternateKey(csk, new DeleteListener(deleteIndex));
325         }
326       });
327     button.setMargin(new Insets(0, 3, 0, 3));
328     gbc.insets = new Insets(0, 5, 0, 0);
329     cskPanel.add(button, gbc);
330   }
331   
332   
333   /*package*/ class ComboListener
334   implements
335     UndoableEditListener,
336     ActionListener
337   {
338     private ChordSetKey csk_;
339     private JComboBox noteCombo_;
340     private JComboBox accidentalCombo_;
341     private boolean comboListenerActive_;
342     
343     
344     /*package*/ ComboListener(
345       final ChordSetKey csk,
346       final JComboBox noteCombo,
347       final JComboBox accidentalCombo)
348     {
349       csk_ = csk;
350       noteCombo_ = noteCombo;
351       accidentalCombo_ = accidentalCombo;
352       comboListenerActive_ = true;
353     }
354     
355     
356     private void updateCombos()
357     {
358       comboListenerActive_ = false;
359       Note n = csk_.getKeyNote();
360       Note base = n.getBaseNote();
361       if (!noteCombo_.getSelectedItem().equals(base))
362       {
363         noteCombo_.setSelectedItem(base);
364         accidentalCombo_.removeAllItems();
365         NoteModifier[] mods = notationFactory_.getCommonModifiersForNote(n);
366         for (int i=0; i<mods.length; ++i)
367         {
368           accidentalCombo_.addItem(mods[i]);
369         }
370       }
371       accidentalCombo_.setSelectedItem(n.getNoteModifier());
372       comboListenerActive_ = true;
373     }
374     
375     
376     public void undoableEditHappened(
377       UndoableEditEvent ev)
378     {
379       updateCombos();
380       final UndoableEdit delegate = ev.getEdit();
381       undoListener_.undoableEditHappened(new UndoableEditEvent(
382         ev.getSource(),
383         new AbstractUndoableEdit()
384         {
385           public void undo()
386           throws CannotUndoException
387           {
388             super.undo();
389             delegate.undo();
390             updateCombos();
391           }
392           
393           public void redo()
394           throws CannotRedoException
395           {
396             super.redo();
397             delegate.redo();
398             updateCombos();
399           }
400         }));
401     }
402     
403     
404     public void actionPerformed(
405       ActionEvent ev)
406     {
407       if (comboListenerActive_)
408       {
409         Note n = ((Note)noteCombo_.getSelectedItem()).getNoteWithModifier(
410           (NoteModifier)accidentalCombo_.getSelectedItem());
411         csk_.setKeyNote(n, ComboListener.this);
412       }
413     }
414   }
415   
416   
417   private class KeySigTextListener
418   implements UndoableEditListener
419   {
420     private void updateLabels()
421     {
422       String str = chordSet_.getKeySignatureType().getString();
423       for (Iterator iter = sigTypeLabels_.iterator(); iter.hasNext(); )
424       {
425         JLabel label = (JLabel)iter.next();
426         label.setText(str);
427       }
428       revalidate();
429     }
430     
431     public void undoableEditHappened(
432       UndoableEditEvent ev)
433     {
434       updateLabels();
435       
436       final UndoableEdit delegate = ev.getEdit();
437       undoListener_.undoableEditHappened(new UndoableEditEvent(
438         ev.getSource(),
439         new AbstractUndoableEdit()
440         {
441           public void undo()
442           throws CannotUndoException
443           {
444             super.undo();
445             delegate.undo();
446             updateLabels();
447           }
448           
449           public void redo()
450           throws CannotRedoException
451           {
452             super.redo();
453             delegate.redo();
454             updateLabels();
455           }
456         }));
457     }
458   }
459   
460   
461   private class AddListener
462   implements UndoableEditListener
463   {
464     public void undoableEditHappened(
465       UndoableEditEvent ev)
466     {
467       final UndoableEdit delegate = ev.getEdit();
468       
469       // Update view
470       final ChordSetKey csk = chordSet_.getPreviousAlternateKey(null);
471       final int index = chordSet_.getAlternateKeyCount()-1;
472       addAltKeyGui(csk);
473       final JPanel panel = (JPanel)contentPanel_.getComponent(index);
474       revalidate();
475       
476       undoListener_.undoableEditHappened(new UndoableEditEvent(
477         ev.getSource(),
478         new AbstractUndoableEdit()
479         {
480           public void undo()
481           throws CannotUndoException
482           {
483             super.undo();
484             delegate.undo();
485             // Update view
486             contentPanel_.remove(index);
487             revalidate();
488             resetFocus();
489           }
490           
491           public void redo()
492           throws CannotRedoException
493           {
494             super.redo();
495             delegate.redo();
496             // Update view
497             contentPanel_.add(panel, contentGbc_, index);
498             revalidate();
499           }
500         }));
501     }
502   }
503   
504   
505   private class DeleteListener
506   implements UndoableEditListener
507   {
508     private int deleteIndex_;
509     
510     private DeleteListener(
511       int index)
512     {
513       deleteIndex_ = index;
514     }
515     
516     public void undoableEditHappened(
517       UndoableEditEvent ev)
518     {
519       final UndoableEdit delegate = ev.getEdit();
520       
521       // Update view
522       final JPanel panel = (JPanel)contentPanel_.getComponent(deleteIndex_);
523       contentPanel_.remove(deleteIndex_);
524       revalidate();
525       resetFocus();
526       
527       undoListener_.undoableEditHappened(new UndoableEditEvent(
528         ev.getSource(),
529         new AbstractUndoableEdit()
530         {
531           public void undo()
532           throws CannotUndoException
533           {
534             super.undo();
535             delegate.undo();
536             // Update view
537             contentPanel_.add(panel, contentGbc_, deleteIndex_);
538             revalidate();
539           }
540           
541           public void redo()
542           throws CannotRedoException
543           {
544             super.redo();
545             delegate.redo();
546             // Update view
547             contentPanel_.remove(deleteIndex_);
548             resetFocus();
549             revalidate();
550           }
551         }));
552     }
553   }
554   
555   
556   private void resetFocus()
557   {
558     SwingUtilities.invokeLater(
559       new Runnable()
560       {
561         public void run()
562         {
563           contentPanel_.requestFocus();
564         }
565       });
566   }
567 }