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

Quick Search    Search Deep

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


1   /*
2   ================================================================================
3   
4     FILE:  ChordSetListEditor.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Editor swing components for the chord set list
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.asaph.standardgui;
43  
44  
45  import java.util.List;
46  import java.util.ArrayList;
47  import java.util.Map;
48  import java.util.HashMap;
49  import java.awt.GridBagLayout;
50  import java.awt.GridBagConstraints;
51  import java.awt.BorderLayout;
52  import java.awt.Insets;
53  import java.awt.event.ActionListener;
54  import java.awt.event.ActionEvent;
55  import javax.swing.JPanel;
56  import javax.swing.JLabel;
57  import javax.swing.JButton;
58  import javax.swing.JCheckBox;
59  import javax.swing.JTextField;
60  import javax.swing.BorderFactory;
61  import javax.swing.SwingUtilities;
62  import javax.swing.undo.UndoableEdit;
63  import javax.swing.undo.AbstractUndoableEdit;
64  import javax.swing.undo.CannotUndoException;
65  import javax.swing.undo.CannotRedoException;
66  import javax.swing.event.UndoableEditListener;
67  import javax.swing.event.UndoableEditEvent;
68  
69  import com.virtuosotechnologies.lib.util.CollectingCompoundEdit;
70  import com.virtuosotechnologies.lib.util.ObjectUtils;
71  
72  import com.virtuosotechnologies.asaph.model.Song;
73  import com.virtuosotechnologies.asaph.model.ChordSet;
74  import com.virtuosotechnologies.asaph.model.notation.Note;
75  import com.virtuosotechnologies.asaph.model.notation.NotationFactory;
76  import com.virtuosotechnologies.asaph.modelutils.SongUtils;
77  import com.virtuosotechnologies.asaph.notationmanager.NotationManager;
78  
79  
80  /**
81   * Editor swing components for the chord set list
82   */
83  /*package*/ class ChordSetListEditor
84  extends JPanel
85  {
86    private static final String STR_ChordSetListEditor_MainLabel =
87      ResourceAccess.Strings.buildString("ChordSetListEditor_MainLabel");
88    private static final String STR_ChordSetListEditor_AddButton =
89      ResourceAccess.Strings.buildString("ChordSetListEditor_AddButton");
90    private static final String STR_ChordSetListEditor_DeleteButton =
91      ResourceAccess.Strings.buildString("ChordSetListEditor_DeleteButton");
92    private static final String STR_ChordSetListEditor_NameLabel =
93      ResourceAccess.Strings.buildString("ChordSetListEditor_NameLabel");
94    private static final String STR_ChordSetListEditor_InitialTypeString =
95      ResourceAccess.Strings.buildString("ChordSetListEditor_InitialTypeString");
96    private static final String STR_ChordSetListEditor_DefaultCheckbox =
97      ResourceAccess.Strings.buildString("ChordSetListEditor_DefaultCheckbox");
98    
99    
100   private Song song_;
101   private SongEditor editor_;
102   private UndoableEditListener undoListener_;
103   private SongUtils songUtils_;
104   private NotationFactory notationFactory_;
105   
106   private JPanel contentPanel_;
107   private GridBagConstraints contentGbc_;
108   private Map defaultChecks_;
109   
110   
111   /**
112    * Constructor
113    */
114   /*package*/ ChordSetListEditor(
115     SongUtils songUtils,
116     NotationManager notationManager,
117     Song song,
118     SongEditor editor,
119     UndoableEditListener undoListener)
120   {
121     super(new BorderLayout());
122     song_ = song;
123     editor_ = editor;
124     undoListener_ = undoListener;
125     defaultChecks_ = new HashMap();
126     songUtils_ = songUtils;
127     notationFactory_ = notationManager.getNotationFactoryForLocale(song.getLocale());
128     
129     JPanel headerPanel = new JPanel(new GridBagLayout());
130     add(headerPanel, BorderLayout.NORTH);
131     GridBagConstraints gbc = new GridBagConstraints();
132     gbc.gridy = 0;
133     gbc.anchor = GridBagConstraints.WEST;
134     gbc.weighty = 1;
135     
136     JLabel label = new JLabel(STR_ChordSetListEditor_MainLabel);
137     gbc.weightx = 0;
138     gbc.insets = new Insets(0, 0, 2, 0);
139     headerPanel.add(label, gbc);
140     
141     JButton button = new JButton(STR_ChordSetListEditor_AddButton);
142     button.addActionListener(
143       new ActionListener()
144       {
145         public void actionPerformed(
146           ActionEvent ev)
147         {
148           CollectingCompoundEdit editCollector = new CollectingCompoundEdit();
149           ChordSet newSet = song_.addChordSet(
150             STR_ChordSetListEditor_InitialTypeString,
151             notationFactory_.getDefaultNote(), editCollector);
152           if (song_.getDefaultChordSet() == null)
153           {
154             song_.setDefaultChordSet(newSet, editCollector);
155           }
156           editCollector.end();
157           performAdd(editCollector);
158         }
159       });
160     button.setMargin(new Insets(0, 3, 0, 3));
161     gbc.weightx = 1;
162     gbc.insets = new Insets(0, 10, 2, 0);
163     headerPanel.add(button, gbc);
164     
165     contentPanel_ = new JPanel(new GridBagLayout());
166     add(contentPanel_, BorderLayout.CENTER);
167     
168     // Populate contentPanel_.
169     contentGbc_ = new GridBagConstraints();
170     contentGbc_.fill = GridBagConstraints.HORIZONTAL;
171     contentGbc_.anchor = GridBagConstraints.WEST;
172     contentGbc_.gridx = 0;
173     contentGbc_.weightx = 1;
174     contentGbc_.insets = new Insets(3, 15, 1, 0);
175     
176     for (ChordSet cs = song_.getNextChordSet(null);
177       cs != null; cs = song_.getNextChordSet(cs))
178     {
179       addChordSetGui(cs);
180     }
181   }
182   
183   
184   private void addChordSetGui(
185     final ChordSet cs)
186   {
187     JPanel csPanel = new JPanel(new GridBagLayout());
188     csPanel.setBorder(BorderFactory.createCompoundBorder(
189       BorderFactory.createLoweredBevelBorder(),
190       BorderFactory.createEmptyBorder(5, 5, 5, 5)));
191     contentPanel_.add(csPanel, contentGbc_);
192     
193     GridBagConstraints gbc = new GridBagConstraints();
194     gbc.weighty = 1;
195     
196     final JCheckBox defaultCheck = new JCheckBox(STR_ChordSetListEditor_DefaultCheckbox,
197       ObjectUtils.safeEquals(song_.getDefaultChordSet(), cs));
198     gbc.gridx = 0;
199     gbc.gridy = 0;
200     gbc.weightx = 0;
201     gbc.gridwidth = 2;
202     gbc.fill = GridBagConstraints.NONE;
203     gbc.anchor = GridBagConstraints.WEST;
204     gbc.insets = new Insets(0, 0, 3, 10);
205     csPanel.add(defaultCheck, gbc);
206     defaultChecks_.put(cs, defaultCheck);
207     defaultCheck.addActionListener(
208       new ActionListener()
209       {
210         public void actionPerformed(
211           ActionEvent ev)
212         {
213           ChordSet oldDefaultCS = song_.getDefaultChordSet();
214           JCheckBox oldCheck = (JCheckBox)defaultChecks_.get(oldDefaultCS);
215           if (defaultCheck.isSelected())
216           {
217             if (oldCheck != null)
218             {
219               oldCheck.setSelected(false);
220             }
221             song_.setDefaultChordSet(cs,
222               new SetDefaultListener(oldCheck, defaultCheck));
223           }
224           else if (oldCheck == defaultCheck)
225           {
226             song_.setDefaultChordSet(null,
227               new SetDefaultListener(oldCheck, null));
228           }
229         }
230       });
231     
232     final JButton deleteButton = new JButton(STR_ChordSetListEditor_DeleteButton);
233     gbc.gridx = 2;
234     gbc.gridy = 0;
235     gbc.weightx = 1;
236     gbc.gridwidth = 1;
237     gbc.fill = GridBagConstraints.NONE;
238     gbc.anchor = GridBagConstraints.EAST;
239     gbc.insets = new Insets(0, 0, 3, 0);
240     csPanel.add(deleteButton, gbc);
241     deleteButton.setMargin(new Insets(0, 3, 0, 3));
242     deleteButton.addActionListener(
243       new ActionListener()
244       {
245         public void actionPerformed(
246           ActionEvent ev)
247         {
248           int deleteIndex = 0;
249           for (ChordSet set = song_.getNextChordSet(null);
250             set != null; set = song_.getNextChordSet(set))
251           {
252             if (cs.equals(set))
253             {
254               break;
255             }
256             ++deleteIndex;
257           }
258           DeleteListener deleter = new DeleteListener(deleteIndex);
259           song_.removeChordSet(cs, deleter);
260           songUtils_.compactSong(song_, deleter);
261           deleter.finish();
262         }
263       });
264     
265     JLabel label = new JLabel(STR_ChordSetListEditor_NameLabel);
266     gbc.gridx = 0;
267     gbc.gridy = 1;
268     gbc.weightx = 0;
269     gbc.gridwidth = 1;
270     gbc.fill = GridBagConstraints.NONE;
271     gbc.anchor = GridBagConstraints.WEST;
272     gbc.insets = new Insets(0, 0, 5, 5);
273     csPanel.add(label, gbc);
274     
275     final JTextField nameField = new JTextField(cs.getName().getString());
276     StringUpdater.install(nameField, cs.getName(), editor_, undoListener_);
277     gbc.gridx = 1;
278     gbc.gridy = 1;
279     gbc.weightx = 0;
280     gbc.gridwidth = 2;
281     gbc.fill = GridBagConstraints.HORIZONTAL;
282     gbc.anchor = GridBagConstraints.WEST;
283     gbc.insets = new Insets(0, 0, 5, 0);
284     csPanel.add(nameField, gbc);
285     
286     KeySignatureListEditor keySigList = new KeySignatureListEditor(
287       cs, editor_, undoListener_, notationFactory_);
288     gbc.gridx = 0;
289     gbc.gridy = 2;
290     gbc.weightx = 0;
291     gbc.gridwidth = 3;
292     gbc.fill = GridBagConstraints.HORIZONTAL;
293     gbc.anchor = GridBagConstraints.WEST;
294     gbc.insets = new Insets(0, 0, 0, 0);
295     csPanel.add(keySigList, gbc);
296   }
297   
298   
299   private class SetDefaultListener
300   implements UndoableEditListener
301   {
302     private JCheckBox oldCheck_;
303     private JCheckBox newCheck_;
304     
305     private SetDefaultListener(
306       JCheckBox oldCheck,
307       JCheckBox newCheck)
308     {
309       oldCheck_ = oldCheck;
310       newCheck_ = newCheck;
311     }
312     
313     public void undoableEditHappened(
314       UndoableEditEvent ev)
315     {
316       final UndoableEdit delegate = ev.getEdit();
317       
318       undoListener_.undoableEditHappened(new UndoableEditEvent(
319         ev.getSource(),
320         new AbstractUndoableEdit()
321         {
322           public void undo()
323           throws CannotUndoException
324           {
325             super.undo();
326             delegate.undo();
327             // Update view
328             if (oldCheck_ != null)
329             {
330               oldCheck_.setSelected(true);
331             }
332             if (newCheck_ != null)
333             {
334               newCheck_.setSelected(false);
335             }
336           }
337           
338           public void redo()
339           throws CannotRedoException
340           {
341             super.redo();
342             delegate.redo();
343             // Update view
344             if (oldCheck_ != null)
345             {
346               oldCheck_.setSelected(false);
347             }
348             if (newCheck_ != null)
349             {
350               newCheck_.setSelected(true);
351             }
352           }
353         }));
354     }
355   }
356   
357   
358   private void performAdd(
359     final UndoableEdit edit)
360   {
361     // Update view
362     final ChordSet cs = song_.getPreviousChordSet(null);
363     final int index = song_.getChordSetCount()-1;
364     addChordSetGui(cs);
365     final JPanel panel = (JPanel)contentPanel_.getComponent(index);
366     revalidate();
367     
368     undoListener_.undoableEditHappened(new UndoableEditEvent(this,
369       new AbstractUndoableEdit()
370       {
371         public void undo()
372         throws CannotUndoException
373         {
374           super.undo();
375           edit.undo();
376           // Update view
377           contentPanel_.remove(index);
378           revalidate();
379           resetFocus();
380         }
381         
382         public void redo()
383         throws CannotRedoException
384         {
385           super.redo();
386           edit.redo();
387           // Update view
388           contentPanel_.add(panel, contentGbc_, index);
389           revalidate();
390         }
391       }));
392   }
393   
394   
395   private class DeleteListener
396   implements UndoableEditListener
397   {
398     private int deleteIndex_;
399     private List edits_;
400     private Object source_;
401     
402     private DeleteListener(
403       int index)
404     {
405       deleteIndex_ = index;
406       edits_ = new ArrayList();
407     }
408     
409     public void undoableEditHappened(
410       UndoableEditEvent ev)
411     {
412       edits_.add(ev.getEdit());
413       if (source_ == null)
414       {
415         source_ = ev.getSource();
416       }
417     }
418     
419     /*package*/ final void finish()
420     {
421       // Update view
422       final JPanel panel = (JPanel)contentPanel_.getComponent(deleteIndex_);
423       contentPanel_.remove(deleteIndex_);
424       revalidate();
425       resetFocus();
426       final UndoableEdit[] editArray = new UndoableEdit[edits_.size()];
427       edits_.toArray(editArray);
428       
429       undoListener_.undoableEditHappened(new UndoableEditEvent(source_,
430         new AbstractUndoableEdit()
431         {
432           public void undo()
433           throws CannotUndoException
434           {
435             super.undo();
436             for (int i=editArray.length-1; i>=0; --i)
437             {
438               editArray[i].undo();
439             }
440             // Update view
441             contentPanel_.add(panel, contentGbc_, deleteIndex_);
442             revalidate();
443           }
444           
445           public void redo()
446           throws CannotRedoException
447           {
448             super.redo();
449             for (int i=0; i<editArray.length; ++i)
450             {
451               editArray[i].redo();
452             }
453             // Update view
454             contentPanel_.remove(deleteIndex_);
455             revalidate();
456             resetFocus();
457           }
458         }));
459     }
460   }
461   
462   
463   private void resetFocus()
464   {
465     SwingUtilities.invokeLater(
466       new Runnable()
467       {
468         public void run()
469         {
470           contentPanel_.requestFocus();
471         }
472       });
473   }
474 }